ActivityManagerService.java revision 6e2f395a86d557d2de4b52dda419a5f3eee00c84
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 mCallFinishBooting = false;
892    boolean mBootAnimationComplete = false;
893    boolean mWaitingUpdate = false;
894    boolean mDidUpdate = false;
895    boolean mOnBattery = false;
896    boolean mLaunchWarningShown = false;
897
898    Context mContext;
899
900    int mFactoryTest;
901
902    boolean mCheckedForSetup;
903
904    /**
905     * The time at which we will allow normal application switches again,
906     * after a call to {@link #stopAppSwitches()}.
907     */
908    long mAppSwitchesAllowedTime;
909
910    /**
911     * This is set to true after the first switch after mAppSwitchesAllowedTime
912     * is set; any switches after that will clear the time.
913     */
914    boolean mDidAppSwitch;
915
916    /**
917     * Last time (in realtime) at which we checked for power usage.
918     */
919    long mLastPowerCheckRealtime;
920
921    /**
922     * Last time (in uptime) at which we checked for power usage.
923     */
924    long mLastPowerCheckUptime;
925
926    /**
927     * Set while we are wanting to sleep, to prevent any
928     * activities from being started/resumed.
929     */
930    private boolean mSleeping = false;
931
932    /**
933     * Set while we are running a voice interaction.  This overrides
934     * sleeping while it is active.
935     */
936    private boolean mRunningVoice = false;
937
938    /**
939     * State of external calls telling us if the device is asleep.
940     */
941    private boolean mWentToSleep = false;
942
943    /**
944     * State of external call telling us if the lock screen is shown.
945     */
946    private boolean mLockScreenShown = false;
947
948    /**
949     * Set if we are shutting down the system, similar to sleeping.
950     */
951    boolean mShuttingDown = false;
952
953    /**
954     * Current sequence id for oom_adj computation traversal.
955     */
956    int mAdjSeq = 0;
957
958    /**
959     * Current sequence id for process LRU updating.
960     */
961    int mLruSeq = 0;
962
963    /**
964     * Keep track of the non-cached/empty process we last found, to help
965     * determine how to distribute cached/empty processes next time.
966     */
967    int mNumNonCachedProcs = 0;
968
969    /**
970     * Keep track of the number of cached hidden procs, to balance oom adj
971     * distribution between those and empty procs.
972     */
973    int mNumCachedHiddenProcs = 0;
974
975    /**
976     * Keep track of the number of service processes we last found, to
977     * determine on the next iteration which should be B services.
978     */
979    int mNumServiceProcs = 0;
980    int mNewNumAServiceProcs = 0;
981    int mNewNumServiceProcs = 0;
982
983    /**
984     * Allow the current computed overall memory level of the system to go down?
985     * This is set to false when we are killing processes for reasons other than
986     * memory management, so that the now smaller process list will not be taken as
987     * an indication that memory is tighter.
988     */
989    boolean mAllowLowerMemLevel = false;
990
991    /**
992     * The last computed memory level, for holding when we are in a state that
993     * processes are going away for other reasons.
994     */
995    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
996
997    /**
998     * The last total number of process we have, to determine if changes actually look
999     * like a shrinking number of process due to lower RAM.
1000     */
1001    int mLastNumProcesses;
1002
1003    /**
1004     * The uptime of the last time we performed idle maintenance.
1005     */
1006    long mLastIdleTime = SystemClock.uptimeMillis();
1007
1008    /**
1009     * Total time spent with RAM that has been added in the past since the last idle time.
1010     */
1011    long mLowRamTimeSinceLastIdle = 0;
1012
1013    /**
1014     * If RAM is currently low, when that horrible situation started.
1015     */
1016    long mLowRamStartTime = 0;
1017
1018    /**
1019     * For reporting to battery stats the current top application.
1020     */
1021    private String mCurResumedPackage = null;
1022    private int mCurResumedUid = -1;
1023
1024    /**
1025     * For reporting to battery stats the apps currently running foreground
1026     * service.  The ProcessMap is package/uid tuples; each of these contain
1027     * an array of the currently foreground processes.
1028     */
1029    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1030            = new ProcessMap<ArrayList<ProcessRecord>>();
1031
1032    /**
1033     * This is set if we had to do a delayed dexopt of an app before launching
1034     * it, to increase the ANR timeouts in that case.
1035     */
1036    boolean mDidDexOpt;
1037
1038    /**
1039     * Set if the systemServer made a call to enterSafeMode.
1040     */
1041    boolean mSafeMode;
1042
1043    String mDebugApp = null;
1044    boolean mWaitForDebugger = false;
1045    boolean mDebugTransient = false;
1046    String mOrigDebugApp = null;
1047    boolean mOrigWaitForDebugger = false;
1048    boolean mAlwaysFinishActivities = false;
1049    IActivityController mController = null;
1050    String mProfileApp = null;
1051    ProcessRecord mProfileProc = null;
1052    String mProfileFile;
1053    ParcelFileDescriptor mProfileFd;
1054    int mSamplingInterval = 0;
1055    boolean mAutoStopProfiler = false;
1056    int mProfileType = 0;
1057    String mOpenGlTraceApp = null;
1058
1059    static class ProcessChangeItem {
1060        static final int CHANGE_ACTIVITIES = 1<<0;
1061        static final int CHANGE_PROCESS_STATE = 1<<1;
1062        int changes;
1063        int uid;
1064        int pid;
1065        int processState;
1066        boolean foregroundActivities;
1067    }
1068
1069    final RemoteCallbackList<IProcessObserver> mProcessObservers
1070            = new RemoteCallbackList<IProcessObserver>();
1071    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1072
1073    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1076            = new ArrayList<ProcessChangeItem>();
1077
1078    /**
1079     * Runtime CPU use collection thread.  This object's lock is used to
1080     * protect all related state.
1081     */
1082    final Thread mProcessCpuThread;
1083
1084    /**
1085     * Used to collect process stats when showing not responding dialog.
1086     * Protected by mProcessCpuThread.
1087     */
1088    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1089            MONITOR_THREAD_CPU_USAGE);
1090    final AtomicLong mLastCpuTime = new AtomicLong(0);
1091    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1092
1093    long mLastWriteTime = 0;
1094
1095    /**
1096     * Used to retain an update lock when the foreground activity is in
1097     * immersive mode.
1098     */
1099    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1100
1101    /**
1102     * Set to true after the system has finished booting.
1103     */
1104    boolean mBooted = false;
1105
1106    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1107    int mProcessLimitOverride = -1;
1108
1109    WindowManagerService mWindowManager;
1110
1111    final ActivityThread mSystemThread;
1112
1113    // Holds the current foreground user's id
1114    int mCurrentUserId = 0;
1115    // Holds the target user's id during a user switch
1116    int mTargetUserId = UserHandle.USER_NULL;
1117    // If there are multiple profiles for the current user, their ids are here
1118    // Currently only the primary user can have managed profiles
1119    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1120
1121    /**
1122     * Mapping from each known user ID to the profile group ID it is associated with.
1123     */
1124    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1125
1126    private UserManagerService mUserManager;
1127
1128    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1129        final ProcessRecord mApp;
1130        final int mPid;
1131        final IApplicationThread mAppThread;
1132
1133        AppDeathRecipient(ProcessRecord app, int pid,
1134                IApplicationThread thread) {
1135            if (localLOGV) Slog.v(
1136                TAG, "New death recipient " + this
1137                + " for thread " + thread.asBinder());
1138            mApp = app;
1139            mPid = pid;
1140            mAppThread = thread;
1141        }
1142
1143        @Override
1144        public void binderDied() {
1145            if (localLOGV) Slog.v(
1146                TAG, "Death received in " + this
1147                + " for thread " + mAppThread.asBinder());
1148            synchronized(ActivityManagerService.this) {
1149                appDiedLocked(mApp, mPid, mAppThread);
1150            }
1151        }
1152    }
1153
1154    static final int SHOW_ERROR_MSG = 1;
1155    static final int SHOW_NOT_RESPONDING_MSG = 2;
1156    static final int SHOW_FACTORY_ERROR_MSG = 3;
1157    static final int UPDATE_CONFIGURATION_MSG = 4;
1158    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1159    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1160    static final int SERVICE_TIMEOUT_MSG = 12;
1161    static final int UPDATE_TIME_ZONE = 13;
1162    static final int SHOW_UID_ERROR_MSG = 14;
1163    static final int IM_FEELING_LUCKY_MSG = 15;
1164    static final int PROC_START_TIMEOUT_MSG = 20;
1165    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1166    static final int KILL_APPLICATION_MSG = 22;
1167    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1168    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1169    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1170    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1171    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1172    static final int CLEAR_DNS_CACHE_MSG = 28;
1173    static final int UPDATE_HTTP_PROXY_MSG = 29;
1174    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1175    static final int DISPATCH_PROCESSES_CHANGED = 31;
1176    static final int DISPATCH_PROCESS_DIED = 32;
1177    static final int REPORT_MEM_USAGE_MSG = 33;
1178    static final int REPORT_USER_SWITCH_MSG = 34;
1179    static final int CONTINUE_USER_SWITCH_MSG = 35;
1180    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1181    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1182    static final int PERSIST_URI_GRANTS_MSG = 38;
1183    static final int REQUEST_ALL_PSS_MSG = 39;
1184    static final int START_PROFILES_MSG = 40;
1185    static final int UPDATE_TIME = 41;
1186    static final int SYSTEM_USER_START_MSG = 42;
1187    static final int SYSTEM_USER_CURRENT_MSG = 43;
1188    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1189    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1190    static final int START_USER_SWITCH_MSG = 46;
1191
1192    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1193    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1194    static final int FIRST_COMPAT_MODE_MSG = 300;
1195    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1196
1197    AlertDialog mUidAlert;
1198    CompatModeDialog mCompatModeDialog;
1199    long mLastMemUsageReportTime = 0;
1200
1201    private LockToAppRequestDialog mLockToAppRequest;
1202
1203    /**
1204     * Flag whether the current user is a "monkey", i.e. whether
1205     * the UI is driven by a UI automation tool.
1206     */
1207    private boolean mUserIsMonkey;
1208
1209    /** Flag whether the device has a Recents UI */
1210    boolean mHasRecents;
1211
1212    /** The dimensions of the thumbnails in the Recents UI. */
1213    int mThumbnailWidth;
1214    int mThumbnailHeight;
1215
1216    final ServiceThread mHandlerThread;
1217    final MainHandler mHandler;
1218
1219    final class MainHandler extends Handler {
1220        public MainHandler(Looper looper) {
1221            super(looper, null, true);
1222        }
1223
1224        @Override
1225        public void handleMessage(Message msg) {
1226            switch (msg.what) {
1227            case SHOW_ERROR_MSG: {
1228                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1229                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1230                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1231                synchronized (ActivityManagerService.this) {
1232                    ProcessRecord proc = (ProcessRecord)data.get("app");
1233                    AppErrorResult res = (AppErrorResult) data.get("result");
1234                    if (proc != null && proc.crashDialog != null) {
1235                        Slog.e(TAG, "App already has crash dialog: " + proc);
1236                        if (res != null) {
1237                            res.set(0);
1238                        }
1239                        return;
1240                    }
1241                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1242                            >= Process.FIRST_APPLICATION_UID
1243                            && proc.pid != MY_PID);
1244                    for (int userId : mCurrentProfileIds) {
1245                        isBackground &= (proc.userId != userId);
1246                    }
1247                    if (isBackground && !showBackground) {
1248                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1249                        if (res != null) {
1250                            res.set(0);
1251                        }
1252                        return;
1253                    }
1254                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1255                        Dialog d = new AppErrorDialog(mContext,
1256                                ActivityManagerService.this, res, proc);
1257                        d.show();
1258                        proc.crashDialog = d;
1259                    } else {
1260                        // The device is asleep, so just pretend that the user
1261                        // saw a crash dialog and hit "force quit".
1262                        if (res != null) {
1263                            res.set(0);
1264                        }
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_NOT_RESPONDING_MSG: {
1271                synchronized (ActivityManagerService.this) {
1272                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1273                    ProcessRecord proc = (ProcessRecord)data.get("app");
1274                    if (proc != null && proc.anrDialog != null) {
1275                        Slog.e(TAG, "App already has anr dialog: " + proc);
1276                        return;
1277                    }
1278
1279                    Intent intent = new Intent("android.intent.action.ANR");
1280                    if (!mProcessesReady) {
1281                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1282                                | Intent.FLAG_RECEIVER_FOREGROUND);
1283                    }
1284                    broadcastIntentLocked(null, null, intent,
1285                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1286                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1287
1288                    if (mShowDialogs) {
1289                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1290                                mContext, proc, (ActivityRecord)data.get("activity"),
1291                                msg.arg1 != 0);
1292                        d.show();
1293                        proc.anrDialog = d;
1294                    } else {
1295                        // Just kill the app if there is no dialog to be shown.
1296                        killAppAtUsersRequest(proc, null);
1297                    }
1298                }
1299
1300                ensureBootCompleted();
1301            } break;
1302            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1303                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1304                synchronized (ActivityManagerService.this) {
1305                    ProcessRecord proc = (ProcessRecord) data.get("app");
1306                    if (proc == null) {
1307                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1308                        break;
1309                    }
1310                    if (proc.crashDialog != null) {
1311                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1312                        return;
1313                    }
1314                    AppErrorResult res = (AppErrorResult) data.get("result");
1315                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1316                        Dialog d = new StrictModeViolationDialog(mContext,
1317                                ActivityManagerService.this, res, proc);
1318                        d.show();
1319                        proc.crashDialog = d;
1320                    } else {
1321                        // The device is asleep, so just pretend that the user
1322                        // saw a crash dialog and hit "force quit".
1323                        res.set(0);
1324                    }
1325                }
1326                ensureBootCompleted();
1327            } break;
1328            case SHOW_FACTORY_ERROR_MSG: {
1329                Dialog d = new FactoryErrorDialog(
1330                    mContext, msg.getData().getCharSequence("msg"));
1331                d.show();
1332                ensureBootCompleted();
1333            } break;
1334            case UPDATE_CONFIGURATION_MSG: {
1335                final ContentResolver resolver = mContext.getContentResolver();
1336                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1337            } break;
1338            case GC_BACKGROUND_PROCESSES_MSG: {
1339                synchronized (ActivityManagerService.this) {
1340                    performAppGcsIfAppropriateLocked();
1341                }
1342            } break;
1343            case WAIT_FOR_DEBUGGER_MSG: {
1344                synchronized (ActivityManagerService.this) {
1345                    ProcessRecord app = (ProcessRecord)msg.obj;
1346                    if (msg.arg1 != 0) {
1347                        if (!app.waitedForDebugger) {
1348                            Dialog d = new AppWaitingForDebuggerDialog(
1349                                    ActivityManagerService.this,
1350                                    mContext, app);
1351                            app.waitDialog = d;
1352                            app.waitedForDebugger = true;
1353                            d.show();
1354                        }
1355                    } else {
1356                        if (app.waitDialog != null) {
1357                            app.waitDialog.dismiss();
1358                            app.waitDialog = null;
1359                        }
1360                    }
1361                }
1362            } break;
1363            case SERVICE_TIMEOUT_MSG: {
1364                if (mDidDexOpt) {
1365                    mDidDexOpt = false;
1366                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1367                    nmsg.obj = msg.obj;
1368                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1369                    return;
1370                }
1371                mServices.serviceTimeout((ProcessRecord)msg.obj);
1372            } break;
1373            case UPDATE_TIME_ZONE: {
1374                synchronized (ActivityManagerService.this) {
1375                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1376                        ProcessRecord r = mLruProcesses.get(i);
1377                        if (r.thread != null) {
1378                            try {
1379                                r.thread.updateTimeZone();
1380                            } catch (RemoteException ex) {
1381                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1382                            }
1383                        }
1384                    }
1385                }
1386            } break;
1387            case CLEAR_DNS_CACHE_MSG: {
1388                synchronized (ActivityManagerService.this) {
1389                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1390                        ProcessRecord r = mLruProcesses.get(i);
1391                        if (r.thread != null) {
1392                            try {
1393                                r.thread.clearDnsCache();
1394                            } catch (RemoteException ex) {
1395                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1396                            }
1397                        }
1398                    }
1399                }
1400            } break;
1401            case UPDATE_HTTP_PROXY_MSG: {
1402                ProxyInfo proxy = (ProxyInfo)msg.obj;
1403                String host = "";
1404                String port = "";
1405                String exclList = "";
1406                Uri pacFileUrl = Uri.EMPTY;
1407                if (proxy != null) {
1408                    host = proxy.getHost();
1409                    port = Integer.toString(proxy.getPort());
1410                    exclList = proxy.getExclusionListAsString();
1411                    pacFileUrl = proxy.getPacFileUrl();
1412                }
1413                synchronized (ActivityManagerService.this) {
1414                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1415                        ProcessRecord r = mLruProcesses.get(i);
1416                        if (r.thread != null) {
1417                            try {
1418                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1419                            } catch (RemoteException ex) {
1420                                Slog.w(TAG, "Failed to update http proxy for: " +
1421                                        r.info.processName);
1422                            }
1423                        }
1424                    }
1425                }
1426            } break;
1427            case SHOW_UID_ERROR_MSG: {
1428                String title = "System UIDs Inconsistent";
1429                String text = "UIDs on the system are inconsistent, you need to wipe your"
1430                        + " data partition or your device will be unstable.";
1431                Log.e(TAG, title + ": " + text);
1432                if (mShowDialogs) {
1433                    // XXX This is a temporary dialog, no need to localize.
1434                    AlertDialog d = new BaseErrorDialog(mContext);
1435                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1436                    d.setCancelable(false);
1437                    d.setTitle(title);
1438                    d.setMessage(text);
1439                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1440                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1441                    mUidAlert = d;
1442                    d.show();
1443                }
1444            } break;
1445            case IM_FEELING_LUCKY_MSG: {
1446                if (mUidAlert != null) {
1447                    mUidAlert.dismiss();
1448                    mUidAlert = null;
1449                }
1450            } break;
1451            case PROC_START_TIMEOUT_MSG: {
1452                if (mDidDexOpt) {
1453                    mDidDexOpt = false;
1454                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1455                    nmsg.obj = msg.obj;
1456                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1457                    return;
1458                }
1459                ProcessRecord app = (ProcessRecord)msg.obj;
1460                synchronized (ActivityManagerService.this) {
1461                    processStartTimedOutLocked(app);
1462                }
1463            } break;
1464            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1465                synchronized (ActivityManagerService.this) {
1466                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1467                }
1468            } break;
1469            case KILL_APPLICATION_MSG: {
1470                synchronized (ActivityManagerService.this) {
1471                    int appid = msg.arg1;
1472                    boolean restart = (msg.arg2 == 1);
1473                    Bundle bundle = (Bundle)msg.obj;
1474                    String pkg = bundle.getString("pkg");
1475                    String reason = bundle.getString("reason");
1476                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1477                            false, UserHandle.USER_ALL, reason);
1478                }
1479            } break;
1480            case FINALIZE_PENDING_INTENT_MSG: {
1481                ((PendingIntentRecord)msg.obj).completeFinalize();
1482            } break;
1483            case POST_HEAVY_NOTIFICATION_MSG: {
1484                INotificationManager inm = NotificationManager.getService();
1485                if (inm == null) {
1486                    return;
1487                }
1488
1489                ActivityRecord root = (ActivityRecord)msg.obj;
1490                ProcessRecord process = root.app;
1491                if (process == null) {
1492                    return;
1493                }
1494
1495                try {
1496                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1497                    String text = mContext.getString(R.string.heavy_weight_notification,
1498                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1499                    Notification notification = new Notification();
1500                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1501                    notification.when = 0;
1502                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1503                    notification.tickerText = text;
1504                    notification.defaults = 0; // please be quiet
1505                    notification.sound = null;
1506                    notification.vibrate = null;
1507                    notification.color = mContext.getResources().getColor(
1508                            com.android.internal.R.color.system_notification_accent_color);
1509                    notification.setLatestEventInfo(context, text,
1510                            mContext.getText(R.string.heavy_weight_notification_detail),
1511                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1512                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1513                                    new UserHandle(root.userId)));
1514
1515                    try {
1516                        int[] outId = new int[1];
1517                        inm.enqueueNotificationWithTag("android", "android", null,
1518                                R.string.heavy_weight_notification,
1519                                notification, outId, root.userId);
1520                    } catch (RuntimeException e) {
1521                        Slog.w(ActivityManagerService.TAG,
1522                                "Error showing notification for heavy-weight app", e);
1523                    } catch (RemoteException e) {
1524                    }
1525                } catch (NameNotFoundException e) {
1526                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1527                }
1528            } break;
1529            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1530                INotificationManager inm = NotificationManager.getService();
1531                if (inm == null) {
1532                    return;
1533                }
1534                try {
1535                    inm.cancelNotificationWithTag("android", null,
1536                            R.string.heavy_weight_notification,  msg.arg1);
1537                } catch (RuntimeException e) {
1538                    Slog.w(ActivityManagerService.TAG,
1539                            "Error canceling notification for service", e);
1540                } catch (RemoteException e) {
1541                }
1542            } break;
1543            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    checkExcessivePowerUsageLocked(true);
1546                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1547                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1548                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1549                }
1550            } break;
1551            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1552                synchronized (ActivityManagerService.this) {
1553                    ActivityRecord ar = (ActivityRecord)msg.obj;
1554                    if (mCompatModeDialog != null) {
1555                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1556                                ar.info.applicationInfo.packageName)) {
1557                            return;
1558                        }
1559                        mCompatModeDialog.dismiss();
1560                        mCompatModeDialog = null;
1561                    }
1562                    if (ar != null && false) {
1563                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1564                                ar.packageName)) {
1565                            int mode = mCompatModePackages.computeCompatModeLocked(
1566                                    ar.info.applicationInfo);
1567                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1568                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1569                                mCompatModeDialog = new CompatModeDialog(
1570                                        ActivityManagerService.this, mContext,
1571                                        ar.info.applicationInfo);
1572                                mCompatModeDialog.show();
1573                            }
1574                        }
1575                    }
1576                }
1577                break;
1578            }
1579            case DISPATCH_PROCESSES_CHANGED: {
1580                dispatchProcessesChanged();
1581                break;
1582            }
1583            case DISPATCH_PROCESS_DIED: {
1584                final int pid = msg.arg1;
1585                final int uid = msg.arg2;
1586                dispatchProcessDied(pid, uid);
1587                break;
1588            }
1589            case REPORT_MEM_USAGE_MSG: {
1590                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1591                Thread thread = new Thread() {
1592                    @Override public void run() {
1593                        final SparseArray<ProcessMemInfo> infoMap
1594                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1595                        for (int i=0, N=memInfos.size(); i<N; i++) {
1596                            ProcessMemInfo mi = memInfos.get(i);
1597                            infoMap.put(mi.pid, mi);
1598                        }
1599                        updateCpuStatsNow();
1600                        synchronized (mProcessCpuThread) {
1601                            final int N = mProcessCpuTracker.countStats();
1602                            for (int i=0; i<N; i++) {
1603                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1604                                if (st.vsize > 0) {
1605                                    long pss = Debug.getPss(st.pid, null);
1606                                    if (pss > 0) {
1607                                        if (infoMap.indexOfKey(st.pid) < 0) {
1608                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1609                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1610                                            mi.pss = pss;
1611                                            memInfos.add(mi);
1612                                        }
1613                                    }
1614                                }
1615                            }
1616                        }
1617
1618                        long totalPss = 0;
1619                        for (int i=0, N=memInfos.size(); i<N; i++) {
1620                            ProcessMemInfo mi = memInfos.get(i);
1621                            if (mi.pss == 0) {
1622                                mi.pss = Debug.getPss(mi.pid, null);
1623                            }
1624                            totalPss += mi.pss;
1625                        }
1626                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1627                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1628                                if (lhs.oomAdj != rhs.oomAdj) {
1629                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1630                                }
1631                                if (lhs.pss != rhs.pss) {
1632                                    return lhs.pss < rhs.pss ? 1 : -1;
1633                                }
1634                                return 0;
1635                            }
1636                        });
1637
1638                        StringBuilder tag = new StringBuilder(128);
1639                        StringBuilder stack = new StringBuilder(128);
1640                        tag.append("Low on memory -- ");
1641                        appendMemBucket(tag, totalPss, "total", false);
1642                        appendMemBucket(stack, totalPss, "total", true);
1643
1644                        StringBuilder logBuilder = new StringBuilder(1024);
1645                        logBuilder.append("Low on memory:\n");
1646
1647                        boolean firstLine = true;
1648                        int lastOomAdj = Integer.MIN_VALUE;
1649                        for (int i=0, N=memInfos.size(); i<N; i++) {
1650                            ProcessMemInfo mi = memInfos.get(i);
1651
1652                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1653                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1654                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1655                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1656                                if (lastOomAdj != mi.oomAdj) {
1657                                    lastOomAdj = mi.oomAdj;
1658                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1659                                        tag.append(" / ");
1660                                    }
1661                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1662                                        if (firstLine) {
1663                                            stack.append(":");
1664                                            firstLine = false;
1665                                        }
1666                                        stack.append("\n\t at ");
1667                                    } else {
1668                                        stack.append("$");
1669                                    }
1670                                } else {
1671                                    tag.append(" ");
1672                                    stack.append("$");
1673                                }
1674                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1675                                    appendMemBucket(tag, mi.pss, mi.name, false);
1676                                }
1677                                appendMemBucket(stack, mi.pss, mi.name, true);
1678                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1679                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1680                                    stack.append("(");
1681                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1682                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1683                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1684                                            stack.append(":");
1685                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1686                                        }
1687                                    }
1688                                    stack.append(")");
1689                                }
1690                            }
1691
1692                            logBuilder.append("  ");
1693                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1694                            logBuilder.append(' ');
1695                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1696                            logBuilder.append(' ');
1697                            ProcessList.appendRamKb(logBuilder, mi.pss);
1698                            logBuilder.append(" kB: ");
1699                            logBuilder.append(mi.name);
1700                            logBuilder.append(" (");
1701                            logBuilder.append(mi.pid);
1702                            logBuilder.append(") ");
1703                            logBuilder.append(mi.adjType);
1704                            logBuilder.append('\n');
1705                            if (mi.adjReason != null) {
1706                                logBuilder.append("                      ");
1707                                logBuilder.append(mi.adjReason);
1708                                logBuilder.append('\n');
1709                            }
1710                        }
1711
1712                        logBuilder.append("           ");
1713                        ProcessList.appendRamKb(logBuilder, totalPss);
1714                        logBuilder.append(" kB: TOTAL\n");
1715
1716                        long[] infos = new long[Debug.MEMINFO_COUNT];
1717                        Debug.getMemInfo(infos);
1718                        logBuilder.append("  MemInfo: ");
1719                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1721                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1722                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1723                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1724                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1725                            logBuilder.append("  ZRAM: ");
1726                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1727                            logBuilder.append(" kB RAM, ");
1728                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1729                            logBuilder.append(" kB swap total, ");
1730                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1731                            logBuilder.append(" kB swap free\n");
1732                        }
1733                        Slog.i(TAG, logBuilder.toString());
1734
1735                        StringBuilder dropBuilder = new StringBuilder(1024);
1736                        /*
1737                        StringWriter oomSw = new StringWriter();
1738                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1739                        StringWriter catSw = new StringWriter();
1740                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1741                        String[] emptyArgs = new String[] { };
1742                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1743                        oomPw.flush();
1744                        String oomString = oomSw.toString();
1745                        */
1746                        dropBuilder.append(stack);
1747                        dropBuilder.append('\n');
1748                        dropBuilder.append('\n');
1749                        dropBuilder.append(logBuilder);
1750                        dropBuilder.append('\n');
1751                        /*
1752                        dropBuilder.append(oomString);
1753                        dropBuilder.append('\n');
1754                        */
1755                        StringWriter catSw = new StringWriter();
1756                        synchronized (ActivityManagerService.this) {
1757                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1758                            String[] emptyArgs = new String[] { };
1759                            catPw.println();
1760                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1761                            catPw.println();
1762                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1763                                    false, false, null);
1764                            catPw.println();
1765                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1766                            catPw.flush();
1767                        }
1768                        dropBuilder.append(catSw.toString());
1769                        addErrorToDropBox("lowmem", null, "system_server", null,
1770                                null, tag.toString(), dropBuilder.toString(), null, null);
1771                        //Slog.i(TAG, "Sent to dropbox:");
1772                        //Slog.i(TAG, dropBuilder.toString());
1773                        synchronized (ActivityManagerService.this) {
1774                            long now = SystemClock.uptimeMillis();
1775                            if (mLastMemUsageReportTime < now) {
1776                                mLastMemUsageReportTime = now;
1777                            }
1778                        }
1779                    }
1780                };
1781                thread.start();
1782                break;
1783            }
1784            case START_USER_SWITCH_MSG: {
1785                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1786                break;
1787            }
1788            case REPORT_USER_SWITCH_MSG: {
1789                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case CONTINUE_USER_SWITCH_MSG: {
1793                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case USER_SWITCH_TIMEOUT_MSG: {
1797                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case IMMERSIVE_MODE_LOCK_MSG: {
1801                final boolean nextState = (msg.arg1 != 0);
1802                if (mUpdateLock.isHeld() != nextState) {
1803                    if (DEBUG_IMMERSIVE) {
1804                        final ActivityRecord r = (ActivityRecord) msg.obj;
1805                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1806                    }
1807                    if (nextState) {
1808                        mUpdateLock.acquire();
1809                    } else {
1810                        mUpdateLock.release();
1811                    }
1812                }
1813                break;
1814            }
1815            case PERSIST_URI_GRANTS_MSG: {
1816                writeGrantedUriPermissions();
1817                break;
1818            }
1819            case REQUEST_ALL_PSS_MSG: {
1820                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1821                break;
1822            }
1823            case START_PROFILES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    startProfilesLocked();
1826                }
1827                break;
1828            }
1829            case UPDATE_TIME: {
1830                synchronized (ActivityManagerService.this) {
1831                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                        ProcessRecord r = mLruProcesses.get(i);
1833                        if (r.thread != null) {
1834                            try {
1835                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1836                            } catch (RemoteException ex) {
1837                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1838                            }
1839                        }
1840                    }
1841                }
1842                break;
1843            }
1844            case SYSTEM_USER_START_MSG: {
1845                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1846                        Integer.toString(msg.arg1), msg.arg1);
1847                mSystemServiceManager.startUser(msg.arg1);
1848                break;
1849            }
1850            case SYSTEM_USER_CURRENT_MSG: {
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1853                        Integer.toString(msg.arg2), msg.arg2);
1854                mBatteryStatsService.noteEvent(
1855                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1856                        Integer.toString(msg.arg1), msg.arg1);
1857                mSystemServiceManager.switchUser(msg.arg1);
1858                mLockToAppRequest.clearPrompt();
1859                break;
1860            }
1861            case ENTER_ANIMATION_COMPLETE_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1864                    if (r != null && r.app != null && r.app.thread != null) {
1865                        try {
1866                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1867                        } catch (RemoteException e) {
1868                        }
1869                    }
1870                }
1871                break;
1872            }
1873            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1874                enableScreenAfterBoot();
1875                break;
1876            }
1877            }
1878        }
1879    };
1880
1881    static final int COLLECT_PSS_BG_MSG = 1;
1882
1883    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1884        @Override
1885        public void handleMessage(Message msg) {
1886            switch (msg.what) {
1887            case COLLECT_PSS_BG_MSG: {
1888                long start = SystemClock.uptimeMillis();
1889                MemInfoReader memInfo = null;
1890                synchronized (ActivityManagerService.this) {
1891                    if (mFullPssPending) {
1892                        mFullPssPending = false;
1893                        memInfo = new MemInfoReader();
1894                    }
1895                }
1896                if (memInfo != null) {
1897                    updateCpuStatsNow();
1898                    long nativeTotalPss = 0;
1899                    synchronized (mProcessCpuThread) {
1900                        final int N = mProcessCpuTracker.countStats();
1901                        for (int j=0; j<N; j++) {
1902                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1903                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1904                                // This is definitely an application process; skip it.
1905                                continue;
1906                            }
1907                            synchronized (mPidsSelfLocked) {
1908                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1909                                    // This is one of our own processes; skip it.
1910                                    continue;
1911                                }
1912                            }
1913                            nativeTotalPss += Debug.getPss(st.pid, null);
1914                        }
1915                    }
1916                    memInfo.readMemInfo();
1917                    synchronized (this) {
1918                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1919                                + (SystemClock.uptimeMillis()-start) + "ms");
1920                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1921                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1922                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1923                                        +memInfo.getSlabSizeKb(),
1924                                nativeTotalPss);
1925                    }
1926                }
1927
1928                int i=0, num=0;
1929                long[] tmp = new long[1];
1930                do {
1931                    ProcessRecord proc;
1932                    int procState;
1933                    int pid;
1934                    synchronized (ActivityManagerService.this) {
1935                        if (i >= mPendingPssProcesses.size()) {
1936                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1937                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1938                            mPendingPssProcesses.clear();
1939                            return;
1940                        }
1941                        proc = mPendingPssProcesses.get(i);
1942                        procState = proc.pssProcState;
1943                        if (proc.thread != null && procState == proc.setProcState) {
1944                            pid = proc.pid;
1945                        } else {
1946                            proc = null;
1947                            pid = 0;
1948                        }
1949                        i++;
1950                    }
1951                    if (proc != null) {
1952                        long pss = Debug.getPss(pid, tmp);
1953                        synchronized (ActivityManagerService.this) {
1954                            if (proc.thread != null && proc.setProcState == procState
1955                                    && proc.pid == pid) {
1956                                num++;
1957                                proc.lastPssTime = SystemClock.uptimeMillis();
1958                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1959                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1960                                        + ": " + pss + " lastPss=" + proc.lastPss
1961                                        + " state=" + ProcessList.makeProcStateString(procState));
1962                                if (proc.initialIdlePss == 0) {
1963                                    proc.initialIdlePss = pss;
1964                                }
1965                                proc.lastPss = pss;
1966                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1967                                    proc.lastCachedPss = pss;
1968                                }
1969                            }
1970                        }
1971                    }
1972                } while (true);
1973            }
1974            }
1975        }
1976    };
1977
1978    /**
1979     * Monitor for package changes and update our internal state.
1980     */
1981    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1982        @Override
1983        public void onPackageRemoved(String packageName, int uid) {
1984            // Remove all tasks with activities in the specified package from the list of recent tasks
1985            synchronized (ActivityManagerService.this) {
1986                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1987                    TaskRecord tr = mRecentTasks.get(i);
1988                    ComponentName cn = tr.intent.getComponent();
1989                    if (cn != null && cn.getPackageName().equals(packageName)) {
1990                        // If the package name matches, remove the task and kill the process
1991                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1992                    }
1993                }
1994            }
1995        }
1996
1997        @Override
1998        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1999            onPackageModified(packageName);
2000            return true;
2001        }
2002
2003        @Override
2004        public void onPackageModified(String packageName) {
2005            final PackageManager pm = mContext.getPackageManager();
2006            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2007                    new ArrayList<Pair<Intent, Integer>>();
2008            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2009            // Copy the list of recent tasks so that we don't hold onto the lock on
2010            // ActivityManagerService for long periods while checking if components exist.
2011            synchronized (ActivityManagerService.this) {
2012                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2013                    TaskRecord tr = mRecentTasks.get(i);
2014                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2015                }
2016            }
2017            // Check the recent tasks and filter out all tasks with components that no longer exist.
2018            Intent tmpI = new Intent();
2019            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2020                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2021                ComponentName cn = p.first.getComponent();
2022                if (cn != null && cn.getPackageName().equals(packageName)) {
2023                    try {
2024                        // Add the task to the list to remove if the component no longer exists
2025                        tmpI.setComponent(cn);
2026                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2027                            tasksToRemove.add(p.second);
2028                        }
2029                    } catch (Exception e) {}
2030                }
2031            }
2032            // Prune all the tasks with removed components from the list of recent tasks
2033            synchronized (ActivityManagerService.this) {
2034                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2035                    // Remove the task but don't kill the process (since other components in that
2036                    // package may still be running and in the background)
2037                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2038                }
2039            }
2040        }
2041
2042        @Override
2043        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2044            // Force stop the specified packages
2045            if (packages != null) {
2046                for (String pkg : packages) {
2047                    synchronized (ActivityManagerService.this) {
2048                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2049                                "finished booting")) {
2050                            return true;
2051                        }
2052                    }
2053                }
2054            }
2055            return false;
2056        }
2057    };
2058
2059    public void setSystemProcess() {
2060        try {
2061            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2062            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2063            ServiceManager.addService("meminfo", new MemBinder(this));
2064            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2065            ServiceManager.addService("dbinfo", new DbBinder(this));
2066            if (MONITOR_CPU_USAGE) {
2067                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2068            }
2069            ServiceManager.addService("permission", new PermissionController(this));
2070
2071            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2072                    "android", STOCK_PM_FLAGS);
2073            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2074
2075            synchronized (this) {
2076                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2077                app.persistent = true;
2078                app.pid = MY_PID;
2079                app.maxAdj = ProcessList.SYSTEM_ADJ;
2080                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2081                mProcessNames.put(app.processName, app.uid, app);
2082                synchronized (mPidsSelfLocked) {
2083                    mPidsSelfLocked.put(app.pid, app);
2084                }
2085                updateLruProcessLocked(app, false, null);
2086                updateOomAdjLocked();
2087            }
2088        } catch (PackageManager.NameNotFoundException e) {
2089            throw new RuntimeException(
2090                    "Unable to find android system package", e);
2091        }
2092    }
2093
2094    public void setWindowManager(WindowManagerService wm) {
2095        mWindowManager = wm;
2096        mStackSupervisor.setWindowManager(wm);
2097    }
2098
2099    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2100        mUsageStatsService = usageStatsManager;
2101    }
2102
2103    public void startObservingNativeCrashes() {
2104        final NativeCrashListener ncl = new NativeCrashListener(this);
2105        ncl.start();
2106    }
2107
2108    public IAppOpsService getAppOpsService() {
2109        return mAppOpsService;
2110    }
2111
2112    static class MemBinder extends Binder {
2113        ActivityManagerService mActivityManagerService;
2114        MemBinder(ActivityManagerService activityManagerService) {
2115            mActivityManagerService = activityManagerService;
2116        }
2117
2118        @Override
2119        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2120            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2121                    != PackageManager.PERMISSION_GRANTED) {
2122                pw.println("Permission Denial: can't dump meminfo from from pid="
2123                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2124                        + " without permission " + android.Manifest.permission.DUMP);
2125                return;
2126            }
2127
2128            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2129        }
2130    }
2131
2132    static class GraphicsBinder extends Binder {
2133        ActivityManagerService mActivityManagerService;
2134        GraphicsBinder(ActivityManagerService activityManagerService) {
2135            mActivityManagerService = activityManagerService;
2136        }
2137
2138        @Override
2139        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2140            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2141                    != PackageManager.PERMISSION_GRANTED) {
2142                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2143                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2144                        + " without permission " + android.Manifest.permission.DUMP);
2145                return;
2146            }
2147
2148            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2149        }
2150    }
2151
2152    static class DbBinder extends Binder {
2153        ActivityManagerService mActivityManagerService;
2154        DbBinder(ActivityManagerService activityManagerService) {
2155            mActivityManagerService = activityManagerService;
2156        }
2157
2158        @Override
2159        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2160            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2161                    != PackageManager.PERMISSION_GRANTED) {
2162                pw.println("Permission Denial: can't dump dbinfo from from pid="
2163                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2164                        + " without permission " + android.Manifest.permission.DUMP);
2165                return;
2166            }
2167
2168            mActivityManagerService.dumpDbInfo(fd, pw, args);
2169        }
2170    }
2171
2172    static class CpuBinder extends Binder {
2173        ActivityManagerService mActivityManagerService;
2174        CpuBinder(ActivityManagerService activityManagerService) {
2175            mActivityManagerService = activityManagerService;
2176        }
2177
2178        @Override
2179        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2180            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2181                    != PackageManager.PERMISSION_GRANTED) {
2182                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2183                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2184                        + " without permission " + android.Manifest.permission.DUMP);
2185                return;
2186            }
2187
2188            synchronized (mActivityManagerService.mProcessCpuThread) {
2189                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2190                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2191                        SystemClock.uptimeMillis()));
2192            }
2193        }
2194    }
2195
2196    public static final class Lifecycle extends SystemService {
2197        private final ActivityManagerService mService;
2198
2199        public Lifecycle(Context context) {
2200            super(context);
2201            mService = new ActivityManagerService(context);
2202        }
2203
2204        @Override
2205        public void onStart() {
2206            mService.start();
2207        }
2208
2209        public ActivityManagerService getService() {
2210            return mService;
2211        }
2212    }
2213
2214    // Note: This method is invoked on the main thread but may need to attach various
2215    // handlers to other threads.  So take care to be explicit about the looper.
2216    public ActivityManagerService(Context systemContext) {
2217        mContext = systemContext;
2218        mFactoryTest = FactoryTest.getMode();
2219        mSystemThread = ActivityThread.currentActivityThread();
2220
2221        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2222
2223        mHandlerThread = new ServiceThread(TAG,
2224                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2225        mHandlerThread.start();
2226        mHandler = new MainHandler(mHandlerThread.getLooper());
2227
2228        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2229                "foreground", BROADCAST_FG_TIMEOUT, false);
2230        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2231                "background", BROADCAST_BG_TIMEOUT, true);
2232        mBroadcastQueues[0] = mFgBroadcastQueue;
2233        mBroadcastQueues[1] = mBgBroadcastQueue;
2234
2235        mServices = new ActiveServices(this);
2236        mProviderMap = new ProviderMap(this);
2237
2238        // TODO: Move creation of battery stats service outside of activity manager service.
2239        File dataDir = Environment.getDataDirectory();
2240        File systemDir = new File(dataDir, "system");
2241        systemDir.mkdirs();
2242        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2243        mBatteryStatsService.getActiveStatistics().readLocked();
2244        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2245        mOnBattery = DEBUG_POWER ? true
2246                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2247        mBatteryStatsService.getActiveStatistics().setCallback(this);
2248
2249        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2250
2251        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2252
2253        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2254
2255        // User 0 is the first and only user that runs at boot.
2256        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2257        mUserLru.add(Integer.valueOf(0));
2258        updateStartedUserArrayLocked();
2259
2260        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2261            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2262
2263        mConfiguration.setToDefaults();
2264        mConfiguration.setLocale(Locale.getDefault());
2265
2266        mConfigurationSeq = mConfiguration.seq = 1;
2267        mProcessCpuTracker.init();
2268
2269        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2270        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2271        mStackSupervisor = new ActivityStackSupervisor(this);
2272        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2273
2274        mProcessCpuThread = new Thread("CpuTracker") {
2275            @Override
2276            public void run() {
2277                while (true) {
2278                    try {
2279                        try {
2280                            synchronized(this) {
2281                                final long now = SystemClock.uptimeMillis();
2282                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2283                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2284                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2285                                //        + ", write delay=" + nextWriteDelay);
2286                                if (nextWriteDelay < nextCpuDelay) {
2287                                    nextCpuDelay = nextWriteDelay;
2288                                }
2289                                if (nextCpuDelay > 0) {
2290                                    mProcessCpuMutexFree.set(true);
2291                                    this.wait(nextCpuDelay);
2292                                }
2293                            }
2294                        } catch (InterruptedException e) {
2295                        }
2296                        updateCpuStatsNow();
2297                    } catch (Exception e) {
2298                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2299                    }
2300                }
2301            }
2302        };
2303
2304        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2305
2306        Watchdog.getInstance().addMonitor(this);
2307        Watchdog.getInstance().addThread(mHandler);
2308    }
2309
2310    public void setSystemServiceManager(SystemServiceManager mgr) {
2311        mSystemServiceManager = mgr;
2312    }
2313
2314    private void start() {
2315        Process.removeAllProcessGroups();
2316        mProcessCpuThread.start();
2317
2318        mBatteryStatsService.publish(mContext);
2319        mAppOpsService.publish(mContext);
2320        Slog.d("AppOps", "AppOpsService published");
2321        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2322    }
2323
2324    public void initPowerManagement() {
2325        mStackSupervisor.initPowerManagement();
2326        mBatteryStatsService.initPowerManagement();
2327    }
2328
2329    @Override
2330    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2331            throws RemoteException {
2332        if (code == SYSPROPS_TRANSACTION) {
2333            // We need to tell all apps about the system property change.
2334            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2335            synchronized(this) {
2336                final int NP = mProcessNames.getMap().size();
2337                for (int ip=0; ip<NP; ip++) {
2338                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2339                    final int NA = apps.size();
2340                    for (int ia=0; ia<NA; ia++) {
2341                        ProcessRecord app = apps.valueAt(ia);
2342                        if (app.thread != null) {
2343                            procs.add(app.thread.asBinder());
2344                        }
2345                    }
2346                }
2347            }
2348
2349            int N = procs.size();
2350            for (int i=0; i<N; i++) {
2351                Parcel data2 = Parcel.obtain();
2352                try {
2353                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2354                } catch (RemoteException e) {
2355                }
2356                data2.recycle();
2357            }
2358        }
2359        try {
2360            return super.onTransact(code, data, reply, flags);
2361        } catch (RuntimeException e) {
2362            // The activity manager only throws security exceptions, so let's
2363            // log all others.
2364            if (!(e instanceof SecurityException)) {
2365                Slog.wtf(TAG, "Activity Manager Crash", e);
2366            }
2367            throw e;
2368        }
2369    }
2370
2371    void updateCpuStats() {
2372        final long now = SystemClock.uptimeMillis();
2373        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2374            return;
2375        }
2376        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2377            synchronized (mProcessCpuThread) {
2378                mProcessCpuThread.notify();
2379            }
2380        }
2381    }
2382
2383    void updateCpuStatsNow() {
2384        synchronized (mProcessCpuThread) {
2385            mProcessCpuMutexFree.set(false);
2386            final long now = SystemClock.uptimeMillis();
2387            boolean haveNewCpuStats = false;
2388
2389            if (MONITOR_CPU_USAGE &&
2390                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2391                mLastCpuTime.set(now);
2392                haveNewCpuStats = true;
2393                mProcessCpuTracker.update();
2394                //Slog.i(TAG, mProcessCpu.printCurrentState());
2395                //Slog.i(TAG, "Total CPU usage: "
2396                //        + mProcessCpu.getTotalCpuPercent() + "%");
2397
2398                // Slog the cpu usage if the property is set.
2399                if ("true".equals(SystemProperties.get("events.cpu"))) {
2400                    int user = mProcessCpuTracker.getLastUserTime();
2401                    int system = mProcessCpuTracker.getLastSystemTime();
2402                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2403                    int irq = mProcessCpuTracker.getLastIrqTime();
2404                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2405                    int idle = mProcessCpuTracker.getLastIdleTime();
2406
2407                    int total = user + system + iowait + irq + softIrq + idle;
2408                    if (total == 0) total = 1;
2409
2410                    EventLog.writeEvent(EventLogTags.CPU,
2411                            ((user+system+iowait+irq+softIrq) * 100) / total,
2412                            (user * 100) / total,
2413                            (system * 100) / total,
2414                            (iowait * 100) / total,
2415                            (irq * 100) / total,
2416                            (softIrq * 100) / total);
2417                }
2418            }
2419
2420            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2421            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2422            synchronized(bstats) {
2423                synchronized(mPidsSelfLocked) {
2424                    if (haveNewCpuStats) {
2425                        if (mOnBattery) {
2426                            int perc = bstats.startAddingCpuLocked();
2427                            int totalUTime = 0;
2428                            int totalSTime = 0;
2429                            final int N = mProcessCpuTracker.countStats();
2430                            for (int i=0; i<N; i++) {
2431                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2432                                if (!st.working) {
2433                                    continue;
2434                                }
2435                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2436                                int otherUTime = (st.rel_utime*perc)/100;
2437                                int otherSTime = (st.rel_stime*perc)/100;
2438                                totalUTime += otherUTime;
2439                                totalSTime += otherSTime;
2440                                if (pr != null) {
2441                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2442                                    if (ps == null || !ps.isActive()) {
2443                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2444                                                pr.info.uid, pr.processName);
2445                                    }
2446                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2447                                            st.rel_stime-otherSTime);
2448                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2449                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2450                                } else {
2451                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2452                                    if (ps == null || !ps.isActive()) {
2453                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2454                                                bstats.mapUid(st.uid), st.name);
2455                                    }
2456                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2457                                            st.rel_stime-otherSTime);
2458                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2459                                }
2460                            }
2461                            bstats.finishAddingCpuLocked(perc, totalUTime,
2462                                    totalSTime, cpuSpeedTimes);
2463                        }
2464                    }
2465                }
2466
2467                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2468                    mLastWriteTime = now;
2469                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2470                }
2471            }
2472        }
2473    }
2474
2475    @Override
2476    public void batteryNeedsCpuUpdate() {
2477        updateCpuStatsNow();
2478    }
2479
2480    @Override
2481    public void batteryPowerChanged(boolean onBattery) {
2482        // When plugging in, update the CPU stats first before changing
2483        // the plug state.
2484        updateCpuStatsNow();
2485        synchronized (this) {
2486            synchronized(mPidsSelfLocked) {
2487                mOnBattery = DEBUG_POWER ? true : onBattery;
2488            }
2489        }
2490    }
2491
2492    /**
2493     * Initialize the application bind args. These are passed to each
2494     * process when the bindApplication() IPC is sent to the process. They're
2495     * lazily setup to make sure the services are running when they're asked for.
2496     */
2497    private HashMap<String, IBinder> getCommonServicesLocked() {
2498        if (mAppBindArgs == null) {
2499            mAppBindArgs = new HashMap<String, IBinder>();
2500
2501            // Setup the application init args
2502            mAppBindArgs.put("package", ServiceManager.getService("package"));
2503            mAppBindArgs.put("window", ServiceManager.getService("window"));
2504            mAppBindArgs.put(Context.ALARM_SERVICE,
2505                    ServiceManager.getService(Context.ALARM_SERVICE));
2506        }
2507        return mAppBindArgs;
2508    }
2509
2510    final void setFocusedActivityLocked(ActivityRecord r) {
2511        if (mFocusedActivity != r) {
2512            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2513            mFocusedActivity = r;
2514            if (r.task != null && r.task.voiceInteractor != null) {
2515                startRunningVoiceLocked();
2516            } else {
2517                finishRunningVoiceLocked();
2518            }
2519            mStackSupervisor.setFocusedStack(r);
2520            if (r != null) {
2521                mWindowManager.setFocusedApp(r.appToken, true);
2522            }
2523            applyUpdateLockStateLocked(r);
2524        }
2525    }
2526
2527    final void clearFocusedActivity(ActivityRecord r) {
2528        if (mFocusedActivity == r) {
2529            mFocusedActivity = null;
2530        }
2531    }
2532
2533    @Override
2534    public void setFocusedStack(int stackId) {
2535        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2536        synchronized (ActivityManagerService.this) {
2537            ActivityStack stack = mStackSupervisor.getStack(stackId);
2538            if (stack != null) {
2539                ActivityRecord r = stack.topRunningActivityLocked(null);
2540                if (r != null) {
2541                    setFocusedActivityLocked(r);
2542                }
2543            }
2544        }
2545    }
2546
2547    @Override
2548    public void notifyActivityDrawn(IBinder token) {
2549        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2550        synchronized (this) {
2551            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2552            if (r != null) {
2553                r.task.stack.notifyActivityDrawnLocked(r);
2554            }
2555        }
2556    }
2557
2558    final void applyUpdateLockStateLocked(ActivityRecord r) {
2559        // Modifications to the UpdateLock state are done on our handler, outside
2560        // the activity manager's locks.  The new state is determined based on the
2561        // state *now* of the relevant activity record.  The object is passed to
2562        // the handler solely for logging detail, not to be consulted/modified.
2563        final boolean nextState = r != null && r.immersive;
2564        mHandler.sendMessage(
2565                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2566    }
2567
2568    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2569        Message msg = Message.obtain();
2570        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2571        msg.obj = r.task.askedCompatMode ? null : r;
2572        mHandler.sendMessage(msg);
2573    }
2574
2575    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2576            String what, Object obj, ProcessRecord srcApp) {
2577        app.lastActivityTime = now;
2578
2579        if (app.activities.size() > 0) {
2580            // Don't want to touch dependent processes that are hosting activities.
2581            return index;
2582        }
2583
2584        int lrui = mLruProcesses.lastIndexOf(app);
2585        if (lrui < 0) {
2586            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2587                    + what + " " + obj + " from " + srcApp);
2588            return index;
2589        }
2590
2591        if (lrui >= index) {
2592            // Don't want to cause this to move dependent processes *back* in the
2593            // list as if they were less frequently used.
2594            return index;
2595        }
2596
2597        if (lrui >= mLruProcessActivityStart) {
2598            // Don't want to touch dependent processes that are hosting activities.
2599            return index;
2600        }
2601
2602        mLruProcesses.remove(lrui);
2603        if (index > 0) {
2604            index--;
2605        }
2606        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2607                + " in LRU list: " + app);
2608        mLruProcesses.add(index, app);
2609        return index;
2610    }
2611
2612    final void removeLruProcessLocked(ProcessRecord app) {
2613        int lrui = mLruProcesses.lastIndexOf(app);
2614        if (lrui >= 0) {
2615            if (lrui <= mLruProcessActivityStart) {
2616                mLruProcessActivityStart--;
2617            }
2618            if (lrui <= mLruProcessServiceStart) {
2619                mLruProcessServiceStart--;
2620            }
2621            mLruProcesses.remove(lrui);
2622        }
2623    }
2624
2625    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2626            ProcessRecord client) {
2627        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2628                || app.treatLikeActivity;
2629        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2630        if (!activityChange && hasActivity) {
2631            // The process has activities, so we are only allowing activity-based adjustments
2632            // to move it.  It should be kept in the front of the list with other
2633            // processes that have activities, and we don't want those to change their
2634            // order except due to activity operations.
2635            return;
2636        }
2637
2638        mLruSeq++;
2639        final long now = SystemClock.uptimeMillis();
2640        app.lastActivityTime = now;
2641
2642        // First a quick reject: if the app is already at the position we will
2643        // put it, then there is nothing to do.
2644        if (hasActivity) {
2645            final int N = mLruProcesses.size();
2646            if (N > 0 && mLruProcesses.get(N-1) == app) {
2647                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2648                return;
2649            }
2650        } else {
2651            if (mLruProcessServiceStart > 0
2652                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2653                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2654                return;
2655            }
2656        }
2657
2658        int lrui = mLruProcesses.lastIndexOf(app);
2659
2660        if (app.persistent && lrui >= 0) {
2661            // We don't care about the position of persistent processes, as long as
2662            // they are in the list.
2663            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2664            return;
2665        }
2666
2667        /* In progress: compute new position first, so we can avoid doing work
2668           if the process is not actually going to move.  Not yet working.
2669        int addIndex;
2670        int nextIndex;
2671        boolean inActivity = false, inService = false;
2672        if (hasActivity) {
2673            // Process has activities, put it at the very tipsy-top.
2674            addIndex = mLruProcesses.size();
2675            nextIndex = mLruProcessServiceStart;
2676            inActivity = true;
2677        } else if (hasService) {
2678            // Process has services, put it at the top of the service list.
2679            addIndex = mLruProcessActivityStart;
2680            nextIndex = mLruProcessServiceStart;
2681            inActivity = true;
2682            inService = true;
2683        } else  {
2684            // Process not otherwise of interest, it goes to the top of the non-service area.
2685            addIndex = mLruProcessServiceStart;
2686            if (client != null) {
2687                int clientIndex = mLruProcesses.lastIndexOf(client);
2688                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2689                        + app);
2690                if (clientIndex >= 0 && addIndex > clientIndex) {
2691                    addIndex = clientIndex;
2692                }
2693            }
2694            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2695        }
2696
2697        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2698                + mLruProcessActivityStart + "): " + app);
2699        */
2700
2701        if (lrui >= 0) {
2702            if (lrui < mLruProcessActivityStart) {
2703                mLruProcessActivityStart--;
2704            }
2705            if (lrui < mLruProcessServiceStart) {
2706                mLruProcessServiceStart--;
2707            }
2708            /*
2709            if (addIndex > lrui) {
2710                addIndex--;
2711            }
2712            if (nextIndex > lrui) {
2713                nextIndex--;
2714            }
2715            */
2716            mLruProcesses.remove(lrui);
2717        }
2718
2719        /*
2720        mLruProcesses.add(addIndex, app);
2721        if (inActivity) {
2722            mLruProcessActivityStart++;
2723        }
2724        if (inService) {
2725            mLruProcessActivityStart++;
2726        }
2727        */
2728
2729        int nextIndex;
2730        if (hasActivity) {
2731            final int N = mLruProcesses.size();
2732            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2733                // Process doesn't have activities, but has clients with
2734                // activities...  move it up, but one below the top (the top
2735                // should always have a real activity).
2736                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2737                mLruProcesses.add(N-1, app);
2738                // To keep it from spamming the LRU list (by making a bunch of clients),
2739                // we will push down any other entries owned by the app.
2740                final int uid = app.info.uid;
2741                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2742                    ProcessRecord subProc = mLruProcesses.get(i);
2743                    if (subProc.info.uid == uid) {
2744                        // We want to push this one down the list.  If the process after
2745                        // it is for the same uid, however, don't do so, because we don't
2746                        // want them internally to be re-ordered.
2747                        if (mLruProcesses.get(i-1).info.uid != uid) {
2748                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2749                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2750                            ProcessRecord tmp = mLruProcesses.get(i);
2751                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2752                            mLruProcesses.set(i-1, tmp);
2753                            i--;
2754                        }
2755                    } else {
2756                        // A gap, we can stop here.
2757                        break;
2758                    }
2759                }
2760            } else {
2761                // Process has activities, put it at the very tipsy-top.
2762                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2763                mLruProcesses.add(app);
2764            }
2765            nextIndex = mLruProcessServiceStart;
2766        } else if (hasService) {
2767            // Process has services, put it at the top of the service list.
2768            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2769            mLruProcesses.add(mLruProcessActivityStart, app);
2770            nextIndex = mLruProcessServiceStart;
2771            mLruProcessActivityStart++;
2772        } else  {
2773            // Process not otherwise of interest, it goes to the top of the non-service area.
2774            int index = mLruProcessServiceStart;
2775            if (client != null) {
2776                // If there is a client, don't allow the process to be moved up higher
2777                // in the list than that client.
2778                int clientIndex = mLruProcesses.lastIndexOf(client);
2779                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2780                        + " when updating " + app);
2781                if (clientIndex <= lrui) {
2782                    // Don't allow the client index restriction to push it down farther in the
2783                    // list than it already is.
2784                    clientIndex = lrui;
2785                }
2786                if (clientIndex >= 0 && index > clientIndex) {
2787                    index = clientIndex;
2788                }
2789            }
2790            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2791            mLruProcesses.add(index, app);
2792            nextIndex = index-1;
2793            mLruProcessActivityStart++;
2794            mLruProcessServiceStart++;
2795        }
2796
2797        // If the app is currently using a content provider or service,
2798        // bump those processes as well.
2799        for (int j=app.connections.size()-1; j>=0; j--) {
2800            ConnectionRecord cr = app.connections.valueAt(j);
2801            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2802                    && cr.binding.service.app != null
2803                    && cr.binding.service.app.lruSeq != mLruSeq
2804                    && !cr.binding.service.app.persistent) {
2805                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2806                        "service connection", cr, app);
2807            }
2808        }
2809        for (int j=app.conProviders.size()-1; j>=0; j--) {
2810            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2811            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2812                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2813                        "provider reference", cpr, app);
2814            }
2815        }
2816    }
2817
2818    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2819        if (uid == Process.SYSTEM_UID) {
2820            // The system gets to run in any process.  If there are multiple
2821            // processes with the same uid, just pick the first (this
2822            // should never happen).
2823            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2824            if (procs == null) return null;
2825            final int N = procs.size();
2826            for (int i = 0; i < N; i++) {
2827                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2828            }
2829        }
2830        ProcessRecord proc = mProcessNames.get(processName, uid);
2831        if (false && proc != null && !keepIfLarge
2832                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2833                && proc.lastCachedPss >= 4000) {
2834            // Turn this condition on to cause killing to happen regularly, for testing.
2835            if (proc.baseProcessTracker != null) {
2836                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2837            }
2838            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2839        } else if (proc != null && !keepIfLarge
2840                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2841                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2842            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2843            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2844                if (proc.baseProcessTracker != null) {
2845                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2846                }
2847                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2848            }
2849        }
2850        return proc;
2851    }
2852
2853    void ensurePackageDexOpt(String packageName) {
2854        IPackageManager pm = AppGlobals.getPackageManager();
2855        try {
2856            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2857                mDidDexOpt = true;
2858            }
2859        } catch (RemoteException e) {
2860        }
2861    }
2862
2863    boolean isNextTransitionForward() {
2864        int transit = mWindowManager.getPendingAppTransition();
2865        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2866                || transit == AppTransition.TRANSIT_TASK_OPEN
2867                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2868    }
2869
2870    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2871            String processName, String abiOverride, int uid, Runnable crashHandler) {
2872        synchronized(this) {
2873            ApplicationInfo info = new ApplicationInfo();
2874            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2875            // For isolated processes, the former contains the parent's uid and the latter the
2876            // actual uid of the isolated process.
2877            // In the special case introduced by this method (which is, starting an isolated
2878            // process directly from the SystemServer without an actual parent app process) the
2879            // closest thing to a parent's uid is SYSTEM_UID.
2880            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2881            // the |isolated| logic in the ProcessRecord constructor.
2882            info.uid = Process.SYSTEM_UID;
2883            info.processName = processName;
2884            info.className = entryPoint;
2885            info.packageName = "android";
2886            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2887                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2888                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2889                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2890                    crashHandler);
2891            return proc != null ? proc.pid : 0;
2892        }
2893    }
2894
2895    final ProcessRecord startProcessLocked(String processName,
2896            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2897            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2898            boolean isolated, boolean keepIfLarge) {
2899        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2900                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2901                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2902                null /* crashHandler */);
2903    }
2904
2905    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2906            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2907            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2908            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2909        long startTime = SystemClock.elapsedRealtime();
2910        ProcessRecord app;
2911        if (!isolated) {
2912            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2913            checkTime(startTime, "startProcess: after getProcessRecord");
2914        } else {
2915            // If this is an isolated process, it can't re-use an existing process.
2916            app = null;
2917        }
2918        // We don't have to do anything more if:
2919        // (1) There is an existing application record; and
2920        // (2) The caller doesn't think it is dead, OR there is no thread
2921        //     object attached to it so we know it couldn't have crashed; and
2922        // (3) There is a pid assigned to it, so it is either starting or
2923        //     already running.
2924        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2925                + " app=" + app + " knownToBeDead=" + knownToBeDead
2926                + " thread=" + (app != null ? app.thread : null)
2927                + " pid=" + (app != null ? app.pid : -1));
2928        if (app != null && app.pid > 0) {
2929            if (!knownToBeDead || app.thread == null) {
2930                // We already have the app running, or are waiting for it to
2931                // come up (we have a pid but not yet its thread), so keep it.
2932                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2933                // If this is a new package in the process, add the package to the list
2934                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2935                checkTime(startTime, "startProcess: done, added package to proc");
2936                return app;
2937            }
2938
2939            // An application record is attached to a previous process,
2940            // clean it up now.
2941            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2942            checkTime(startTime, "startProcess: bad proc running, killing");
2943            Process.killProcessGroup(app.info.uid, app.pid);
2944            handleAppDiedLocked(app, true, true);
2945            checkTime(startTime, "startProcess: done killing old proc");
2946        }
2947
2948        String hostingNameStr = hostingName != null
2949                ? hostingName.flattenToShortString() : null;
2950
2951        if (!isolated) {
2952            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2953                // If we are in the background, then check to see if this process
2954                // is bad.  If so, we will just silently fail.
2955                if (mBadProcesses.get(info.processName, info.uid) != null) {
2956                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2957                            + "/" + info.processName);
2958                    return null;
2959                }
2960            } else {
2961                // When the user is explicitly starting a process, then clear its
2962                // crash count so that we won't make it bad until they see at
2963                // least one crash dialog again, and make the process good again
2964                // if it had been bad.
2965                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2966                        + "/" + info.processName);
2967                mProcessCrashTimes.remove(info.processName, info.uid);
2968                if (mBadProcesses.get(info.processName, info.uid) != null) {
2969                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2970                            UserHandle.getUserId(info.uid), info.uid,
2971                            info.processName);
2972                    mBadProcesses.remove(info.processName, info.uid);
2973                    if (app != null) {
2974                        app.bad = false;
2975                    }
2976                }
2977            }
2978        }
2979
2980        if (app == null) {
2981            checkTime(startTime, "startProcess: creating new process record");
2982            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2983            app.crashHandler = crashHandler;
2984            if (app == null) {
2985                Slog.w(TAG, "Failed making new process record for "
2986                        + processName + "/" + info.uid + " isolated=" + isolated);
2987                return null;
2988            }
2989            mProcessNames.put(processName, app.uid, app);
2990            if (isolated) {
2991                mIsolatedProcesses.put(app.uid, app);
2992            }
2993            checkTime(startTime, "startProcess: done creating new process record");
2994        } else {
2995            // If this is a new package in the process, add the package to the list
2996            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2997            checkTime(startTime, "startProcess: added package to existing proc");
2998        }
2999
3000        // If the system is not ready yet, then hold off on starting this
3001        // process until it is.
3002        if (!mProcessesReady
3003                && !isAllowedWhileBooting(info)
3004                && !allowWhileBooting) {
3005            if (!mProcessesOnHold.contains(app)) {
3006                mProcessesOnHold.add(app);
3007            }
3008            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3009            checkTime(startTime, "startProcess: returning with proc on hold");
3010            return app;
3011        }
3012
3013        checkTime(startTime, "startProcess: stepping in to startProcess");
3014        startProcessLocked(
3015                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3016        checkTime(startTime, "startProcess: done starting proc!");
3017        return (app.pid != 0) ? app : null;
3018    }
3019
3020    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3021        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3022    }
3023
3024    private final void startProcessLocked(ProcessRecord app,
3025            String hostingType, String hostingNameStr) {
3026        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3027                null /* entryPoint */, null /* entryPointArgs */);
3028    }
3029
3030    private final void startProcessLocked(ProcessRecord app, String hostingType,
3031            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3032        long startTime = SystemClock.elapsedRealtime();
3033        if (app.pid > 0 && app.pid != MY_PID) {
3034            checkTime(startTime, "startProcess: removing from pids map");
3035            synchronized (mPidsSelfLocked) {
3036                mPidsSelfLocked.remove(app.pid);
3037                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3038            }
3039            checkTime(startTime, "startProcess: done removing from pids map");
3040            app.setPid(0);
3041        }
3042
3043        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3044                "startProcessLocked removing on hold: " + app);
3045        mProcessesOnHold.remove(app);
3046
3047        checkTime(startTime, "startProcess: starting to update cpu stats");
3048        updateCpuStats();
3049        checkTime(startTime, "startProcess: done updating cpu stats");
3050
3051        try {
3052            int uid = app.uid;
3053
3054            int[] gids = null;
3055            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3056            if (!app.isolated) {
3057                int[] permGids = null;
3058                try {
3059                    checkTime(startTime, "startProcess: getting gids from package manager");
3060                    final PackageManager pm = mContext.getPackageManager();
3061                    permGids = pm.getPackageGids(app.info.packageName);
3062
3063                    if (Environment.isExternalStorageEmulated()) {
3064                        checkTime(startTime, "startProcess: checking external storage perm");
3065                        if (pm.checkPermission(
3066                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3067                                app.info.packageName) == PERMISSION_GRANTED) {
3068                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3069                        } else {
3070                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3071                        }
3072                    }
3073                } catch (PackageManager.NameNotFoundException e) {
3074                    Slog.w(TAG, "Unable to retrieve gids", e);
3075                }
3076
3077                /*
3078                 * Add shared application and profile GIDs so applications can share some
3079                 * resources like shared libraries and access user-wide resources
3080                 */
3081                if (permGids == null) {
3082                    gids = new int[2];
3083                } else {
3084                    gids = new int[permGids.length + 2];
3085                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3086                }
3087                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3088                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3089            }
3090            checkTime(startTime, "startProcess: building args");
3091            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3092                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3093                        && mTopComponent != null
3094                        && app.processName.equals(mTopComponent.getPackageName())) {
3095                    uid = 0;
3096                }
3097                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3098                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3099                    uid = 0;
3100                }
3101            }
3102            int debugFlags = 0;
3103            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3104                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3105                // Also turn on CheckJNI for debuggable apps. It's quite
3106                // awkward to turn on otherwise.
3107                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3108            }
3109            // Run the app in safe mode if its manifest requests so or the
3110            // system is booted in safe mode.
3111            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3112                mSafeMode == true) {
3113                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3114            }
3115            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3116                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3117            }
3118            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3119                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3120            }
3121            if ("1".equals(SystemProperties.get("debug.assert"))) {
3122                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3123            }
3124
3125            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3126            if (requiredAbi == null) {
3127                requiredAbi = Build.SUPPORTED_ABIS[0];
3128            }
3129
3130            String instructionSet = null;
3131            if (app.info.primaryCpuAbi != null) {
3132                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3133            }
3134
3135            // Start the process.  It will either succeed and return a result containing
3136            // the PID of the new process, or else throw a RuntimeException.
3137            boolean isActivityProcess = (entryPoint == null);
3138            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3139            checkTime(startTime, "startProcess: asking zygote to start proc");
3140            Process.ProcessStartResult startResult = Process.start(entryPoint,
3141                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3142                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3143                    entryPointArgs);
3144            checkTime(startTime, "startProcess: returned from zygote!");
3145
3146            if (app.isolated) {
3147                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3148            }
3149            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3150            checkTime(startTime, "startProcess: done updating battery stats");
3151
3152            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3153                    UserHandle.getUserId(uid), startResult.pid, uid,
3154                    app.processName, hostingType,
3155                    hostingNameStr != null ? hostingNameStr : "");
3156
3157            if (app.persistent) {
3158                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3159            }
3160
3161            checkTime(startTime, "startProcess: building log message");
3162            StringBuilder buf = mStringBuilder;
3163            buf.setLength(0);
3164            buf.append("Start proc ");
3165            buf.append(app.processName);
3166            if (!isActivityProcess) {
3167                buf.append(" [");
3168                buf.append(entryPoint);
3169                buf.append("]");
3170            }
3171            buf.append(" for ");
3172            buf.append(hostingType);
3173            if (hostingNameStr != null) {
3174                buf.append(" ");
3175                buf.append(hostingNameStr);
3176            }
3177            buf.append(": pid=");
3178            buf.append(startResult.pid);
3179            buf.append(" uid=");
3180            buf.append(uid);
3181            buf.append(" gids={");
3182            if (gids != null) {
3183                for (int gi=0; gi<gids.length; gi++) {
3184                    if (gi != 0) buf.append(", ");
3185                    buf.append(gids[gi]);
3186
3187                }
3188            }
3189            buf.append("}");
3190            if (requiredAbi != null) {
3191                buf.append(" abi=");
3192                buf.append(requiredAbi);
3193            }
3194            Slog.i(TAG, buf.toString());
3195            app.setPid(startResult.pid);
3196            app.usingWrapper = startResult.usingWrapper;
3197            app.removed = false;
3198            app.killedByAm = false;
3199            checkTime(startTime, "startProcess: starting to update pids map");
3200            synchronized (mPidsSelfLocked) {
3201                this.mPidsSelfLocked.put(startResult.pid, app);
3202                if (isActivityProcess) {
3203                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3204                    msg.obj = app;
3205                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3206                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3207                }
3208            }
3209            checkTime(startTime, "startProcess: done updating pids map");
3210        } catch (RuntimeException e) {
3211            // XXX do better error recovery.
3212            app.setPid(0);
3213            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3214            if (app.isolated) {
3215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3216            }
3217            Slog.e(TAG, "Failure starting process " + app.processName, e);
3218        }
3219    }
3220
3221    void updateUsageStats(ActivityRecord component, boolean resumed) {
3222        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3223        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3224        if (resumed) {
3225            if (mUsageStatsService != null) {
3226                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3227                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3228            }
3229            synchronized (stats) {
3230                stats.noteActivityResumedLocked(component.app.uid);
3231            }
3232        } else {
3233            if (mUsageStatsService != null) {
3234                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3235                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3236            }
3237            synchronized (stats) {
3238                stats.noteActivityPausedLocked(component.app.uid);
3239            }
3240        }
3241    }
3242
3243    Intent getHomeIntent() {
3244        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3245        intent.setComponent(mTopComponent);
3246        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3247            intent.addCategory(Intent.CATEGORY_HOME);
3248        }
3249        return intent;
3250    }
3251
3252    boolean startHomeActivityLocked(int userId) {
3253        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3254                && mTopAction == null) {
3255            // We are running in factory test mode, but unable to find
3256            // the factory test app, so just sit around displaying the
3257            // error message and don't try to start anything.
3258            return false;
3259        }
3260        Intent intent = getHomeIntent();
3261        ActivityInfo aInfo =
3262            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3263        if (aInfo != null) {
3264            intent.setComponent(new ComponentName(
3265                    aInfo.applicationInfo.packageName, aInfo.name));
3266            // Don't do this if the home app is currently being
3267            // instrumented.
3268            aInfo = new ActivityInfo(aInfo);
3269            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3270            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3271                    aInfo.applicationInfo.uid, true);
3272            if (app == null || app.instrumentationClass == null) {
3273                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3274                mStackSupervisor.startHomeActivity(intent, aInfo);
3275            }
3276        }
3277
3278        return true;
3279    }
3280
3281    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3282        ActivityInfo ai = null;
3283        ComponentName comp = intent.getComponent();
3284        try {
3285            if (comp != null) {
3286                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3287            } else {
3288                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3289                        intent,
3290                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3291                            flags, userId);
3292
3293                if (info != null) {
3294                    ai = info.activityInfo;
3295                }
3296            }
3297        } catch (RemoteException e) {
3298            // ignore
3299        }
3300
3301        return ai;
3302    }
3303
3304    /**
3305     * Starts the "new version setup screen" if appropriate.
3306     */
3307    void startSetupActivityLocked() {
3308        // Only do this once per boot.
3309        if (mCheckedForSetup) {
3310            return;
3311        }
3312
3313        // We will show this screen if the current one is a different
3314        // version than the last one shown, and we are not running in
3315        // low-level factory test mode.
3316        final ContentResolver resolver = mContext.getContentResolver();
3317        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3318                Settings.Global.getInt(resolver,
3319                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3320            mCheckedForSetup = true;
3321
3322            // See if we should be showing the platform update setup UI.
3323            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3324            List<ResolveInfo> ris = mContext.getPackageManager()
3325                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3326
3327            // We don't allow third party apps to replace this.
3328            ResolveInfo ri = null;
3329            for (int i=0; ris != null && i<ris.size(); i++) {
3330                if ((ris.get(i).activityInfo.applicationInfo.flags
3331                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3332                    ri = ris.get(i);
3333                    break;
3334                }
3335            }
3336
3337            if (ri != null) {
3338                String vers = ri.activityInfo.metaData != null
3339                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3340                        : null;
3341                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3342                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3343                            Intent.METADATA_SETUP_VERSION);
3344                }
3345                String lastVers = Settings.Secure.getString(
3346                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3347                if (vers != null && !vers.equals(lastVers)) {
3348                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3349                    intent.setComponent(new ComponentName(
3350                            ri.activityInfo.packageName, ri.activityInfo.name));
3351                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3352                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3353                            null);
3354                }
3355            }
3356        }
3357    }
3358
3359    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3360        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3361    }
3362
3363    void enforceNotIsolatedCaller(String caller) {
3364        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3365            throw new SecurityException("Isolated process not allowed to call " + caller);
3366        }
3367    }
3368
3369    @Override
3370    public int getFrontActivityScreenCompatMode() {
3371        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3372        synchronized (this) {
3373            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3374        }
3375    }
3376
3377    @Override
3378    public void setFrontActivityScreenCompatMode(int mode) {
3379        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3380                "setFrontActivityScreenCompatMode");
3381        synchronized (this) {
3382            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3383        }
3384    }
3385
3386    @Override
3387    public int getPackageScreenCompatMode(String packageName) {
3388        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3389        synchronized (this) {
3390            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3391        }
3392    }
3393
3394    @Override
3395    public void setPackageScreenCompatMode(String packageName, int mode) {
3396        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3397                "setPackageScreenCompatMode");
3398        synchronized (this) {
3399            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3400        }
3401    }
3402
3403    @Override
3404    public boolean getPackageAskScreenCompat(String packageName) {
3405        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3406        synchronized (this) {
3407            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3408        }
3409    }
3410
3411    @Override
3412    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3413        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3414                "setPackageAskScreenCompat");
3415        synchronized (this) {
3416            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3417        }
3418    }
3419
3420    private void dispatchProcessesChanged() {
3421        int N;
3422        synchronized (this) {
3423            N = mPendingProcessChanges.size();
3424            if (mActiveProcessChanges.length < N) {
3425                mActiveProcessChanges = new ProcessChangeItem[N];
3426            }
3427            mPendingProcessChanges.toArray(mActiveProcessChanges);
3428            mAvailProcessChanges.addAll(mPendingProcessChanges);
3429            mPendingProcessChanges.clear();
3430            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3431        }
3432
3433        int i = mProcessObservers.beginBroadcast();
3434        while (i > 0) {
3435            i--;
3436            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3437            if (observer != null) {
3438                try {
3439                    for (int j=0; j<N; j++) {
3440                        ProcessChangeItem item = mActiveProcessChanges[j];
3441                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3442                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3443                                    + item.pid + " uid=" + item.uid + ": "
3444                                    + item.foregroundActivities);
3445                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3446                                    item.foregroundActivities);
3447                        }
3448                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3449                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3450                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3451                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3452                        }
3453                    }
3454                } catch (RemoteException e) {
3455                }
3456            }
3457        }
3458        mProcessObservers.finishBroadcast();
3459    }
3460
3461    private void dispatchProcessDied(int pid, int uid) {
3462        int i = mProcessObservers.beginBroadcast();
3463        while (i > 0) {
3464            i--;
3465            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3466            if (observer != null) {
3467                try {
3468                    observer.onProcessDied(pid, uid);
3469                } catch (RemoteException e) {
3470                }
3471            }
3472        }
3473        mProcessObservers.finishBroadcast();
3474    }
3475
3476    @Override
3477    public final int startActivity(IApplicationThread caller, String callingPackage,
3478            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3479            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3480        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3481            resultWho, requestCode, startFlags, profilerInfo, options,
3482            UserHandle.getCallingUserId());
3483    }
3484
3485    @Override
3486    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3487            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3488            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3489        enforceNotIsolatedCaller("startActivity");
3490        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3491                false, ALLOW_FULL_ONLY, "startActivity", null);
3492        // TODO: Switch to user app stacks here.
3493        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3494                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3495                profilerInfo, null, null, options, userId, null, null);
3496    }
3497
3498    @Override
3499    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3500            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3501            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3502
3503        // This is very dangerous -- it allows you to perform a start activity (including
3504        // permission grants) as any app that may launch one of your own activities.  So
3505        // we will only allow this to be done from activities that are part of the core framework,
3506        // and then only when they are running as the system.
3507        final ActivityRecord sourceRecord;
3508        final int targetUid;
3509        final String targetPackage;
3510        synchronized (this) {
3511            if (resultTo == null) {
3512                throw new SecurityException("Must be called from an activity");
3513            }
3514            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3515            if (sourceRecord == null) {
3516                throw new SecurityException("Called with bad activity token: " + resultTo);
3517            }
3518            if (!sourceRecord.info.packageName.equals("android")) {
3519                throw new SecurityException(
3520                        "Must be called from an activity that is declared in the android package");
3521            }
3522            if (sourceRecord.app == null) {
3523                throw new SecurityException("Called without a process attached to activity");
3524            }
3525            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3526                // This is still okay, as long as this activity is running under the
3527                // uid of the original calling activity.
3528                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3529                    throw new SecurityException(
3530                            "Calling activity in uid " + sourceRecord.app.uid
3531                                    + " must be system uid or original calling uid "
3532                                    + sourceRecord.launchedFromUid);
3533                }
3534            }
3535            targetUid = sourceRecord.launchedFromUid;
3536            targetPackage = sourceRecord.launchedFromPackage;
3537        }
3538
3539        // TODO: Switch to user app stacks here.
3540        try {
3541            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3542                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3543                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3544            return ret;
3545        } catch (SecurityException e) {
3546            // XXX need to figure out how to propagate to original app.
3547            // A SecurityException here is generally actually a fault of the original
3548            // calling activity (such as a fairly granting permissions), so propagate it
3549            // back to them.
3550            /*
3551            StringBuilder msg = new StringBuilder();
3552            msg.append("While launching");
3553            msg.append(intent.toString());
3554            msg.append(": ");
3555            msg.append(e.getMessage());
3556            */
3557            throw e;
3558        }
3559    }
3560
3561    @Override
3562    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3563            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3564            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3565        enforceNotIsolatedCaller("startActivityAndWait");
3566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3567                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3568        WaitResult res = new WaitResult();
3569        // TODO: Switch to user app stacks here.
3570        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3571                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3572                options, userId, null, null);
3573        return res;
3574    }
3575
3576    @Override
3577    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3578            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3579            int startFlags, Configuration config, Bundle options, int userId) {
3580        enforceNotIsolatedCaller("startActivityWithConfig");
3581        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3582                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3583        // TODO: Switch to user app stacks here.
3584        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3585                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3586                null, null, config, options, userId, null, null);
3587        return ret;
3588    }
3589
3590    @Override
3591    public int startActivityIntentSender(IApplicationThread caller,
3592            IntentSender intent, Intent fillInIntent, String resolvedType,
3593            IBinder resultTo, String resultWho, int requestCode,
3594            int flagsMask, int flagsValues, Bundle options) {
3595        enforceNotIsolatedCaller("startActivityIntentSender");
3596        // Refuse possible leaked file descriptors
3597        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3598            throw new IllegalArgumentException("File descriptors passed in Intent");
3599        }
3600
3601        IIntentSender sender = intent.getTarget();
3602        if (!(sender instanceof PendingIntentRecord)) {
3603            throw new IllegalArgumentException("Bad PendingIntent object");
3604        }
3605
3606        PendingIntentRecord pir = (PendingIntentRecord)sender;
3607
3608        synchronized (this) {
3609            // If this is coming from the currently resumed activity, it is
3610            // effectively saying that app switches are allowed at this point.
3611            final ActivityStack stack = getFocusedStack();
3612            if (stack.mResumedActivity != null &&
3613                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3614                mAppSwitchesAllowedTime = 0;
3615            }
3616        }
3617        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3618                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3619        return ret;
3620    }
3621
3622    @Override
3623    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3624            Intent intent, String resolvedType, IVoiceInteractionSession session,
3625            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3626            Bundle options, int userId) {
3627        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3628                != PackageManager.PERMISSION_GRANTED) {
3629            String msg = "Permission Denial: startVoiceActivity() from pid="
3630                    + Binder.getCallingPid()
3631                    + ", uid=" + Binder.getCallingUid()
3632                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3633            Slog.w(TAG, msg);
3634            throw new SecurityException(msg);
3635        }
3636        if (session == null || interactor == null) {
3637            throw new NullPointerException("null session or interactor");
3638        }
3639        userId = handleIncomingUser(callingPid, callingUid, userId,
3640                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3641        // TODO: Switch to user app stacks here.
3642        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3643                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3644                null, options, userId, null, null);
3645    }
3646
3647    @Override
3648    public boolean startNextMatchingActivity(IBinder callingActivity,
3649            Intent intent, Bundle options) {
3650        // Refuse possible leaked file descriptors
3651        if (intent != null && intent.hasFileDescriptors() == true) {
3652            throw new IllegalArgumentException("File descriptors passed in Intent");
3653        }
3654
3655        synchronized (this) {
3656            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3657            if (r == null) {
3658                ActivityOptions.abort(options);
3659                return false;
3660            }
3661            if (r.app == null || r.app.thread == null) {
3662                // The caller is not running...  d'oh!
3663                ActivityOptions.abort(options);
3664                return false;
3665            }
3666            intent = new Intent(intent);
3667            // The caller is not allowed to change the data.
3668            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3669            // And we are resetting to find the next component...
3670            intent.setComponent(null);
3671
3672            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3673
3674            ActivityInfo aInfo = null;
3675            try {
3676                List<ResolveInfo> resolves =
3677                    AppGlobals.getPackageManager().queryIntentActivities(
3678                            intent, r.resolvedType,
3679                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3680                            UserHandle.getCallingUserId());
3681
3682                // Look for the original activity in the list...
3683                final int N = resolves != null ? resolves.size() : 0;
3684                for (int i=0; i<N; i++) {
3685                    ResolveInfo rInfo = resolves.get(i);
3686                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3687                            && rInfo.activityInfo.name.equals(r.info.name)) {
3688                        // We found the current one...  the next matching is
3689                        // after it.
3690                        i++;
3691                        if (i<N) {
3692                            aInfo = resolves.get(i).activityInfo;
3693                        }
3694                        if (debug) {
3695                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3696                                    + "/" + r.info.name);
3697                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3698                                    + "/" + aInfo.name);
3699                        }
3700                        break;
3701                    }
3702                }
3703            } catch (RemoteException e) {
3704            }
3705
3706            if (aInfo == null) {
3707                // Nobody who is next!
3708                ActivityOptions.abort(options);
3709                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3710                return false;
3711            }
3712
3713            intent.setComponent(new ComponentName(
3714                    aInfo.applicationInfo.packageName, aInfo.name));
3715            intent.setFlags(intent.getFlags()&~(
3716                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3717                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3718                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3719                    Intent.FLAG_ACTIVITY_NEW_TASK));
3720
3721            // Okay now we need to start the new activity, replacing the
3722            // currently running activity.  This is a little tricky because
3723            // we want to start the new one as if the current one is finished,
3724            // but not finish the current one first so that there is no flicker.
3725            // And thus...
3726            final boolean wasFinishing = r.finishing;
3727            r.finishing = true;
3728
3729            // Propagate reply information over to the new activity.
3730            final ActivityRecord resultTo = r.resultTo;
3731            final String resultWho = r.resultWho;
3732            final int requestCode = r.requestCode;
3733            r.resultTo = null;
3734            if (resultTo != null) {
3735                resultTo.removeResultsLocked(r, resultWho, requestCode);
3736            }
3737
3738            final long origId = Binder.clearCallingIdentity();
3739            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3740                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3741                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3742                    options, false, null, null, null);
3743            Binder.restoreCallingIdentity(origId);
3744
3745            r.finishing = wasFinishing;
3746            if (res != ActivityManager.START_SUCCESS) {
3747                return false;
3748            }
3749            return true;
3750        }
3751    }
3752
3753    @Override
3754    public final int startActivityFromRecents(int taskId, Bundle options) {
3755        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3756            String msg = "Permission Denial: startActivityFromRecents called without " +
3757                    START_TASKS_FROM_RECENTS;
3758            Slog.w(TAG, msg);
3759            throw new SecurityException(msg);
3760        }
3761        return startActivityFromRecentsInner(taskId, options);
3762    }
3763
3764    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3765        final TaskRecord task;
3766        final int callingUid;
3767        final String callingPackage;
3768        final Intent intent;
3769        final int userId;
3770        synchronized (this) {
3771            task = recentTaskForIdLocked(taskId);
3772            if (task == null) {
3773                throw new IllegalArgumentException("Task " + taskId + " not found.");
3774            }
3775            callingUid = task.mCallingUid;
3776            callingPackage = task.mCallingPackage;
3777            intent = task.intent;
3778            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3779            userId = task.userId;
3780        }
3781        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3782                options, userId, null, task);
3783    }
3784
3785    final int startActivityInPackage(int uid, String callingPackage,
3786            Intent intent, String resolvedType, IBinder resultTo,
3787            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3788            IActivityContainer container, TaskRecord inTask) {
3789
3790        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3791                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3792
3793        // TODO: Switch to user app stacks here.
3794        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3795                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3796                null, null, null, options, userId, container, inTask);
3797        return ret;
3798    }
3799
3800    @Override
3801    public final int startActivities(IApplicationThread caller, String callingPackage,
3802            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3803            int userId) {
3804        enforceNotIsolatedCaller("startActivities");
3805        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3806                false, ALLOW_FULL_ONLY, "startActivity", null);
3807        // TODO: Switch to user app stacks here.
3808        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3809                resolvedTypes, resultTo, options, userId);
3810        return ret;
3811    }
3812
3813    final int startActivitiesInPackage(int uid, String callingPackage,
3814            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3815            Bundle options, int userId) {
3816
3817        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3818                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3819        // TODO: Switch to user app stacks here.
3820        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3821                resultTo, options, userId);
3822        return ret;
3823    }
3824
3825    //explicitly remove thd old information in mRecentTasks when removing existing user.
3826    private void removeRecentTasksForUserLocked(int userId) {
3827        if(userId <= 0) {
3828            Slog.i(TAG, "Can't remove recent task on user " + userId);
3829            return;
3830        }
3831
3832        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3833            TaskRecord tr = mRecentTasks.get(i);
3834            if (tr.userId == userId) {
3835                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3836                        + " when finishing user" + userId);
3837                mRecentTasks.remove(i);
3838                tr.removedFromRecents(mTaskPersister);
3839            }
3840        }
3841
3842        // Remove tasks from persistent storage.
3843        mTaskPersister.wakeup(null, true);
3844    }
3845
3846    /**
3847     * Update the recent tasks lists: make sure tasks should still be here (their
3848     * applications / activities still exist), update their availability, fixup ordering
3849     * of affiliations.
3850     */
3851    void cleanupRecentTasksLocked(int userId) {
3852        if (mRecentTasks == null) {
3853            // Happens when called from the packagemanager broadcast before boot.
3854            return;
3855        }
3856
3857        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3858        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3859        final IPackageManager pm = AppGlobals.getPackageManager();
3860        final ActivityInfo dummyAct = new ActivityInfo();
3861        final ApplicationInfo dummyApp = new ApplicationInfo();
3862
3863        int N = mRecentTasks.size();
3864
3865        int[] users = userId == UserHandle.USER_ALL
3866                ? getUsersLocked() : new int[] { userId };
3867        for (int user : users) {
3868            for (int i = 0; i < N; i++) {
3869                TaskRecord task = mRecentTasks.get(i);
3870                if (task.userId != user) {
3871                    // Only look at tasks for the user ID of interest.
3872                    continue;
3873                }
3874                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3875                    // This situation is broken, and we should just get rid of it now.
3876                    mRecentTasks.remove(i);
3877                    task.removedFromRecents(mTaskPersister);
3878                    i--;
3879                    N--;
3880                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3881                    continue;
3882                }
3883                // Check whether this activity is currently available.
3884                if (task.realActivity != null) {
3885                    ActivityInfo ai = availActCache.get(task.realActivity);
3886                    if (ai == null) {
3887                        try {
3888                            ai = pm.getActivityInfo(task.realActivity,
3889                                    PackageManager.GET_UNINSTALLED_PACKAGES
3890                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3891                        } catch (RemoteException e) {
3892                            // Will never happen.
3893                            continue;
3894                        }
3895                        if (ai == null) {
3896                            ai = dummyAct;
3897                        }
3898                        availActCache.put(task.realActivity, ai);
3899                    }
3900                    if (ai == dummyAct) {
3901                        // This could be either because the activity no longer exists, or the
3902                        // app is temporarily gone.  For the former we want to remove the recents
3903                        // entry; for the latter we want to mark it as unavailable.
3904                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3905                        if (app == null) {
3906                            try {
3907                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3908                                        PackageManager.GET_UNINSTALLED_PACKAGES
3909                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3910                            } catch (RemoteException e) {
3911                                // Will never happen.
3912                                continue;
3913                            }
3914                            if (app == null) {
3915                                app = dummyApp;
3916                            }
3917                            availAppCache.put(task.realActivity.getPackageName(), app);
3918                        }
3919                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3920                            // Doesn't exist any more!  Good-bye.
3921                            mRecentTasks.remove(i);
3922                            task.removedFromRecents(mTaskPersister);
3923                            i--;
3924                            N--;
3925                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3926                            continue;
3927                        } else {
3928                            // Otherwise just not available for now.
3929                            if (task.isAvailable) {
3930                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3931                                        + task);
3932                            }
3933                            task.isAvailable = false;
3934                        }
3935                    } else {
3936                        if (!ai.enabled || !ai.applicationInfo.enabled
3937                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3938                            if (task.isAvailable) {
3939                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3940                                        + task + " (enabled=" + ai.enabled + "/"
3941                                        + ai.applicationInfo.enabled +  " flags="
3942                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3943                            }
3944                            task.isAvailable = false;
3945                        } else {
3946                            if (!task.isAvailable) {
3947                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3948                                        + task);
3949                            }
3950                            task.isAvailable = true;
3951                        }
3952                    }
3953                }
3954            }
3955        }
3956
3957        // Verify the affiliate chain for each task.
3958        for (int i = 0; i < N; ) {
3959            TaskRecord task = mRecentTasks.remove(i);
3960            if (mTmpRecents.contains(task)) {
3961                continue;
3962            }
3963            int affiliatedTaskId = task.mAffiliatedTaskId;
3964            while (true) {
3965                TaskRecord next = task.mNextAffiliate;
3966                if (next == null) {
3967                    break;
3968                }
3969                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3970                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3971                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3972                    task.setNextAffiliate(null);
3973                    if (next.mPrevAffiliate == task) {
3974                        next.setPrevAffiliate(null);
3975                    }
3976                    break;
3977                }
3978                if (next.mPrevAffiliate != task) {
3979                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3980                            next.mPrevAffiliate + " task=" + task);
3981                    next.setPrevAffiliate(null);
3982                    task.setNextAffiliate(null);
3983                    break;
3984                }
3985                if (!mRecentTasks.contains(next)) {
3986                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3987                    task.setNextAffiliate(null);
3988                    // We know that next.mPrevAffiliate is always task, from above, so clear
3989                    // its previous affiliate.
3990                    next.setPrevAffiliate(null);
3991                    break;
3992                }
3993                task = next;
3994            }
3995            // task is now the end of the list
3996            do {
3997                mRecentTasks.remove(task);
3998                mRecentTasks.add(i++, task);
3999                mTmpRecents.add(task);
4000                task.inRecents = true;
4001            } while ((task = task.mPrevAffiliate) != null);
4002        }
4003        mTmpRecents.clear();
4004        // mRecentTasks is now in sorted, affiliated order.
4005    }
4006
4007    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4008        int N = mRecentTasks.size();
4009        TaskRecord top = task;
4010        int topIndex = taskIndex;
4011        while (top.mNextAffiliate != null && topIndex > 0) {
4012            top = top.mNextAffiliate;
4013            topIndex--;
4014        }
4015        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4016                + topIndex + " from intial " + taskIndex);
4017        // Find the end of the chain, doing a sanity check along the way.
4018        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4019        int endIndex = topIndex;
4020        TaskRecord prev = top;
4021        while (endIndex < N) {
4022            TaskRecord cur = mRecentTasks.get(endIndex);
4023            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4024                    + endIndex + " " + cur);
4025            if (cur == top) {
4026                // Verify start of the chain.
4027                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4028                    Slog.wtf(TAG, "Bad chain @" + endIndex
4029                            + ": first task has next affiliate: " + prev);
4030                    sane = false;
4031                    break;
4032                }
4033            } else {
4034                // Verify middle of the chain's next points back to the one before.
4035                if (cur.mNextAffiliate != prev
4036                        || cur.mNextAffiliateTaskId != prev.taskId) {
4037                    Slog.wtf(TAG, "Bad chain @" + endIndex
4038                            + ": middle task " + cur + " @" + endIndex
4039                            + " has bad next affiliate "
4040                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4041                            + ", expected " + prev);
4042                    sane = false;
4043                    break;
4044                }
4045            }
4046            if (cur.mPrevAffiliateTaskId == -1) {
4047                // Chain ends here.
4048                if (cur.mPrevAffiliate != null) {
4049                    Slog.wtf(TAG, "Bad chain @" + endIndex
4050                            + ": last task " + cur + " has previous affiliate "
4051                            + cur.mPrevAffiliate);
4052                    sane = false;
4053                }
4054                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4055                break;
4056            } else {
4057                // Verify middle of the chain's prev points to a valid item.
4058                if (cur.mPrevAffiliate == null) {
4059                    Slog.wtf(TAG, "Bad chain @" + endIndex
4060                            + ": task " + cur + " has previous affiliate "
4061                            + cur.mPrevAffiliate + " but should be id "
4062                            + cur.mPrevAffiliate);
4063                    sane = false;
4064                    break;
4065                }
4066            }
4067            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4068                Slog.wtf(TAG, "Bad chain @" + endIndex
4069                        + ": task " + cur + " has affiliated id "
4070                        + cur.mAffiliatedTaskId + " but should be "
4071                        + task.mAffiliatedTaskId);
4072                sane = false;
4073                break;
4074            }
4075            prev = cur;
4076            endIndex++;
4077            if (endIndex >= N) {
4078                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4079                        + ": last task " + prev);
4080                sane = false;
4081                break;
4082            }
4083        }
4084        if (sane) {
4085            if (endIndex < taskIndex) {
4086                Slog.wtf(TAG, "Bad chain @" + endIndex
4087                        + ": did not extend to task " + task + " @" + taskIndex);
4088                sane = false;
4089            }
4090        }
4091        if (sane) {
4092            // All looks good, we can just move all of the affiliated tasks
4093            // to the top.
4094            for (int i=topIndex; i<=endIndex; i++) {
4095                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4096                        + " from " + i + " to " + (i-topIndex));
4097                TaskRecord cur = mRecentTasks.remove(i);
4098                mRecentTasks.add(i-topIndex, cur);
4099            }
4100            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4101                    + " to " + endIndex);
4102            return true;
4103        }
4104
4105        // Whoops, couldn't do it.
4106        return false;
4107    }
4108
4109    final void addRecentTaskLocked(TaskRecord task) {
4110        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4111                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4112
4113        int N = mRecentTasks.size();
4114        // Quick case: check if the top-most recent task is the same.
4115        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4116            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4117            return;
4118        }
4119        // Another quick case: check if this is part of a set of affiliated
4120        // tasks that are at the top.
4121        if (isAffiliated && N > 0 && task.inRecents
4122                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4123            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4124                    + " at top when adding " + task);
4125            return;
4126        }
4127        // Another quick case: never add voice sessions.
4128        if (task.voiceSession != null) {
4129            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4130            return;
4131        }
4132
4133        boolean needAffiliationFix = false;
4134
4135        // Slightly less quick case: the task is already in recents, so all we need
4136        // to do is move it.
4137        if (task.inRecents) {
4138            int taskIndex = mRecentTasks.indexOf(task);
4139            if (taskIndex >= 0) {
4140                if (!isAffiliated) {
4141                    // Simple case: this is not an affiliated task, so we just move it to the front.
4142                    mRecentTasks.remove(taskIndex);
4143                    mRecentTasks.add(0, task);
4144                    notifyTaskPersisterLocked(task, false);
4145                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4146                            + " from " + taskIndex);
4147                    return;
4148                } else {
4149                    // More complicated: need to keep all affiliated tasks together.
4150                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4151                        // All went well.
4152                        return;
4153                    }
4154
4155                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4156                    // everything and then go through our general path of adding a new task.
4157                    needAffiliationFix = true;
4158                }
4159            } else {
4160                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4161                needAffiliationFix = true;
4162            }
4163        }
4164
4165        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4166        trimRecentsForTask(task, true);
4167
4168        N = mRecentTasks.size();
4169        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4170            final TaskRecord tr = mRecentTasks.remove(N - 1);
4171            tr.removedFromRecents(mTaskPersister);
4172            N--;
4173        }
4174        task.inRecents = true;
4175        if (!isAffiliated || needAffiliationFix) {
4176            // If this is a simple non-affiliated task, or we had some failure trying to
4177            // handle it as part of an affilated task, then just place it at the top.
4178            mRecentTasks.add(0, task);
4179        } else if (isAffiliated) {
4180            // If this is a new affiliated task, then move all of the affiliated tasks
4181            // to the front and insert this new one.
4182            TaskRecord other = task.mNextAffiliate;
4183            if (other == null) {
4184                other = task.mPrevAffiliate;
4185            }
4186            if (other != null) {
4187                int otherIndex = mRecentTasks.indexOf(other);
4188                if (otherIndex >= 0) {
4189                    // Insert new task at appropriate location.
4190                    int taskIndex;
4191                    if (other == task.mNextAffiliate) {
4192                        // We found the index of our next affiliation, which is who is
4193                        // before us in the list, so add after that point.
4194                        taskIndex = otherIndex+1;
4195                    } else {
4196                        // We found the index of our previous affiliation, which is who is
4197                        // after us in the list, so add at their position.
4198                        taskIndex = otherIndex;
4199                    }
4200                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4201                            + taskIndex + ": " + task);
4202                    mRecentTasks.add(taskIndex, task);
4203
4204                    // Now move everything to the front.
4205                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4206                        // All went well.
4207                        return;
4208                    }
4209
4210                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4211                    // everything and then go through our general path of adding a new task.
4212                    needAffiliationFix = true;
4213                } else {
4214                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4215                            + other);
4216                    needAffiliationFix = true;
4217                }
4218            } else {
4219                if (DEBUG_RECENTS) Slog.d(TAG,
4220                        "addRecent: adding affiliated task without next/prev:" + task);
4221                needAffiliationFix = true;
4222            }
4223        }
4224        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4225
4226        if (needAffiliationFix) {
4227            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4228            cleanupRecentTasksLocked(task.userId);
4229        }
4230    }
4231
4232    /**
4233     * If needed, remove oldest existing entries in recents that are for the same kind
4234     * of task as the given one.
4235     */
4236    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4237        int N = mRecentTasks.size();
4238        final Intent intent = task.intent;
4239        final boolean document = intent != null && intent.isDocument();
4240
4241        int maxRecents = task.maxRecents - 1;
4242        for (int i=0; i<N; i++) {
4243            final TaskRecord tr = mRecentTasks.get(i);
4244            if (task != tr) {
4245                if (task.userId != tr.userId) {
4246                    continue;
4247                }
4248                if (i > MAX_RECENT_BITMAPS) {
4249                    tr.freeLastThumbnail();
4250                }
4251                final Intent trIntent = tr.intent;
4252                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4253                    (intent == null || !intent.filterEquals(trIntent))) {
4254                    continue;
4255                }
4256                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4257                if (document && trIsDocument) {
4258                    // These are the same document activity (not necessarily the same doc).
4259                    if (maxRecents > 0) {
4260                        --maxRecents;
4261                        continue;
4262                    }
4263                    // Hit the maximum number of documents for this task. Fall through
4264                    // and remove this document from recents.
4265                } else if (document || trIsDocument) {
4266                    // Only one of these is a document. Not the droid we're looking for.
4267                    continue;
4268                }
4269            }
4270
4271            if (!doTrim) {
4272                // If the caller is not actually asking for a trim, just tell them we reached
4273                // a point where the trim would happen.
4274                return i;
4275            }
4276
4277            // Either task and tr are the same or, their affinities match or their intents match
4278            // and neither of them is a document, or they are documents using the same activity
4279            // and their maxRecents has been reached.
4280            tr.disposeThumbnail();
4281            mRecentTasks.remove(i);
4282            if (task != tr) {
4283                tr.removedFromRecents(mTaskPersister);
4284            }
4285            i--;
4286            N--;
4287            if (task.intent == null) {
4288                // If the new recent task we are adding is not fully
4289                // specified, then replace it with the existing recent task.
4290                task = tr;
4291            }
4292            notifyTaskPersisterLocked(tr, false);
4293        }
4294
4295        return -1;
4296    }
4297
4298    @Override
4299    public void reportActivityFullyDrawn(IBinder token) {
4300        synchronized (this) {
4301            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4302            if (r == null) {
4303                return;
4304            }
4305            r.reportFullyDrawnLocked();
4306        }
4307    }
4308
4309    @Override
4310    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4311        synchronized (this) {
4312            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4313            if (r == null) {
4314                return;
4315            }
4316            final long origId = Binder.clearCallingIdentity();
4317            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4318            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4319                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4320            if (config != null) {
4321                r.frozenBeforeDestroy = true;
4322                if (!updateConfigurationLocked(config, r, false, false)) {
4323                    mStackSupervisor.resumeTopActivitiesLocked();
4324                }
4325            }
4326            Binder.restoreCallingIdentity(origId);
4327        }
4328    }
4329
4330    @Override
4331    public int getRequestedOrientation(IBinder token) {
4332        synchronized (this) {
4333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4334            if (r == null) {
4335                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4336            }
4337            return mWindowManager.getAppOrientation(r.appToken);
4338        }
4339    }
4340
4341    /**
4342     * This is the internal entry point for handling Activity.finish().
4343     *
4344     * @param token The Binder token referencing the Activity we want to finish.
4345     * @param resultCode Result code, if any, from this Activity.
4346     * @param resultData Result data (Intent), if any, from this Activity.
4347     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4348     *            the root Activity in the task.
4349     *
4350     * @return Returns true if the activity successfully finished, or false if it is still running.
4351     */
4352    @Override
4353    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4354            boolean finishTask) {
4355        // Refuse possible leaked file descriptors
4356        if (resultData != null && resultData.hasFileDescriptors() == true) {
4357            throw new IllegalArgumentException("File descriptors passed in Intent");
4358        }
4359
4360        synchronized(this) {
4361            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4362            if (r == null) {
4363                return true;
4364            }
4365            // Keep track of the root activity of the task before we finish it
4366            TaskRecord tr = r.task;
4367            ActivityRecord rootR = tr.getRootActivity();
4368            // Do not allow task to finish in Lock Task mode.
4369            if (tr == mStackSupervisor.mLockTaskModeTask) {
4370                if (rootR == r) {
4371                    mStackSupervisor.showLockTaskToast();
4372                    return false;
4373                }
4374            }
4375            if (mController != null) {
4376                // Find the first activity that is not finishing.
4377                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4378                if (next != null) {
4379                    // ask watcher if this is allowed
4380                    boolean resumeOK = true;
4381                    try {
4382                        resumeOK = mController.activityResuming(next.packageName);
4383                    } catch (RemoteException e) {
4384                        mController = null;
4385                        Watchdog.getInstance().setActivityController(null);
4386                    }
4387
4388                    if (!resumeOK) {
4389                        return false;
4390                    }
4391                }
4392            }
4393            final long origId = Binder.clearCallingIdentity();
4394            try {
4395                boolean res;
4396                if (finishTask && r == rootR) {
4397                    // If requested, remove the task that is associated to this activity only if it
4398                    // was the root activity in the task.  The result code and data is ignored because
4399                    // we don't support returning them across task boundaries.
4400                    res = removeTaskByIdLocked(tr.taskId, 0);
4401                } else {
4402                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4403                            resultData, "app-request", true);
4404                }
4405                return res;
4406            } finally {
4407                Binder.restoreCallingIdentity(origId);
4408            }
4409        }
4410    }
4411
4412    @Override
4413    public final void finishHeavyWeightApp() {
4414        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4415                != PackageManager.PERMISSION_GRANTED) {
4416            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4417                    + Binder.getCallingPid()
4418                    + ", uid=" + Binder.getCallingUid()
4419                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4420            Slog.w(TAG, msg);
4421            throw new SecurityException(msg);
4422        }
4423
4424        synchronized(this) {
4425            if (mHeavyWeightProcess == null) {
4426                return;
4427            }
4428
4429            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4430                    mHeavyWeightProcess.activities);
4431            for (int i=0; i<activities.size(); i++) {
4432                ActivityRecord r = activities.get(i);
4433                if (!r.finishing) {
4434                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4435                            null, "finish-heavy", true);
4436                }
4437            }
4438
4439            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4440                    mHeavyWeightProcess.userId, 0));
4441            mHeavyWeightProcess = null;
4442        }
4443    }
4444
4445    @Override
4446    public void crashApplication(int uid, int initialPid, String packageName,
4447            String message) {
4448        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4449                != PackageManager.PERMISSION_GRANTED) {
4450            String msg = "Permission Denial: crashApplication() from pid="
4451                    + Binder.getCallingPid()
4452                    + ", uid=" + Binder.getCallingUid()
4453                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4454            Slog.w(TAG, msg);
4455            throw new SecurityException(msg);
4456        }
4457
4458        synchronized(this) {
4459            ProcessRecord proc = null;
4460
4461            // Figure out which process to kill.  We don't trust that initialPid
4462            // still has any relation to current pids, so must scan through the
4463            // list.
4464            synchronized (mPidsSelfLocked) {
4465                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4466                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4467                    if (p.uid != uid) {
4468                        continue;
4469                    }
4470                    if (p.pid == initialPid) {
4471                        proc = p;
4472                        break;
4473                    }
4474                    if (p.pkgList.containsKey(packageName)) {
4475                        proc = p;
4476                    }
4477                }
4478            }
4479
4480            if (proc == null) {
4481                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4482                        + " initialPid=" + initialPid
4483                        + " packageName=" + packageName);
4484                return;
4485            }
4486
4487            if (proc.thread != null) {
4488                if (proc.pid == Process.myPid()) {
4489                    Log.w(TAG, "crashApplication: trying to crash self!");
4490                    return;
4491                }
4492                long ident = Binder.clearCallingIdentity();
4493                try {
4494                    proc.thread.scheduleCrash(message);
4495                } catch (RemoteException e) {
4496                }
4497                Binder.restoreCallingIdentity(ident);
4498            }
4499        }
4500    }
4501
4502    @Override
4503    public final void finishSubActivity(IBinder token, String resultWho,
4504            int requestCode) {
4505        synchronized(this) {
4506            final long origId = Binder.clearCallingIdentity();
4507            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4508            if (r != null) {
4509                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4510            }
4511            Binder.restoreCallingIdentity(origId);
4512        }
4513    }
4514
4515    @Override
4516    public boolean finishActivityAffinity(IBinder token) {
4517        synchronized(this) {
4518            final long origId = Binder.clearCallingIdentity();
4519            try {
4520                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4521
4522                ActivityRecord rootR = r.task.getRootActivity();
4523                // Do not allow task to finish in Lock Task mode.
4524                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4525                    if (rootR == r) {
4526                        mStackSupervisor.showLockTaskToast();
4527                        return false;
4528                    }
4529                }
4530                boolean res = false;
4531                if (r != null) {
4532                    res = r.task.stack.finishActivityAffinityLocked(r);
4533                }
4534                return res;
4535            } finally {
4536                Binder.restoreCallingIdentity(origId);
4537            }
4538        }
4539    }
4540
4541    @Override
4542    public void finishVoiceTask(IVoiceInteractionSession session) {
4543        synchronized(this) {
4544            final long origId = Binder.clearCallingIdentity();
4545            try {
4546                mStackSupervisor.finishVoiceTask(session);
4547            } finally {
4548                Binder.restoreCallingIdentity(origId);
4549            }
4550        }
4551
4552    }
4553
4554    @Override
4555    public boolean releaseActivityInstance(IBinder token) {
4556        synchronized(this) {
4557            final long origId = Binder.clearCallingIdentity();
4558            try {
4559                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4560                if (r.task == null || r.task.stack == null) {
4561                    return false;
4562                }
4563                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4564            } finally {
4565                Binder.restoreCallingIdentity(origId);
4566            }
4567        }
4568    }
4569
4570    @Override
4571    public void releaseSomeActivities(IApplicationThread appInt) {
4572        synchronized(this) {
4573            final long origId = Binder.clearCallingIdentity();
4574            try {
4575                ProcessRecord app = getRecordForAppLocked(appInt);
4576                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4577            } finally {
4578                Binder.restoreCallingIdentity(origId);
4579            }
4580        }
4581    }
4582
4583    @Override
4584    public boolean willActivityBeVisible(IBinder token) {
4585        synchronized(this) {
4586            ActivityStack stack = ActivityRecord.getStackLocked(token);
4587            if (stack != null) {
4588                return stack.willActivityBeVisibleLocked(token);
4589            }
4590            return false;
4591        }
4592    }
4593
4594    @Override
4595    public void overridePendingTransition(IBinder token, String packageName,
4596            int enterAnim, int exitAnim) {
4597        synchronized(this) {
4598            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4599            if (self == null) {
4600                return;
4601            }
4602
4603            final long origId = Binder.clearCallingIdentity();
4604
4605            if (self.state == ActivityState.RESUMED
4606                    || self.state == ActivityState.PAUSING) {
4607                mWindowManager.overridePendingAppTransition(packageName,
4608                        enterAnim, exitAnim, null);
4609            }
4610
4611            Binder.restoreCallingIdentity(origId);
4612        }
4613    }
4614
4615    /**
4616     * Main function for removing an existing process from the activity manager
4617     * as a result of that process going away.  Clears out all connections
4618     * to the process.
4619     */
4620    private final void handleAppDiedLocked(ProcessRecord app,
4621            boolean restarting, boolean allowRestart) {
4622        int pid = app.pid;
4623        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4624        if (!restarting) {
4625            removeLruProcessLocked(app);
4626            if (pid > 0) {
4627                ProcessList.remove(pid);
4628            }
4629        }
4630
4631        if (mProfileProc == app) {
4632            clearProfilerLocked();
4633        }
4634
4635        // Remove this application's activities from active lists.
4636        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4637
4638        app.activities.clear();
4639
4640        if (app.instrumentationClass != null) {
4641            Slog.w(TAG, "Crash of app " + app.processName
4642                  + " running instrumentation " + app.instrumentationClass);
4643            Bundle info = new Bundle();
4644            info.putString("shortMsg", "Process crashed.");
4645            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4646        }
4647
4648        if (!restarting) {
4649            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4650                // If there was nothing to resume, and we are not already
4651                // restarting this process, but there is a visible activity that
4652                // is hosted by the process...  then make sure all visible
4653                // activities are running, taking care of restarting this
4654                // process.
4655                if (hasVisibleActivities) {
4656                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4657                }
4658            }
4659        }
4660    }
4661
4662    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4663        IBinder threadBinder = thread.asBinder();
4664        // Find the application record.
4665        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4666            ProcessRecord rec = mLruProcesses.get(i);
4667            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4668                return i;
4669            }
4670        }
4671        return -1;
4672    }
4673
4674    final ProcessRecord getRecordForAppLocked(
4675            IApplicationThread thread) {
4676        if (thread == null) {
4677            return null;
4678        }
4679
4680        int appIndex = getLRURecordIndexForAppLocked(thread);
4681        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4682    }
4683
4684    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4685        // If there are no longer any background processes running,
4686        // and the app that died was not running instrumentation,
4687        // then tell everyone we are now low on memory.
4688        boolean haveBg = false;
4689        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4690            ProcessRecord rec = mLruProcesses.get(i);
4691            if (rec.thread != null
4692                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4693                haveBg = true;
4694                break;
4695            }
4696        }
4697
4698        if (!haveBg) {
4699            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4700            if (doReport) {
4701                long now = SystemClock.uptimeMillis();
4702                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4703                    doReport = false;
4704                } else {
4705                    mLastMemUsageReportTime = now;
4706                }
4707            }
4708            final ArrayList<ProcessMemInfo> memInfos
4709                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4710            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4711            long now = SystemClock.uptimeMillis();
4712            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4713                ProcessRecord rec = mLruProcesses.get(i);
4714                if (rec == dyingProc || rec.thread == null) {
4715                    continue;
4716                }
4717                if (doReport) {
4718                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4719                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4720                }
4721                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4722                    // The low memory report is overriding any current
4723                    // state for a GC request.  Make sure to do
4724                    // heavy/important/visible/foreground processes first.
4725                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4726                        rec.lastRequestedGc = 0;
4727                    } else {
4728                        rec.lastRequestedGc = rec.lastLowMemory;
4729                    }
4730                    rec.reportLowMemory = true;
4731                    rec.lastLowMemory = now;
4732                    mProcessesToGc.remove(rec);
4733                    addProcessToGcListLocked(rec);
4734                }
4735            }
4736            if (doReport) {
4737                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4738                mHandler.sendMessage(msg);
4739            }
4740            scheduleAppGcsLocked();
4741        }
4742    }
4743
4744    final void appDiedLocked(ProcessRecord app) {
4745       appDiedLocked(app, app.pid, app.thread);
4746    }
4747
4748    final void appDiedLocked(ProcessRecord app, int pid,
4749            IApplicationThread thread) {
4750
4751        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4752        synchronized (stats) {
4753            stats.noteProcessDiedLocked(app.info.uid, pid);
4754        }
4755
4756        Process.killProcessGroup(app.info.uid, pid);
4757
4758        // Clean up already done if the process has been re-started.
4759        if (app.pid == pid && app.thread != null &&
4760                app.thread.asBinder() == thread.asBinder()) {
4761            boolean doLowMem = app.instrumentationClass == null;
4762            boolean doOomAdj = doLowMem;
4763            if (!app.killedByAm) {
4764                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4765                        + ") has died.");
4766                mAllowLowerMemLevel = true;
4767            } else {
4768                // Note that we always want to do oom adj to update our state with the
4769                // new number of procs.
4770                mAllowLowerMemLevel = false;
4771                doLowMem = false;
4772            }
4773            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4774            if (DEBUG_CLEANUP) Slog.v(
4775                TAG, "Dying app: " + app + ", pid: " + pid
4776                + ", thread: " + thread.asBinder());
4777            handleAppDiedLocked(app, false, true);
4778
4779            if (doOomAdj) {
4780                updateOomAdjLocked();
4781            }
4782            if (doLowMem) {
4783                doLowMemReportIfNeededLocked(app);
4784            }
4785        } else if (app.pid != pid) {
4786            // A new process has already been started.
4787            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4788                    + ") has died and restarted (pid " + app.pid + ").");
4789            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4790        } else if (DEBUG_PROCESSES) {
4791            Slog.d(TAG, "Received spurious death notification for thread "
4792                    + thread.asBinder());
4793        }
4794    }
4795
4796    /**
4797     * If a stack trace dump file is configured, dump process stack traces.
4798     * @param clearTraces causes the dump file to be erased prior to the new
4799     *    traces being written, if true; when false, the new traces will be
4800     *    appended to any existing file content.
4801     * @param firstPids of dalvik VM processes to dump stack traces for first
4802     * @param lastPids of dalvik VM processes to dump stack traces for last
4803     * @param nativeProcs optional list of native process names to dump stack crawls
4804     * @return file containing stack traces, or null if no dump file is configured
4805     */
4806    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4807            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4808        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4809        if (tracesPath == null || tracesPath.length() == 0) {
4810            return null;
4811        }
4812
4813        File tracesFile = new File(tracesPath);
4814        try {
4815            File tracesDir = tracesFile.getParentFile();
4816            if (!tracesDir.exists()) {
4817                tracesFile.mkdirs();
4818                if (!SELinux.restorecon(tracesDir)) {
4819                    return null;
4820                }
4821            }
4822            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4823
4824            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4825            tracesFile.createNewFile();
4826            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4827        } catch (IOException e) {
4828            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4829            return null;
4830        }
4831
4832        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4833        return tracesFile;
4834    }
4835
4836    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4837            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4838        // Use a FileObserver to detect when traces finish writing.
4839        // The order of traces is considered important to maintain for legibility.
4840        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4841            @Override
4842            public synchronized void onEvent(int event, String path) { notify(); }
4843        };
4844
4845        try {
4846            observer.startWatching();
4847
4848            // First collect all of the stacks of the most important pids.
4849            if (firstPids != null) {
4850                try {
4851                    int num = firstPids.size();
4852                    for (int i = 0; i < num; i++) {
4853                        synchronized (observer) {
4854                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4855                            observer.wait(200);  // Wait for write-close, give up after 200msec
4856                        }
4857                    }
4858                } catch (InterruptedException e) {
4859                    Log.wtf(TAG, e);
4860                }
4861            }
4862
4863            // Next collect the stacks of the native pids
4864            if (nativeProcs != null) {
4865                int[] pids = Process.getPidsForCommands(nativeProcs);
4866                if (pids != null) {
4867                    for (int pid : pids) {
4868                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4869                    }
4870                }
4871            }
4872
4873            // Lastly, measure CPU usage.
4874            if (processCpuTracker != null) {
4875                processCpuTracker.init();
4876                System.gc();
4877                processCpuTracker.update();
4878                try {
4879                    synchronized (processCpuTracker) {
4880                        processCpuTracker.wait(500); // measure over 1/2 second.
4881                    }
4882                } catch (InterruptedException e) {
4883                }
4884                processCpuTracker.update();
4885
4886                // We'll take the stack crawls of just the top apps using CPU.
4887                final int N = processCpuTracker.countWorkingStats();
4888                int numProcs = 0;
4889                for (int i=0; i<N && numProcs<5; i++) {
4890                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4891                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4892                        numProcs++;
4893                        try {
4894                            synchronized (observer) {
4895                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4896                                observer.wait(200);  // Wait for write-close, give up after 200msec
4897                            }
4898                        } catch (InterruptedException e) {
4899                            Log.wtf(TAG, e);
4900                        }
4901
4902                    }
4903                }
4904            }
4905        } finally {
4906            observer.stopWatching();
4907        }
4908    }
4909
4910    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4911        if (true || IS_USER_BUILD) {
4912            return;
4913        }
4914        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4915        if (tracesPath == null || tracesPath.length() == 0) {
4916            return;
4917        }
4918
4919        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4920        StrictMode.allowThreadDiskWrites();
4921        try {
4922            final File tracesFile = new File(tracesPath);
4923            final File tracesDir = tracesFile.getParentFile();
4924            final File tracesTmp = new File(tracesDir, "__tmp__");
4925            try {
4926                if (!tracesDir.exists()) {
4927                    tracesFile.mkdirs();
4928                    if (!SELinux.restorecon(tracesDir.getPath())) {
4929                        return;
4930                    }
4931                }
4932                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4933
4934                if (tracesFile.exists()) {
4935                    tracesTmp.delete();
4936                    tracesFile.renameTo(tracesTmp);
4937                }
4938                StringBuilder sb = new StringBuilder();
4939                Time tobj = new Time();
4940                tobj.set(System.currentTimeMillis());
4941                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4942                sb.append(": ");
4943                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4944                sb.append(" since ");
4945                sb.append(msg);
4946                FileOutputStream fos = new FileOutputStream(tracesFile);
4947                fos.write(sb.toString().getBytes());
4948                if (app == null) {
4949                    fos.write("\n*** No application process!".getBytes());
4950                }
4951                fos.close();
4952                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4953            } catch (IOException e) {
4954                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4955                return;
4956            }
4957
4958            if (app != null) {
4959                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4960                firstPids.add(app.pid);
4961                dumpStackTraces(tracesPath, firstPids, null, null, null);
4962            }
4963
4964            File lastTracesFile = null;
4965            File curTracesFile = null;
4966            for (int i=9; i>=0; i--) {
4967                String name = String.format(Locale.US, "slow%02d.txt", i);
4968                curTracesFile = new File(tracesDir, name);
4969                if (curTracesFile.exists()) {
4970                    if (lastTracesFile != null) {
4971                        curTracesFile.renameTo(lastTracesFile);
4972                    } else {
4973                        curTracesFile.delete();
4974                    }
4975                }
4976                lastTracesFile = curTracesFile;
4977            }
4978            tracesFile.renameTo(curTracesFile);
4979            if (tracesTmp.exists()) {
4980                tracesTmp.renameTo(tracesFile);
4981            }
4982        } finally {
4983            StrictMode.setThreadPolicy(oldPolicy);
4984        }
4985    }
4986
4987    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4988            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4989        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4990        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4991
4992        if (mController != null) {
4993            try {
4994                // 0 == continue, -1 = kill process immediately
4995                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4996                if (res < 0 && app.pid != MY_PID) {
4997                    app.kill("anr", true);
4998                }
4999            } catch (RemoteException e) {
5000                mController = null;
5001                Watchdog.getInstance().setActivityController(null);
5002            }
5003        }
5004
5005        long anrTime = SystemClock.uptimeMillis();
5006        if (MONITOR_CPU_USAGE) {
5007            updateCpuStatsNow();
5008        }
5009
5010        synchronized (this) {
5011            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5012            if (mShuttingDown) {
5013                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5014                return;
5015            } else if (app.notResponding) {
5016                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5017                return;
5018            } else if (app.crashing) {
5019                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5020                return;
5021            }
5022
5023            // In case we come through here for the same app before completing
5024            // this one, mark as anring now so we will bail out.
5025            app.notResponding = true;
5026
5027            // Log the ANR to the event log.
5028            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5029                    app.processName, app.info.flags, annotation);
5030
5031            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5032            firstPids.add(app.pid);
5033
5034            int parentPid = app.pid;
5035            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5036            if (parentPid != app.pid) firstPids.add(parentPid);
5037
5038            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5039
5040            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5041                ProcessRecord r = mLruProcesses.get(i);
5042                if (r != null && r.thread != null) {
5043                    int pid = r.pid;
5044                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5045                        if (r.persistent) {
5046                            firstPids.add(pid);
5047                        } else {
5048                            lastPids.put(pid, Boolean.TRUE);
5049                        }
5050                    }
5051                }
5052            }
5053        }
5054
5055        // Log the ANR to the main log.
5056        StringBuilder info = new StringBuilder();
5057        info.setLength(0);
5058        info.append("ANR in ").append(app.processName);
5059        if (activity != null && activity.shortComponentName != null) {
5060            info.append(" (").append(activity.shortComponentName).append(")");
5061        }
5062        info.append("\n");
5063        info.append("PID: ").append(app.pid).append("\n");
5064        if (annotation != null) {
5065            info.append("Reason: ").append(annotation).append("\n");
5066        }
5067        if (parent != null && parent != activity) {
5068            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5069        }
5070
5071        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5072
5073        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5074                NATIVE_STACKS_OF_INTEREST);
5075
5076        String cpuInfo = null;
5077        if (MONITOR_CPU_USAGE) {
5078            updateCpuStatsNow();
5079            synchronized (mProcessCpuThread) {
5080                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5081            }
5082            info.append(processCpuTracker.printCurrentLoad());
5083            info.append(cpuInfo);
5084        }
5085
5086        info.append(processCpuTracker.printCurrentState(anrTime));
5087
5088        Slog.e(TAG, info.toString());
5089        if (tracesFile == null) {
5090            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5091            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5092        }
5093
5094        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5095                cpuInfo, tracesFile, null);
5096
5097        if (mController != null) {
5098            try {
5099                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5100                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5101                if (res != 0) {
5102                    if (res < 0 && app.pid != MY_PID) {
5103                        app.kill("anr", true);
5104                    } else {
5105                        synchronized (this) {
5106                            mServices.scheduleServiceTimeoutLocked(app);
5107                        }
5108                    }
5109                    return;
5110                }
5111            } catch (RemoteException e) {
5112                mController = null;
5113                Watchdog.getInstance().setActivityController(null);
5114            }
5115        }
5116
5117        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5118        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5119                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5120
5121        synchronized (this) {
5122            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5123                app.kill("bg anr", true);
5124                return;
5125            }
5126
5127            // Set the app's notResponding state, and look up the errorReportReceiver
5128            makeAppNotRespondingLocked(app,
5129                    activity != null ? activity.shortComponentName : null,
5130                    annotation != null ? "ANR " + annotation : "ANR",
5131                    info.toString());
5132
5133            // Bring up the infamous App Not Responding dialog
5134            Message msg = Message.obtain();
5135            HashMap<String, Object> map = new HashMap<String, Object>();
5136            msg.what = SHOW_NOT_RESPONDING_MSG;
5137            msg.obj = map;
5138            msg.arg1 = aboveSystem ? 1 : 0;
5139            map.put("app", app);
5140            if (activity != null) {
5141                map.put("activity", activity);
5142            }
5143
5144            mHandler.sendMessage(msg);
5145        }
5146    }
5147
5148    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5149        if (!mLaunchWarningShown) {
5150            mLaunchWarningShown = true;
5151            mHandler.post(new Runnable() {
5152                @Override
5153                public void run() {
5154                    synchronized (ActivityManagerService.this) {
5155                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5156                        d.show();
5157                        mHandler.postDelayed(new Runnable() {
5158                            @Override
5159                            public void run() {
5160                                synchronized (ActivityManagerService.this) {
5161                                    d.dismiss();
5162                                    mLaunchWarningShown = false;
5163                                }
5164                            }
5165                        }, 4000);
5166                    }
5167                }
5168            });
5169        }
5170    }
5171
5172    @Override
5173    public boolean clearApplicationUserData(final String packageName,
5174            final IPackageDataObserver observer, int userId) {
5175        enforceNotIsolatedCaller("clearApplicationUserData");
5176        int uid = Binder.getCallingUid();
5177        int pid = Binder.getCallingPid();
5178        userId = handleIncomingUser(pid, uid,
5179                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5180        long callingId = Binder.clearCallingIdentity();
5181        try {
5182            IPackageManager pm = AppGlobals.getPackageManager();
5183            int pkgUid = -1;
5184            synchronized(this) {
5185                try {
5186                    pkgUid = pm.getPackageUid(packageName, userId);
5187                } catch (RemoteException e) {
5188                }
5189                if (pkgUid == -1) {
5190                    Slog.w(TAG, "Invalid packageName: " + packageName);
5191                    if (observer != null) {
5192                        try {
5193                            observer.onRemoveCompleted(packageName, false);
5194                        } catch (RemoteException e) {
5195                            Slog.i(TAG, "Observer no longer exists.");
5196                        }
5197                    }
5198                    return false;
5199                }
5200                if (uid == pkgUid || checkComponentPermission(
5201                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5202                        pid, uid, -1, true)
5203                        == PackageManager.PERMISSION_GRANTED) {
5204                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5205                } else {
5206                    throw new SecurityException("PID " + pid + " does not have permission "
5207                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5208                                    + " of package " + packageName);
5209                }
5210
5211                // Remove all tasks match the cleared application package and user
5212                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5213                    final TaskRecord tr = mRecentTasks.get(i);
5214                    final String taskPackageName =
5215                            tr.getBaseIntent().getComponent().getPackageName();
5216                    if (tr.userId != userId) continue;
5217                    if (!taskPackageName.equals(packageName)) continue;
5218                    removeTaskByIdLocked(tr.taskId, 0);
5219                }
5220            }
5221
5222            try {
5223                // Clear application user data
5224                pm.clearApplicationUserData(packageName, observer, userId);
5225
5226                synchronized(this) {
5227                    // Remove all permissions granted from/to this package
5228                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5229                }
5230
5231                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5232                        Uri.fromParts("package", packageName, null));
5233                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5234                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5235                        null, null, 0, null, null, null, false, false, userId);
5236            } catch (RemoteException e) {
5237            }
5238        } finally {
5239            Binder.restoreCallingIdentity(callingId);
5240        }
5241        return true;
5242    }
5243
5244    @Override
5245    public void killBackgroundProcesses(final String packageName, int userId) {
5246        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5247                != PackageManager.PERMISSION_GRANTED &&
5248                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5249                        != PackageManager.PERMISSION_GRANTED) {
5250            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5251                    + Binder.getCallingPid()
5252                    + ", uid=" + Binder.getCallingUid()
5253                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5254            Slog.w(TAG, msg);
5255            throw new SecurityException(msg);
5256        }
5257
5258        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5259                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5260        long callingId = Binder.clearCallingIdentity();
5261        try {
5262            IPackageManager pm = AppGlobals.getPackageManager();
5263            synchronized(this) {
5264                int appId = -1;
5265                try {
5266                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5267                } catch (RemoteException e) {
5268                }
5269                if (appId == -1) {
5270                    Slog.w(TAG, "Invalid packageName: " + packageName);
5271                    return;
5272                }
5273                killPackageProcessesLocked(packageName, appId, userId,
5274                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5275            }
5276        } finally {
5277            Binder.restoreCallingIdentity(callingId);
5278        }
5279    }
5280
5281    @Override
5282    public void killAllBackgroundProcesses() {
5283        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5284                != PackageManager.PERMISSION_GRANTED) {
5285            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5286                    + Binder.getCallingPid()
5287                    + ", uid=" + Binder.getCallingUid()
5288                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5289            Slog.w(TAG, msg);
5290            throw new SecurityException(msg);
5291        }
5292
5293        long callingId = Binder.clearCallingIdentity();
5294        try {
5295            synchronized(this) {
5296                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5297                final int NP = mProcessNames.getMap().size();
5298                for (int ip=0; ip<NP; ip++) {
5299                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5300                    final int NA = apps.size();
5301                    for (int ia=0; ia<NA; ia++) {
5302                        ProcessRecord app = apps.valueAt(ia);
5303                        if (app.persistent) {
5304                            // we don't kill persistent processes
5305                            continue;
5306                        }
5307                        if (app.removed) {
5308                            procs.add(app);
5309                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5310                            app.removed = true;
5311                            procs.add(app);
5312                        }
5313                    }
5314                }
5315
5316                int N = procs.size();
5317                for (int i=0; i<N; i++) {
5318                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5319                }
5320                mAllowLowerMemLevel = true;
5321                updateOomAdjLocked();
5322                doLowMemReportIfNeededLocked(null);
5323            }
5324        } finally {
5325            Binder.restoreCallingIdentity(callingId);
5326        }
5327    }
5328
5329    @Override
5330    public void forceStopPackage(final String packageName, int userId) {
5331        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5332                != PackageManager.PERMISSION_GRANTED) {
5333            String msg = "Permission Denial: forceStopPackage() from pid="
5334                    + Binder.getCallingPid()
5335                    + ", uid=" + Binder.getCallingUid()
5336                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5337            Slog.w(TAG, msg);
5338            throw new SecurityException(msg);
5339        }
5340        final int callingPid = Binder.getCallingPid();
5341        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5342                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5343        long callingId = Binder.clearCallingIdentity();
5344        try {
5345            IPackageManager pm = AppGlobals.getPackageManager();
5346            synchronized(this) {
5347                int[] users = userId == UserHandle.USER_ALL
5348                        ? getUsersLocked() : new int[] { userId };
5349                for (int user : users) {
5350                    int pkgUid = -1;
5351                    try {
5352                        pkgUid = pm.getPackageUid(packageName, user);
5353                    } catch (RemoteException e) {
5354                    }
5355                    if (pkgUid == -1) {
5356                        Slog.w(TAG, "Invalid packageName: " + packageName);
5357                        continue;
5358                    }
5359                    try {
5360                        pm.setPackageStoppedState(packageName, true, user);
5361                    } catch (RemoteException e) {
5362                    } catch (IllegalArgumentException e) {
5363                        Slog.w(TAG, "Failed trying to unstop package "
5364                                + packageName + ": " + e);
5365                    }
5366                    if (isUserRunningLocked(user, false)) {
5367                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5368                    }
5369                }
5370            }
5371        } finally {
5372            Binder.restoreCallingIdentity(callingId);
5373        }
5374    }
5375
5376    @Override
5377    public void addPackageDependency(String packageName) {
5378        synchronized (this) {
5379            int callingPid = Binder.getCallingPid();
5380            if (callingPid == Process.myPid()) {
5381                //  Yeah, um, no.
5382                Slog.w(TAG, "Can't addPackageDependency on system process");
5383                return;
5384            }
5385            ProcessRecord proc;
5386            synchronized (mPidsSelfLocked) {
5387                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5388            }
5389            if (proc != null) {
5390                if (proc.pkgDeps == null) {
5391                    proc.pkgDeps = new ArraySet<String>(1);
5392                }
5393                proc.pkgDeps.add(packageName);
5394            }
5395        }
5396    }
5397
5398    /*
5399     * The pkg name and app id have to be specified.
5400     */
5401    @Override
5402    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5403        if (pkg == null) {
5404            return;
5405        }
5406        // Make sure the uid is valid.
5407        if (appid < 0) {
5408            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5409            return;
5410        }
5411        int callerUid = Binder.getCallingUid();
5412        // Only the system server can kill an application
5413        if (callerUid == Process.SYSTEM_UID) {
5414            // Post an aysnc message to kill the application
5415            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5416            msg.arg1 = appid;
5417            msg.arg2 = 0;
5418            Bundle bundle = new Bundle();
5419            bundle.putString("pkg", pkg);
5420            bundle.putString("reason", reason);
5421            msg.obj = bundle;
5422            mHandler.sendMessage(msg);
5423        } else {
5424            throw new SecurityException(callerUid + " cannot kill pkg: " +
5425                    pkg);
5426        }
5427    }
5428
5429    @Override
5430    public void closeSystemDialogs(String reason) {
5431        enforceNotIsolatedCaller("closeSystemDialogs");
5432
5433        final int pid = Binder.getCallingPid();
5434        final int uid = Binder.getCallingUid();
5435        final long origId = Binder.clearCallingIdentity();
5436        try {
5437            synchronized (this) {
5438                // Only allow this from foreground processes, so that background
5439                // applications can't abuse it to prevent system UI from being shown.
5440                if (uid >= Process.FIRST_APPLICATION_UID) {
5441                    ProcessRecord proc;
5442                    synchronized (mPidsSelfLocked) {
5443                        proc = mPidsSelfLocked.get(pid);
5444                    }
5445                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5446                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5447                                + " from background process " + proc);
5448                        return;
5449                    }
5450                }
5451                closeSystemDialogsLocked(reason);
5452            }
5453        } finally {
5454            Binder.restoreCallingIdentity(origId);
5455        }
5456    }
5457
5458    void closeSystemDialogsLocked(String reason) {
5459        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5460        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5461                | Intent.FLAG_RECEIVER_FOREGROUND);
5462        if (reason != null) {
5463            intent.putExtra("reason", reason);
5464        }
5465        mWindowManager.closeSystemDialogs(reason);
5466
5467        mStackSupervisor.closeSystemDialogsLocked();
5468
5469        broadcastIntentLocked(null, null, intent, null,
5470                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5471                Process.SYSTEM_UID, UserHandle.USER_ALL);
5472    }
5473
5474    @Override
5475    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5476        enforceNotIsolatedCaller("getProcessMemoryInfo");
5477        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5478        for (int i=pids.length-1; i>=0; i--) {
5479            ProcessRecord proc;
5480            int oomAdj;
5481            synchronized (this) {
5482                synchronized (mPidsSelfLocked) {
5483                    proc = mPidsSelfLocked.get(pids[i]);
5484                    oomAdj = proc != null ? proc.setAdj : 0;
5485                }
5486            }
5487            infos[i] = new Debug.MemoryInfo();
5488            Debug.getMemoryInfo(pids[i], infos[i]);
5489            if (proc != null) {
5490                synchronized (this) {
5491                    if (proc.thread != null && proc.setAdj == oomAdj) {
5492                        // Record this for posterity if the process has been stable.
5493                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5494                                infos[i].getTotalUss(), false, proc.pkgList);
5495                    }
5496                }
5497            }
5498        }
5499        return infos;
5500    }
5501
5502    @Override
5503    public long[] getProcessPss(int[] pids) {
5504        enforceNotIsolatedCaller("getProcessPss");
5505        long[] pss = new long[pids.length];
5506        for (int i=pids.length-1; i>=0; i--) {
5507            ProcessRecord proc;
5508            int oomAdj;
5509            synchronized (this) {
5510                synchronized (mPidsSelfLocked) {
5511                    proc = mPidsSelfLocked.get(pids[i]);
5512                    oomAdj = proc != null ? proc.setAdj : 0;
5513                }
5514            }
5515            long[] tmpUss = new long[1];
5516            pss[i] = Debug.getPss(pids[i], tmpUss);
5517            if (proc != null) {
5518                synchronized (this) {
5519                    if (proc.thread != null && proc.setAdj == oomAdj) {
5520                        // Record this for posterity if the process has been stable.
5521                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5522                    }
5523                }
5524            }
5525        }
5526        return pss;
5527    }
5528
5529    @Override
5530    public void killApplicationProcess(String processName, int uid) {
5531        if (processName == null) {
5532            return;
5533        }
5534
5535        int callerUid = Binder.getCallingUid();
5536        // Only the system server can kill an application
5537        if (callerUid == Process.SYSTEM_UID) {
5538            synchronized (this) {
5539                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5540                if (app != null && app.thread != null) {
5541                    try {
5542                        app.thread.scheduleSuicide();
5543                    } catch (RemoteException e) {
5544                        // If the other end already died, then our work here is done.
5545                    }
5546                } else {
5547                    Slog.w(TAG, "Process/uid not found attempting kill of "
5548                            + processName + " / " + uid);
5549                }
5550            }
5551        } else {
5552            throw new SecurityException(callerUid + " cannot kill app process: " +
5553                    processName);
5554        }
5555    }
5556
5557    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5558        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5559                false, true, false, false, UserHandle.getUserId(uid), reason);
5560        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5561                Uri.fromParts("package", packageName, null));
5562        if (!mProcessesReady) {
5563            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5564                    | Intent.FLAG_RECEIVER_FOREGROUND);
5565        }
5566        intent.putExtra(Intent.EXTRA_UID, uid);
5567        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5568        broadcastIntentLocked(null, null, intent,
5569                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5570                false, false,
5571                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5572    }
5573
5574    private void forceStopUserLocked(int userId, String reason) {
5575        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5576        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5577        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5578                | Intent.FLAG_RECEIVER_FOREGROUND);
5579        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5580        broadcastIntentLocked(null, null, intent,
5581                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5582                false, false,
5583                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5584    }
5585
5586    private final boolean killPackageProcessesLocked(String packageName, int appId,
5587            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5588            boolean doit, boolean evenPersistent, String reason) {
5589        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5590
5591        // Remove all processes this package may have touched: all with the
5592        // same UID (except for the system or root user), and all whose name
5593        // matches the package name.
5594        final int NP = mProcessNames.getMap().size();
5595        for (int ip=0; ip<NP; ip++) {
5596            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5597            final int NA = apps.size();
5598            for (int ia=0; ia<NA; ia++) {
5599                ProcessRecord app = apps.valueAt(ia);
5600                if (app.persistent && !evenPersistent) {
5601                    // we don't kill persistent processes
5602                    continue;
5603                }
5604                if (app.removed) {
5605                    if (doit) {
5606                        procs.add(app);
5607                    }
5608                    continue;
5609                }
5610
5611                // Skip process if it doesn't meet our oom adj requirement.
5612                if (app.setAdj < minOomAdj) {
5613                    continue;
5614                }
5615
5616                // If no package is specified, we call all processes under the
5617                // give user id.
5618                if (packageName == null) {
5619                    if (app.userId != userId) {
5620                        continue;
5621                    }
5622                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5623                        continue;
5624                    }
5625                // Package has been specified, we want to hit all processes
5626                // that match it.  We need to qualify this by the processes
5627                // that are running under the specified app and user ID.
5628                } else {
5629                    final boolean isDep = app.pkgDeps != null
5630                            && app.pkgDeps.contains(packageName);
5631                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5632                        continue;
5633                    }
5634                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5635                        continue;
5636                    }
5637                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5638                        continue;
5639                    }
5640                }
5641
5642                // Process has passed all conditions, kill it!
5643                if (!doit) {
5644                    return true;
5645                }
5646                app.removed = true;
5647                procs.add(app);
5648            }
5649        }
5650
5651        int N = procs.size();
5652        for (int i=0; i<N; i++) {
5653            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5654        }
5655        updateOomAdjLocked();
5656        return N > 0;
5657    }
5658
5659    private final boolean forceStopPackageLocked(String name, int appId,
5660            boolean callerWillRestart, boolean purgeCache, boolean doit,
5661            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5662        int i;
5663        int N;
5664
5665        if (userId == UserHandle.USER_ALL && name == null) {
5666            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5667        }
5668
5669        if (appId < 0 && name != null) {
5670            try {
5671                appId = UserHandle.getAppId(
5672                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5673            } catch (RemoteException e) {
5674            }
5675        }
5676
5677        if (doit) {
5678            if (name != null) {
5679                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5680                        + " user=" + userId + ": " + reason);
5681            } else {
5682                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5683            }
5684
5685            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5686            for (int ip=pmap.size()-1; ip>=0; ip--) {
5687                SparseArray<Long> ba = pmap.valueAt(ip);
5688                for (i=ba.size()-1; i>=0; i--) {
5689                    boolean remove = false;
5690                    final int entUid = ba.keyAt(i);
5691                    if (name != null) {
5692                        if (userId == UserHandle.USER_ALL) {
5693                            if (UserHandle.getAppId(entUid) == appId) {
5694                                remove = true;
5695                            }
5696                        } else {
5697                            if (entUid == UserHandle.getUid(userId, appId)) {
5698                                remove = true;
5699                            }
5700                        }
5701                    } else if (UserHandle.getUserId(entUid) == userId) {
5702                        remove = true;
5703                    }
5704                    if (remove) {
5705                        ba.removeAt(i);
5706                    }
5707                }
5708                if (ba.size() == 0) {
5709                    pmap.removeAt(ip);
5710                }
5711            }
5712        }
5713
5714        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5715                -100, callerWillRestart, true, doit, evenPersistent,
5716                name == null ? ("stop user " + userId) : ("stop " + name));
5717
5718        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5719            if (!doit) {
5720                return true;
5721            }
5722            didSomething = true;
5723        }
5724
5725        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5726            if (!doit) {
5727                return true;
5728            }
5729            didSomething = true;
5730        }
5731
5732        if (name == null) {
5733            // Remove all sticky broadcasts from this user.
5734            mStickyBroadcasts.remove(userId);
5735        }
5736
5737        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5738        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5739                userId, providers)) {
5740            if (!doit) {
5741                return true;
5742            }
5743            didSomething = true;
5744        }
5745        N = providers.size();
5746        for (i=0; i<N; i++) {
5747            removeDyingProviderLocked(null, providers.get(i), true);
5748        }
5749
5750        // Remove transient permissions granted from/to this package/user
5751        removeUriPermissionsForPackageLocked(name, userId, false);
5752
5753        if (name == null || uninstalling) {
5754            // Remove pending intents.  For now we only do this when force
5755            // stopping users, because we have some problems when doing this
5756            // for packages -- app widgets are not currently cleaned up for
5757            // such packages, so they can be left with bad pending intents.
5758            if (mIntentSenderRecords.size() > 0) {
5759                Iterator<WeakReference<PendingIntentRecord>> it
5760                        = mIntentSenderRecords.values().iterator();
5761                while (it.hasNext()) {
5762                    WeakReference<PendingIntentRecord> wpir = it.next();
5763                    if (wpir == null) {
5764                        it.remove();
5765                        continue;
5766                    }
5767                    PendingIntentRecord pir = wpir.get();
5768                    if (pir == null) {
5769                        it.remove();
5770                        continue;
5771                    }
5772                    if (name == null) {
5773                        // Stopping user, remove all objects for the user.
5774                        if (pir.key.userId != userId) {
5775                            // Not the same user, skip it.
5776                            continue;
5777                        }
5778                    } else {
5779                        if (UserHandle.getAppId(pir.uid) != appId) {
5780                            // Different app id, skip it.
5781                            continue;
5782                        }
5783                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5784                            // Different user, skip it.
5785                            continue;
5786                        }
5787                        if (!pir.key.packageName.equals(name)) {
5788                            // Different package, skip it.
5789                            continue;
5790                        }
5791                    }
5792                    if (!doit) {
5793                        return true;
5794                    }
5795                    didSomething = true;
5796                    it.remove();
5797                    pir.canceled = true;
5798                    if (pir.key.activity != null) {
5799                        pir.key.activity.pendingResults.remove(pir.ref);
5800                    }
5801                }
5802            }
5803        }
5804
5805        if (doit) {
5806            if (purgeCache && name != null) {
5807                AttributeCache ac = AttributeCache.instance();
5808                if (ac != null) {
5809                    ac.removePackage(name);
5810                }
5811            }
5812            if (mBooted) {
5813                mStackSupervisor.resumeTopActivitiesLocked();
5814                mStackSupervisor.scheduleIdleLocked();
5815            }
5816        }
5817
5818        return didSomething;
5819    }
5820
5821    private final boolean removeProcessLocked(ProcessRecord app,
5822            boolean callerWillRestart, boolean allowRestart, String reason) {
5823        final String name = app.processName;
5824        final int uid = app.uid;
5825        if (DEBUG_PROCESSES) Slog.d(
5826            TAG, "Force removing proc " + app.toShortString() + " (" + name
5827            + "/" + uid + ")");
5828
5829        mProcessNames.remove(name, uid);
5830        mIsolatedProcesses.remove(app.uid);
5831        if (mHeavyWeightProcess == app) {
5832            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5833                    mHeavyWeightProcess.userId, 0));
5834            mHeavyWeightProcess = null;
5835        }
5836        boolean needRestart = false;
5837        if (app.pid > 0 && app.pid != MY_PID) {
5838            int pid = app.pid;
5839            synchronized (mPidsSelfLocked) {
5840                mPidsSelfLocked.remove(pid);
5841                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5842            }
5843            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5844            if (app.isolated) {
5845                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5846            }
5847            app.kill(reason, true);
5848            handleAppDiedLocked(app, true, allowRestart);
5849            removeLruProcessLocked(app);
5850
5851            if (app.persistent && !app.isolated) {
5852                if (!callerWillRestart) {
5853                    addAppLocked(app.info, false, null /* ABI override */);
5854                } else {
5855                    needRestart = true;
5856                }
5857            }
5858        } else {
5859            mRemovedProcesses.add(app);
5860        }
5861
5862        return needRestart;
5863    }
5864
5865    private final void processStartTimedOutLocked(ProcessRecord app) {
5866        final int pid = app.pid;
5867        boolean gone = false;
5868        synchronized (mPidsSelfLocked) {
5869            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5870            if (knownApp != null && knownApp.thread == null) {
5871                mPidsSelfLocked.remove(pid);
5872                gone = true;
5873            }
5874        }
5875
5876        if (gone) {
5877            Slog.w(TAG, "Process " + app + " failed to attach");
5878            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5879                    pid, app.uid, app.processName);
5880            mProcessNames.remove(app.processName, app.uid);
5881            mIsolatedProcesses.remove(app.uid);
5882            if (mHeavyWeightProcess == app) {
5883                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5884                        mHeavyWeightProcess.userId, 0));
5885                mHeavyWeightProcess = null;
5886            }
5887            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5888            if (app.isolated) {
5889                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5890            }
5891            // Take care of any launching providers waiting for this process.
5892            checkAppInLaunchingProvidersLocked(app, true);
5893            // Take care of any services that are waiting for the process.
5894            mServices.processStartTimedOutLocked(app);
5895            app.kill("start timeout", true);
5896            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5897                Slog.w(TAG, "Unattached app died before backup, skipping");
5898                try {
5899                    IBackupManager bm = IBackupManager.Stub.asInterface(
5900                            ServiceManager.getService(Context.BACKUP_SERVICE));
5901                    bm.agentDisconnected(app.info.packageName);
5902                } catch (RemoteException e) {
5903                    // Can't happen; the backup manager is local
5904                }
5905            }
5906            if (isPendingBroadcastProcessLocked(pid)) {
5907                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5908                skipPendingBroadcastLocked(pid);
5909            }
5910        } else {
5911            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5912        }
5913    }
5914
5915    private final boolean attachApplicationLocked(IApplicationThread thread,
5916            int pid) {
5917
5918        // Find the application record that is being attached...  either via
5919        // the pid if we are running in multiple processes, or just pull the
5920        // next app record if we are emulating process with anonymous threads.
5921        ProcessRecord app;
5922        if (pid != MY_PID && pid >= 0) {
5923            synchronized (mPidsSelfLocked) {
5924                app = mPidsSelfLocked.get(pid);
5925            }
5926        } else {
5927            app = null;
5928        }
5929
5930        if (app == null) {
5931            Slog.w(TAG, "No pending application record for pid " + pid
5932                    + " (IApplicationThread " + thread + "); dropping process");
5933            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5934            if (pid > 0 && pid != MY_PID) {
5935                Process.killProcessQuiet(pid);
5936                //TODO: Process.killProcessGroup(app.info.uid, pid);
5937            } else {
5938                try {
5939                    thread.scheduleExit();
5940                } catch (Exception e) {
5941                    // Ignore exceptions.
5942                }
5943            }
5944            return false;
5945        }
5946
5947        // If this application record is still attached to a previous
5948        // process, clean it up now.
5949        if (app.thread != null) {
5950            handleAppDiedLocked(app, true, true);
5951        }
5952
5953        // Tell the process all about itself.
5954
5955        if (localLOGV) Slog.v(
5956                TAG, "Binding process pid " + pid + " to record " + app);
5957
5958        final String processName = app.processName;
5959        try {
5960            AppDeathRecipient adr = new AppDeathRecipient(
5961                    app, pid, thread);
5962            thread.asBinder().linkToDeath(adr, 0);
5963            app.deathRecipient = adr;
5964        } catch (RemoteException e) {
5965            app.resetPackageList(mProcessStats);
5966            startProcessLocked(app, "link fail", processName);
5967            return false;
5968        }
5969
5970        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5971
5972        app.makeActive(thread, mProcessStats);
5973        app.curAdj = app.setAdj = -100;
5974        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5975        app.forcingToForeground = null;
5976        updateProcessForegroundLocked(app, false, false);
5977        app.hasShownUi = false;
5978        app.debugging = false;
5979        app.cached = false;
5980
5981        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5982
5983        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5984        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5985
5986        if (!normalMode) {
5987            Slog.i(TAG, "Launching preboot mode app: " + app);
5988        }
5989
5990        if (localLOGV) Slog.v(
5991            TAG, "New app record " + app
5992            + " thread=" + thread.asBinder() + " pid=" + pid);
5993        try {
5994            int testMode = IApplicationThread.DEBUG_OFF;
5995            if (mDebugApp != null && mDebugApp.equals(processName)) {
5996                testMode = mWaitForDebugger
5997                    ? IApplicationThread.DEBUG_WAIT
5998                    : IApplicationThread.DEBUG_ON;
5999                app.debugging = true;
6000                if (mDebugTransient) {
6001                    mDebugApp = mOrigDebugApp;
6002                    mWaitForDebugger = mOrigWaitForDebugger;
6003                }
6004            }
6005            String profileFile = app.instrumentationProfileFile;
6006            ParcelFileDescriptor profileFd = null;
6007            int samplingInterval = 0;
6008            boolean profileAutoStop = false;
6009            if (mProfileApp != null && mProfileApp.equals(processName)) {
6010                mProfileProc = app;
6011                profileFile = mProfileFile;
6012                profileFd = mProfileFd;
6013                samplingInterval = mSamplingInterval;
6014                profileAutoStop = mAutoStopProfiler;
6015            }
6016            boolean enableOpenGlTrace = false;
6017            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6018                enableOpenGlTrace = true;
6019                mOpenGlTraceApp = null;
6020            }
6021
6022            // If the app is being launched for restore or full backup, set it up specially
6023            boolean isRestrictedBackupMode = false;
6024            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6025                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6026                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6027                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6028            }
6029
6030            ensurePackageDexOpt(app.instrumentationInfo != null
6031                    ? app.instrumentationInfo.packageName
6032                    : app.info.packageName);
6033            if (app.instrumentationClass != null) {
6034                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6035            }
6036            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6037                    + processName + " with config " + mConfiguration);
6038            ApplicationInfo appInfo = app.instrumentationInfo != null
6039                    ? app.instrumentationInfo : app.info;
6040            app.compat = compatibilityInfoForPackageLocked(appInfo);
6041            if (profileFd != null) {
6042                profileFd = profileFd.dup();
6043            }
6044            ProfilerInfo profilerInfo = profileFile == null ? null
6045                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6046            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6047                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6048                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6049                    isRestrictedBackupMode || !normalMode, app.persistent,
6050                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6051                    mCoreSettingsObserver.getCoreSettingsLocked());
6052            updateLruProcessLocked(app, false, null);
6053            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6054        } catch (Exception e) {
6055            // todo: Yikes!  What should we do?  For now we will try to
6056            // start another process, but that could easily get us in
6057            // an infinite loop of restarting processes...
6058            Slog.w(TAG, "Exception thrown during bind!", e);
6059
6060            app.resetPackageList(mProcessStats);
6061            app.unlinkDeathRecipient();
6062            startProcessLocked(app, "bind fail", processName);
6063            return false;
6064        }
6065
6066        // Remove this record from the list of starting applications.
6067        mPersistentStartingProcesses.remove(app);
6068        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6069                "Attach application locked removing on hold: " + app);
6070        mProcessesOnHold.remove(app);
6071
6072        boolean badApp = false;
6073        boolean didSomething = false;
6074
6075        // See if the top visible activity is waiting to run in this process...
6076        if (normalMode) {
6077            try {
6078                if (mStackSupervisor.attachApplicationLocked(app)) {
6079                    didSomething = true;
6080                }
6081            } catch (Exception e) {
6082                badApp = true;
6083            }
6084        }
6085
6086        // Find any services that should be running in this process...
6087        if (!badApp) {
6088            try {
6089                didSomething |= mServices.attachApplicationLocked(app, processName);
6090            } catch (Exception e) {
6091                badApp = true;
6092            }
6093        }
6094
6095        // Check if a next-broadcast receiver is in this process...
6096        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6097            try {
6098                didSomething |= sendPendingBroadcastsLocked(app);
6099            } catch (Exception e) {
6100                // If the app died trying to launch the receiver we declare it 'bad'
6101                badApp = true;
6102            }
6103        }
6104
6105        // Check whether the next backup agent is in this process...
6106        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6107            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6108            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6109            try {
6110                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6111                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6112                        mBackupTarget.backupMode);
6113            } catch (Exception e) {
6114                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6115                e.printStackTrace();
6116            }
6117        }
6118
6119        if (badApp) {
6120            // todo: Also need to kill application to deal with all
6121            // kinds of exceptions.
6122            handleAppDiedLocked(app, false, true);
6123            return false;
6124        }
6125
6126        if (!didSomething) {
6127            updateOomAdjLocked();
6128        }
6129
6130        return true;
6131    }
6132
6133    @Override
6134    public final void attachApplication(IApplicationThread thread) {
6135        synchronized (this) {
6136            int callingPid = Binder.getCallingPid();
6137            final long origId = Binder.clearCallingIdentity();
6138            attachApplicationLocked(thread, callingPid);
6139            Binder.restoreCallingIdentity(origId);
6140        }
6141    }
6142
6143    @Override
6144    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6145        final long origId = Binder.clearCallingIdentity();
6146        synchronized (this) {
6147            ActivityStack stack = ActivityRecord.getStackLocked(token);
6148            if (stack != null) {
6149                ActivityRecord r =
6150                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6151                if (stopProfiling) {
6152                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6153                        try {
6154                            mProfileFd.close();
6155                        } catch (IOException e) {
6156                        }
6157                        clearProfilerLocked();
6158                    }
6159                }
6160            }
6161        }
6162        Binder.restoreCallingIdentity(origId);
6163    }
6164
6165    void postEnableScreenAfterBootLocked() {
6166        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6167    }
6168
6169    void enableScreenAfterBoot() {
6170        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6171                SystemClock.uptimeMillis());
6172        mWindowManager.enableScreenAfterBoot();
6173
6174        synchronized (this) {
6175            updateEventDispatchingLocked();
6176        }
6177    }
6178
6179    @Override
6180    public void showBootMessage(final CharSequence msg, final boolean always) {
6181        enforceNotIsolatedCaller("showBootMessage");
6182        mWindowManager.showBootMessage(msg, always);
6183    }
6184
6185    @Override
6186    public void keyguardWaitingForActivityDrawn() {
6187        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6188        final long token = Binder.clearCallingIdentity();
6189        try {
6190            synchronized (this) {
6191                if (DEBUG_LOCKSCREEN) logLockScreen("");
6192                mWindowManager.keyguardWaitingForActivityDrawn();
6193            }
6194        } finally {
6195            Binder.restoreCallingIdentity(token);
6196        }
6197    }
6198
6199    final void finishBooting() {
6200        synchronized (this) {
6201            if (!mBootAnimationComplete) {
6202                mCallFinishBooting = true;
6203                return;
6204            }
6205            mCallFinishBooting = false;
6206        }
6207
6208        // Register receivers to handle package update events
6209        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6210
6211        // Let system services know.
6212        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6213
6214        synchronized (this) {
6215            // Ensure that any processes we had put on hold are now started
6216            // up.
6217            final int NP = mProcessesOnHold.size();
6218            if (NP > 0) {
6219                ArrayList<ProcessRecord> procs =
6220                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6221                for (int ip=0; ip<NP; ip++) {
6222                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6223                            + procs.get(ip));
6224                    startProcessLocked(procs.get(ip), "on-hold", null);
6225                }
6226            }
6227
6228            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6229                // Start looking for apps that are abusing wake locks.
6230                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6231                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6232                // Tell anyone interested that we are done booting!
6233                SystemProperties.set("sys.boot_completed", "1");
6234                SystemProperties.set("dev.bootcomplete", "1");
6235                for (int i=0; i<mStartedUsers.size(); i++) {
6236                    UserStartedState uss = mStartedUsers.valueAt(i);
6237                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6238                        uss.mState = UserStartedState.STATE_RUNNING;
6239                        final int userId = mStartedUsers.keyAt(i);
6240                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6241                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6242                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6243                        broadcastIntentLocked(null, null, intent, null,
6244                                new IIntentReceiver.Stub() {
6245                                    @Override
6246                                    public void performReceive(Intent intent, int resultCode,
6247                                            String data, Bundle extras, boolean ordered,
6248                                            boolean sticky, int sendingUser) {
6249                                        synchronized (ActivityManagerService.this) {
6250                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6251                                                    true, false);
6252                                        }
6253                                    }
6254                                },
6255                                0, null, null,
6256                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6257                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6258                                userId);
6259                    }
6260                }
6261                scheduleStartProfilesLocked();
6262            }
6263        }
6264    }
6265
6266    @Override
6267    public void bootAnimationComplete() {
6268        final boolean callFinishBooting;
6269        synchronized (this) {
6270            callFinishBooting = mCallFinishBooting;
6271            mBootAnimationComplete = true;
6272        }
6273        if (callFinishBooting) {
6274            finishBooting();
6275        }
6276    }
6277
6278    final void ensureBootCompleted() {
6279        boolean booting;
6280        boolean enableScreen;
6281        synchronized (this) {
6282            booting = mBooting;
6283            mBooting = false;
6284            enableScreen = !mBooted;
6285            mBooted = true;
6286        }
6287
6288        if (booting) {
6289            finishBooting();
6290        }
6291
6292        if (enableScreen) {
6293            enableScreenAfterBoot();
6294        }
6295    }
6296
6297    @Override
6298    public final void activityResumed(IBinder token) {
6299        final long origId = Binder.clearCallingIdentity();
6300        synchronized(this) {
6301            ActivityStack stack = ActivityRecord.getStackLocked(token);
6302            if (stack != null) {
6303                ActivityRecord.activityResumedLocked(token);
6304            }
6305        }
6306        Binder.restoreCallingIdentity(origId);
6307    }
6308
6309    @Override
6310    public final void activityPaused(IBinder token) {
6311        final long origId = Binder.clearCallingIdentity();
6312        synchronized(this) {
6313            ActivityStack stack = ActivityRecord.getStackLocked(token);
6314            if (stack != null) {
6315                stack.activityPausedLocked(token, false);
6316            }
6317        }
6318        Binder.restoreCallingIdentity(origId);
6319    }
6320
6321    @Override
6322    public final void activityStopped(IBinder token, Bundle icicle,
6323            PersistableBundle persistentState, CharSequence description) {
6324        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6325
6326        // Refuse possible leaked file descriptors
6327        if (icicle != null && icicle.hasFileDescriptors()) {
6328            throw new IllegalArgumentException("File descriptors passed in Bundle");
6329        }
6330
6331        final long origId = Binder.clearCallingIdentity();
6332
6333        synchronized (this) {
6334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6335            if (r != null) {
6336                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6337            }
6338        }
6339
6340        trimApplications();
6341
6342        Binder.restoreCallingIdentity(origId);
6343    }
6344
6345    @Override
6346    public final void activityDestroyed(IBinder token) {
6347        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6348        synchronized (this) {
6349            ActivityStack stack = ActivityRecord.getStackLocked(token);
6350            if (stack != null) {
6351                stack.activityDestroyedLocked(token);
6352            }
6353        }
6354    }
6355
6356    @Override
6357    public final void backgroundResourcesReleased(IBinder token) {
6358        final long origId = Binder.clearCallingIdentity();
6359        try {
6360            synchronized (this) {
6361                ActivityStack stack = ActivityRecord.getStackLocked(token);
6362                if (stack != null) {
6363                    stack.backgroundResourcesReleased(token);
6364                }
6365            }
6366        } finally {
6367            Binder.restoreCallingIdentity(origId);
6368        }
6369    }
6370
6371    @Override
6372    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6373        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6374    }
6375
6376    @Override
6377    public final void notifyEnterAnimationComplete(IBinder token) {
6378        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6379    }
6380
6381    @Override
6382    public String getCallingPackage(IBinder token) {
6383        synchronized (this) {
6384            ActivityRecord r = getCallingRecordLocked(token);
6385            return r != null ? r.info.packageName : null;
6386        }
6387    }
6388
6389    @Override
6390    public ComponentName getCallingActivity(IBinder token) {
6391        synchronized (this) {
6392            ActivityRecord r = getCallingRecordLocked(token);
6393            return r != null ? r.intent.getComponent() : null;
6394        }
6395    }
6396
6397    private ActivityRecord getCallingRecordLocked(IBinder token) {
6398        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6399        if (r == null) {
6400            return null;
6401        }
6402        return r.resultTo;
6403    }
6404
6405    @Override
6406    public ComponentName getActivityClassForToken(IBinder token) {
6407        synchronized(this) {
6408            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6409            if (r == null) {
6410                return null;
6411            }
6412            return r.intent.getComponent();
6413        }
6414    }
6415
6416    @Override
6417    public String getPackageForToken(IBinder token) {
6418        synchronized(this) {
6419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6420            if (r == null) {
6421                return null;
6422            }
6423            return r.packageName;
6424        }
6425    }
6426
6427    @Override
6428    public IIntentSender getIntentSender(int type,
6429            String packageName, IBinder token, String resultWho,
6430            int requestCode, Intent[] intents, String[] resolvedTypes,
6431            int flags, Bundle options, int userId) {
6432        enforceNotIsolatedCaller("getIntentSender");
6433        // Refuse possible leaked file descriptors
6434        if (intents != null) {
6435            if (intents.length < 1) {
6436                throw new IllegalArgumentException("Intents array length must be >= 1");
6437            }
6438            for (int i=0; i<intents.length; i++) {
6439                Intent intent = intents[i];
6440                if (intent != null) {
6441                    if (intent.hasFileDescriptors()) {
6442                        throw new IllegalArgumentException("File descriptors passed in Intent");
6443                    }
6444                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6445                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6446                        throw new IllegalArgumentException(
6447                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6448                    }
6449                    intents[i] = new Intent(intent);
6450                }
6451            }
6452            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6453                throw new IllegalArgumentException(
6454                        "Intent array length does not match resolvedTypes length");
6455            }
6456        }
6457        if (options != null) {
6458            if (options.hasFileDescriptors()) {
6459                throw new IllegalArgumentException("File descriptors passed in options");
6460            }
6461        }
6462
6463        synchronized(this) {
6464            int callingUid = Binder.getCallingUid();
6465            int origUserId = userId;
6466            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6467                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6468                    ALLOW_NON_FULL, "getIntentSender", null);
6469            if (origUserId == UserHandle.USER_CURRENT) {
6470                // We don't want to evaluate this until the pending intent is
6471                // actually executed.  However, we do want to always do the
6472                // security checking for it above.
6473                userId = UserHandle.USER_CURRENT;
6474            }
6475            try {
6476                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6477                    int uid = AppGlobals.getPackageManager()
6478                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6479                    if (!UserHandle.isSameApp(callingUid, uid)) {
6480                        String msg = "Permission Denial: getIntentSender() from pid="
6481                            + Binder.getCallingPid()
6482                            + ", uid=" + Binder.getCallingUid()
6483                            + ", (need uid=" + uid + ")"
6484                            + " is not allowed to send as package " + packageName;
6485                        Slog.w(TAG, msg);
6486                        throw new SecurityException(msg);
6487                    }
6488                }
6489
6490                return getIntentSenderLocked(type, packageName, callingUid, userId,
6491                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6492
6493            } catch (RemoteException e) {
6494                throw new SecurityException(e);
6495            }
6496        }
6497    }
6498
6499    IIntentSender getIntentSenderLocked(int type, String packageName,
6500            int callingUid, int userId, IBinder token, String resultWho,
6501            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6502            Bundle options) {
6503        if (DEBUG_MU)
6504            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6505        ActivityRecord activity = null;
6506        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6507            activity = ActivityRecord.isInStackLocked(token);
6508            if (activity == null) {
6509                return null;
6510            }
6511            if (activity.finishing) {
6512                return null;
6513            }
6514        }
6515
6516        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6517        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6518        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6519        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6520                |PendingIntent.FLAG_UPDATE_CURRENT);
6521
6522        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6523                type, packageName, activity, resultWho,
6524                requestCode, intents, resolvedTypes, flags, options, userId);
6525        WeakReference<PendingIntentRecord> ref;
6526        ref = mIntentSenderRecords.get(key);
6527        PendingIntentRecord rec = ref != null ? ref.get() : null;
6528        if (rec != null) {
6529            if (!cancelCurrent) {
6530                if (updateCurrent) {
6531                    if (rec.key.requestIntent != null) {
6532                        rec.key.requestIntent.replaceExtras(intents != null ?
6533                                intents[intents.length - 1] : null);
6534                    }
6535                    if (intents != null) {
6536                        intents[intents.length-1] = rec.key.requestIntent;
6537                        rec.key.allIntents = intents;
6538                        rec.key.allResolvedTypes = resolvedTypes;
6539                    } else {
6540                        rec.key.allIntents = null;
6541                        rec.key.allResolvedTypes = null;
6542                    }
6543                }
6544                return rec;
6545            }
6546            rec.canceled = true;
6547            mIntentSenderRecords.remove(key);
6548        }
6549        if (noCreate) {
6550            return rec;
6551        }
6552        rec = new PendingIntentRecord(this, key, callingUid);
6553        mIntentSenderRecords.put(key, rec.ref);
6554        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6555            if (activity.pendingResults == null) {
6556                activity.pendingResults
6557                        = new HashSet<WeakReference<PendingIntentRecord>>();
6558            }
6559            activity.pendingResults.add(rec.ref);
6560        }
6561        return rec;
6562    }
6563
6564    @Override
6565    public void cancelIntentSender(IIntentSender sender) {
6566        if (!(sender instanceof PendingIntentRecord)) {
6567            return;
6568        }
6569        synchronized(this) {
6570            PendingIntentRecord rec = (PendingIntentRecord)sender;
6571            try {
6572                int uid = AppGlobals.getPackageManager()
6573                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6574                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6575                    String msg = "Permission Denial: cancelIntentSender() from pid="
6576                        + Binder.getCallingPid()
6577                        + ", uid=" + Binder.getCallingUid()
6578                        + " is not allowed to cancel packges "
6579                        + rec.key.packageName;
6580                    Slog.w(TAG, msg);
6581                    throw new SecurityException(msg);
6582                }
6583            } catch (RemoteException e) {
6584                throw new SecurityException(e);
6585            }
6586            cancelIntentSenderLocked(rec, true);
6587        }
6588    }
6589
6590    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6591        rec.canceled = true;
6592        mIntentSenderRecords.remove(rec.key);
6593        if (cleanActivity && rec.key.activity != null) {
6594            rec.key.activity.pendingResults.remove(rec.ref);
6595        }
6596    }
6597
6598    @Override
6599    public String getPackageForIntentSender(IIntentSender pendingResult) {
6600        if (!(pendingResult instanceof PendingIntentRecord)) {
6601            return null;
6602        }
6603        try {
6604            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6605            return res.key.packageName;
6606        } catch (ClassCastException e) {
6607        }
6608        return null;
6609    }
6610
6611    @Override
6612    public int getUidForIntentSender(IIntentSender sender) {
6613        if (sender instanceof PendingIntentRecord) {
6614            try {
6615                PendingIntentRecord res = (PendingIntentRecord)sender;
6616                return res.uid;
6617            } catch (ClassCastException e) {
6618            }
6619        }
6620        return -1;
6621    }
6622
6623    @Override
6624    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6625        if (!(pendingResult instanceof PendingIntentRecord)) {
6626            return false;
6627        }
6628        try {
6629            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6630            if (res.key.allIntents == null) {
6631                return false;
6632            }
6633            for (int i=0; i<res.key.allIntents.length; i++) {
6634                Intent intent = res.key.allIntents[i];
6635                if (intent.getPackage() != null && intent.getComponent() != null) {
6636                    return false;
6637                }
6638            }
6639            return true;
6640        } catch (ClassCastException e) {
6641        }
6642        return false;
6643    }
6644
6645    @Override
6646    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6647        if (!(pendingResult instanceof PendingIntentRecord)) {
6648            return false;
6649        }
6650        try {
6651            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6652            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6653                return true;
6654            }
6655            return false;
6656        } catch (ClassCastException e) {
6657        }
6658        return false;
6659    }
6660
6661    @Override
6662    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6663        if (!(pendingResult instanceof PendingIntentRecord)) {
6664            return null;
6665        }
6666        try {
6667            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6668            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6669        } catch (ClassCastException e) {
6670        }
6671        return null;
6672    }
6673
6674    @Override
6675    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6676        if (!(pendingResult instanceof PendingIntentRecord)) {
6677            return null;
6678        }
6679        try {
6680            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6681            Intent intent = res.key.requestIntent;
6682            if (intent != null) {
6683                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6684                        || res.lastTagPrefix.equals(prefix))) {
6685                    return res.lastTag;
6686                }
6687                res.lastTagPrefix = prefix;
6688                StringBuilder sb = new StringBuilder(128);
6689                if (prefix != null) {
6690                    sb.append(prefix);
6691                }
6692                if (intent.getAction() != null) {
6693                    sb.append(intent.getAction());
6694                } else if (intent.getComponent() != null) {
6695                    intent.getComponent().appendShortString(sb);
6696                } else {
6697                    sb.append("?");
6698                }
6699                return res.lastTag = sb.toString();
6700            }
6701        } catch (ClassCastException e) {
6702        }
6703        return null;
6704    }
6705
6706    @Override
6707    public void setProcessLimit(int max) {
6708        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6709                "setProcessLimit()");
6710        synchronized (this) {
6711            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6712            mProcessLimitOverride = max;
6713        }
6714        trimApplications();
6715    }
6716
6717    @Override
6718    public int getProcessLimit() {
6719        synchronized (this) {
6720            return mProcessLimitOverride;
6721        }
6722    }
6723
6724    void foregroundTokenDied(ForegroundToken token) {
6725        synchronized (ActivityManagerService.this) {
6726            synchronized (mPidsSelfLocked) {
6727                ForegroundToken cur
6728                    = mForegroundProcesses.get(token.pid);
6729                if (cur != token) {
6730                    return;
6731                }
6732                mForegroundProcesses.remove(token.pid);
6733                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6734                if (pr == null) {
6735                    return;
6736                }
6737                pr.forcingToForeground = null;
6738                updateProcessForegroundLocked(pr, false, false);
6739            }
6740            updateOomAdjLocked();
6741        }
6742    }
6743
6744    @Override
6745    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6746        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6747                "setProcessForeground()");
6748        synchronized(this) {
6749            boolean changed = false;
6750
6751            synchronized (mPidsSelfLocked) {
6752                ProcessRecord pr = mPidsSelfLocked.get(pid);
6753                if (pr == null && isForeground) {
6754                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6755                    return;
6756                }
6757                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6758                if (oldToken != null) {
6759                    oldToken.token.unlinkToDeath(oldToken, 0);
6760                    mForegroundProcesses.remove(pid);
6761                    if (pr != null) {
6762                        pr.forcingToForeground = null;
6763                    }
6764                    changed = true;
6765                }
6766                if (isForeground && token != null) {
6767                    ForegroundToken newToken = new ForegroundToken() {
6768                        @Override
6769                        public void binderDied() {
6770                            foregroundTokenDied(this);
6771                        }
6772                    };
6773                    newToken.pid = pid;
6774                    newToken.token = token;
6775                    try {
6776                        token.linkToDeath(newToken, 0);
6777                        mForegroundProcesses.put(pid, newToken);
6778                        pr.forcingToForeground = token;
6779                        changed = true;
6780                    } catch (RemoteException e) {
6781                        // If the process died while doing this, we will later
6782                        // do the cleanup with the process death link.
6783                    }
6784                }
6785            }
6786
6787            if (changed) {
6788                updateOomAdjLocked();
6789            }
6790        }
6791    }
6792
6793    // =========================================================
6794    // PERMISSIONS
6795    // =========================================================
6796
6797    static class PermissionController extends IPermissionController.Stub {
6798        ActivityManagerService mActivityManagerService;
6799        PermissionController(ActivityManagerService activityManagerService) {
6800            mActivityManagerService = activityManagerService;
6801        }
6802
6803        @Override
6804        public boolean checkPermission(String permission, int pid, int uid) {
6805            return mActivityManagerService.checkPermission(permission, pid,
6806                    uid) == PackageManager.PERMISSION_GRANTED;
6807        }
6808    }
6809
6810    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6811        @Override
6812        public int checkComponentPermission(String permission, int pid, int uid,
6813                int owningUid, boolean exported) {
6814            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6815                    owningUid, exported);
6816        }
6817
6818        @Override
6819        public Object getAMSLock() {
6820            return ActivityManagerService.this;
6821        }
6822    }
6823
6824    /**
6825     * This can be called with or without the global lock held.
6826     */
6827    int checkComponentPermission(String permission, int pid, int uid,
6828            int owningUid, boolean exported) {
6829        // We might be performing an operation on behalf of an indirect binder
6830        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6831        // client identity accordingly before proceeding.
6832        Identity tlsIdentity = sCallerIdentity.get();
6833        if (tlsIdentity != null) {
6834            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6835                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6836            uid = tlsIdentity.uid;
6837            pid = tlsIdentity.pid;
6838        }
6839
6840        if (pid == MY_PID) {
6841            return PackageManager.PERMISSION_GRANTED;
6842        }
6843
6844        return ActivityManager.checkComponentPermission(permission, uid,
6845                owningUid, exported);
6846    }
6847
6848    /**
6849     * As the only public entry point for permissions checking, this method
6850     * can enforce the semantic that requesting a check on a null global
6851     * permission is automatically denied.  (Internally a null permission
6852     * string is used when calling {@link #checkComponentPermission} in cases
6853     * when only uid-based security is needed.)
6854     *
6855     * This can be called with or without the global lock held.
6856     */
6857    @Override
6858    public int checkPermission(String permission, int pid, int uid) {
6859        if (permission == null) {
6860            return PackageManager.PERMISSION_DENIED;
6861        }
6862        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6863    }
6864
6865    /**
6866     * Binder IPC calls go through the public entry point.
6867     * This can be called with or without the global lock held.
6868     */
6869    int checkCallingPermission(String permission) {
6870        return checkPermission(permission,
6871                Binder.getCallingPid(),
6872                UserHandle.getAppId(Binder.getCallingUid()));
6873    }
6874
6875    /**
6876     * This can be called with or without the global lock held.
6877     */
6878    void enforceCallingPermission(String permission, String func) {
6879        if (checkCallingPermission(permission)
6880                == PackageManager.PERMISSION_GRANTED) {
6881            return;
6882        }
6883
6884        String msg = "Permission Denial: " + func + " from pid="
6885                + Binder.getCallingPid()
6886                + ", uid=" + Binder.getCallingUid()
6887                + " requires " + permission;
6888        Slog.w(TAG, msg);
6889        throw new SecurityException(msg);
6890    }
6891
6892    /**
6893     * Determine if UID is holding permissions required to access {@link Uri} in
6894     * the given {@link ProviderInfo}. Final permission checking is always done
6895     * in {@link ContentProvider}.
6896     */
6897    private final boolean checkHoldingPermissionsLocked(
6898            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6899        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6900                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6901        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6902            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6903                    != PERMISSION_GRANTED) {
6904                return false;
6905            }
6906        }
6907        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6908    }
6909
6910    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6911            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6912        if (pi.applicationInfo.uid == uid) {
6913            return true;
6914        } else if (!pi.exported) {
6915            return false;
6916        }
6917
6918        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6919        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6920        try {
6921            // check if target holds top-level <provider> permissions
6922            if (!readMet && pi.readPermission != null && considerUidPermissions
6923                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6924                readMet = true;
6925            }
6926            if (!writeMet && pi.writePermission != null && considerUidPermissions
6927                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6928                writeMet = true;
6929            }
6930
6931            // track if unprotected read/write is allowed; any denied
6932            // <path-permission> below removes this ability
6933            boolean allowDefaultRead = pi.readPermission == null;
6934            boolean allowDefaultWrite = pi.writePermission == null;
6935
6936            // check if target holds any <path-permission> that match uri
6937            final PathPermission[] pps = pi.pathPermissions;
6938            if (pps != null) {
6939                final String path = grantUri.uri.getPath();
6940                int i = pps.length;
6941                while (i > 0 && (!readMet || !writeMet)) {
6942                    i--;
6943                    PathPermission pp = pps[i];
6944                    if (pp.match(path)) {
6945                        if (!readMet) {
6946                            final String pprperm = pp.getReadPermission();
6947                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6948                                    + pprperm + " for " + pp.getPath()
6949                                    + ": match=" + pp.match(path)
6950                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6951                            if (pprperm != null) {
6952                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6953                                        == PERMISSION_GRANTED) {
6954                                    readMet = true;
6955                                } else {
6956                                    allowDefaultRead = false;
6957                                }
6958                            }
6959                        }
6960                        if (!writeMet) {
6961                            final String ppwperm = pp.getWritePermission();
6962                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6963                                    + ppwperm + " for " + pp.getPath()
6964                                    + ": match=" + pp.match(path)
6965                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6966                            if (ppwperm != null) {
6967                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6968                                        == PERMISSION_GRANTED) {
6969                                    writeMet = true;
6970                                } else {
6971                                    allowDefaultWrite = false;
6972                                }
6973                            }
6974                        }
6975                    }
6976                }
6977            }
6978
6979            // grant unprotected <provider> read/write, if not blocked by
6980            // <path-permission> above
6981            if (allowDefaultRead) readMet = true;
6982            if (allowDefaultWrite) writeMet = true;
6983
6984        } catch (RemoteException e) {
6985            return false;
6986        }
6987
6988        return readMet && writeMet;
6989    }
6990
6991    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6992        ProviderInfo pi = null;
6993        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6994        if (cpr != null) {
6995            pi = cpr.info;
6996        } else {
6997            try {
6998                pi = AppGlobals.getPackageManager().resolveContentProvider(
6999                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7000            } catch (RemoteException ex) {
7001            }
7002        }
7003        return pi;
7004    }
7005
7006    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7007        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7008        if (targetUris != null) {
7009            return targetUris.get(grantUri);
7010        }
7011        return null;
7012    }
7013
7014    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7015            String targetPkg, int targetUid, GrantUri grantUri) {
7016        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7017        if (targetUris == null) {
7018            targetUris = Maps.newArrayMap();
7019            mGrantedUriPermissions.put(targetUid, targetUris);
7020        }
7021
7022        UriPermission perm = targetUris.get(grantUri);
7023        if (perm == null) {
7024            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7025            targetUris.put(grantUri, perm);
7026        }
7027
7028        return perm;
7029    }
7030
7031    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7032            final int modeFlags) {
7033        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7034        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7035                : UriPermission.STRENGTH_OWNED;
7036
7037        // Root gets to do everything.
7038        if (uid == 0) {
7039            return true;
7040        }
7041
7042        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7043        if (perms == null) return false;
7044
7045        // First look for exact match
7046        final UriPermission exactPerm = perms.get(grantUri);
7047        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7048            return true;
7049        }
7050
7051        // No exact match, look for prefixes
7052        final int N = perms.size();
7053        for (int i = 0; i < N; i++) {
7054            final UriPermission perm = perms.valueAt(i);
7055            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7056                    && perm.getStrength(modeFlags) >= minStrength) {
7057                return true;
7058            }
7059        }
7060
7061        return false;
7062    }
7063
7064    /**
7065     * @param uri This uri must NOT contain an embedded userId.
7066     * @param userId The userId in which the uri is to be resolved.
7067     */
7068    @Override
7069    public int checkUriPermission(Uri uri, int pid, int uid,
7070            final int modeFlags, int userId) {
7071        enforceNotIsolatedCaller("checkUriPermission");
7072
7073        // Another redirected-binder-call permissions check as in
7074        // {@link checkComponentPermission}.
7075        Identity tlsIdentity = sCallerIdentity.get();
7076        if (tlsIdentity != null) {
7077            uid = tlsIdentity.uid;
7078            pid = tlsIdentity.pid;
7079        }
7080
7081        // Our own process gets to do everything.
7082        if (pid == MY_PID) {
7083            return PackageManager.PERMISSION_GRANTED;
7084        }
7085        synchronized (this) {
7086            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7087                    ? PackageManager.PERMISSION_GRANTED
7088                    : PackageManager.PERMISSION_DENIED;
7089        }
7090    }
7091
7092    /**
7093     * Check if the targetPkg can be granted permission to access uri by
7094     * the callingUid using the given modeFlags.  Throws a security exception
7095     * if callingUid is not allowed to do this.  Returns the uid of the target
7096     * if the URI permission grant should be performed; returns -1 if it is not
7097     * needed (for example targetPkg already has permission to access the URI).
7098     * If you already know the uid of the target, you can supply it in
7099     * lastTargetUid else set that to -1.
7100     */
7101    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7102            final int modeFlags, int lastTargetUid) {
7103        if (!Intent.isAccessUriMode(modeFlags)) {
7104            return -1;
7105        }
7106
7107        if (targetPkg != null) {
7108            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7109                    "Checking grant " + targetPkg + " permission to " + grantUri);
7110        }
7111
7112        final IPackageManager pm = AppGlobals.getPackageManager();
7113
7114        // If this is not a content: uri, we can't do anything with it.
7115        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7116            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7117                    "Can't grant URI permission for non-content URI: " + grantUri);
7118            return -1;
7119        }
7120
7121        final String authority = grantUri.uri.getAuthority();
7122        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7123        if (pi == null) {
7124            Slog.w(TAG, "No content provider found for permission check: " +
7125                    grantUri.uri.toSafeString());
7126            return -1;
7127        }
7128
7129        int targetUid = lastTargetUid;
7130        if (targetUid < 0 && targetPkg != null) {
7131            try {
7132                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7133                if (targetUid < 0) {
7134                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7135                            "Can't grant URI permission no uid for: " + targetPkg);
7136                    return -1;
7137                }
7138            } catch (RemoteException ex) {
7139                return -1;
7140            }
7141        }
7142
7143        if (targetUid >= 0) {
7144            // First...  does the target actually need this permission?
7145            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7146                // No need to grant the target this permission.
7147                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7148                        "Target " + targetPkg + " already has full permission to " + grantUri);
7149                return -1;
7150            }
7151        } else {
7152            // First...  there is no target package, so can anyone access it?
7153            boolean allowed = pi.exported;
7154            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7155                if (pi.readPermission != null) {
7156                    allowed = false;
7157                }
7158            }
7159            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7160                if (pi.writePermission != null) {
7161                    allowed = false;
7162                }
7163            }
7164            if (allowed) {
7165                return -1;
7166            }
7167        }
7168
7169        /* There is a special cross user grant if:
7170         * - The target is on another user.
7171         * - Apps on the current user can access the uri without any uid permissions.
7172         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7173         * grant uri permissions.
7174         */
7175        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7176                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7177                modeFlags, false /*without considering the uid permissions*/);
7178
7179        // Second...  is the provider allowing granting of URI permissions?
7180        if (!specialCrossUserGrant) {
7181            if (!pi.grantUriPermissions) {
7182                throw new SecurityException("Provider " + pi.packageName
7183                        + "/" + pi.name
7184                        + " does not allow granting of Uri permissions (uri "
7185                        + grantUri + ")");
7186            }
7187            if (pi.uriPermissionPatterns != null) {
7188                final int N = pi.uriPermissionPatterns.length;
7189                boolean allowed = false;
7190                for (int i=0; i<N; i++) {
7191                    if (pi.uriPermissionPatterns[i] != null
7192                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7193                        allowed = true;
7194                        break;
7195                    }
7196                }
7197                if (!allowed) {
7198                    throw new SecurityException("Provider " + pi.packageName
7199                            + "/" + pi.name
7200                            + " does not allow granting of permission to path of Uri "
7201                            + grantUri);
7202                }
7203            }
7204        }
7205
7206        // Third...  does the caller itself have permission to access
7207        // this uri?
7208        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7209            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7210                // Require they hold a strong enough Uri permission
7211                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7212                    throw new SecurityException("Uid " + callingUid
7213                            + " does not have permission to uri " + grantUri);
7214                }
7215            }
7216        }
7217        return targetUid;
7218    }
7219
7220    /**
7221     * @param uri This uri must NOT contain an embedded userId.
7222     * @param userId The userId in which the uri is to be resolved.
7223     */
7224    @Override
7225    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7226            final int modeFlags, int userId) {
7227        enforceNotIsolatedCaller("checkGrantUriPermission");
7228        synchronized(this) {
7229            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7230                    new GrantUri(userId, uri, false), modeFlags, -1);
7231        }
7232    }
7233
7234    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7235            final int modeFlags, UriPermissionOwner owner) {
7236        if (!Intent.isAccessUriMode(modeFlags)) {
7237            return;
7238        }
7239
7240        // So here we are: the caller has the assumed permission
7241        // to the uri, and the target doesn't.  Let's now give this to
7242        // the target.
7243
7244        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7245                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7246
7247        final String authority = grantUri.uri.getAuthority();
7248        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7249        if (pi == null) {
7250            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7251            return;
7252        }
7253
7254        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7255            grantUri.prefix = true;
7256        }
7257        final UriPermission perm = findOrCreateUriPermissionLocked(
7258                pi.packageName, targetPkg, targetUid, grantUri);
7259        perm.grantModes(modeFlags, owner);
7260    }
7261
7262    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7263            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7264        if (targetPkg == null) {
7265            throw new NullPointerException("targetPkg");
7266        }
7267        int targetUid;
7268        final IPackageManager pm = AppGlobals.getPackageManager();
7269        try {
7270            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7271        } catch (RemoteException ex) {
7272            return;
7273        }
7274
7275        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7276                targetUid);
7277        if (targetUid < 0) {
7278            return;
7279        }
7280
7281        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7282                owner);
7283    }
7284
7285    static class NeededUriGrants extends ArrayList<GrantUri> {
7286        final String targetPkg;
7287        final int targetUid;
7288        final int flags;
7289
7290        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7291            this.targetPkg = targetPkg;
7292            this.targetUid = targetUid;
7293            this.flags = flags;
7294        }
7295    }
7296
7297    /**
7298     * Like checkGrantUriPermissionLocked, but takes an Intent.
7299     */
7300    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7301            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7302        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7303                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7304                + " clip=" + (intent != null ? intent.getClipData() : null)
7305                + " from " + intent + "; flags=0x"
7306                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7307
7308        if (targetPkg == null) {
7309            throw new NullPointerException("targetPkg");
7310        }
7311
7312        if (intent == null) {
7313            return null;
7314        }
7315        Uri data = intent.getData();
7316        ClipData clip = intent.getClipData();
7317        if (data == null && clip == null) {
7318            return null;
7319        }
7320        // Default userId for uris in the intent (if they don't specify it themselves)
7321        int contentUserHint = intent.getContentUserHint();
7322        if (contentUserHint == UserHandle.USER_CURRENT) {
7323            contentUserHint = UserHandle.getUserId(callingUid);
7324        }
7325        final IPackageManager pm = AppGlobals.getPackageManager();
7326        int targetUid;
7327        if (needed != null) {
7328            targetUid = needed.targetUid;
7329        } else {
7330            try {
7331                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7332            } catch (RemoteException ex) {
7333                return null;
7334            }
7335            if (targetUid < 0) {
7336                if (DEBUG_URI_PERMISSION) {
7337                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7338                            + " on user " + targetUserId);
7339                }
7340                return null;
7341            }
7342        }
7343        if (data != null) {
7344            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7345            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7346                    targetUid);
7347            if (targetUid > 0) {
7348                if (needed == null) {
7349                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7350                }
7351                needed.add(grantUri);
7352            }
7353        }
7354        if (clip != null) {
7355            for (int i=0; i<clip.getItemCount(); i++) {
7356                Uri uri = clip.getItemAt(i).getUri();
7357                if (uri != null) {
7358                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7359                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7360                            targetUid);
7361                    if (targetUid > 0) {
7362                        if (needed == null) {
7363                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7364                        }
7365                        needed.add(grantUri);
7366                    }
7367                } else {
7368                    Intent clipIntent = clip.getItemAt(i).getIntent();
7369                    if (clipIntent != null) {
7370                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7371                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7372                        if (newNeeded != null) {
7373                            needed = newNeeded;
7374                        }
7375                    }
7376                }
7377            }
7378        }
7379
7380        return needed;
7381    }
7382
7383    /**
7384     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7385     */
7386    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7387            UriPermissionOwner owner) {
7388        if (needed != null) {
7389            for (int i=0; i<needed.size(); i++) {
7390                GrantUri grantUri = needed.get(i);
7391                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7392                        grantUri, needed.flags, owner);
7393            }
7394        }
7395    }
7396
7397    void grantUriPermissionFromIntentLocked(int callingUid,
7398            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7399        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7400                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7401        if (needed == null) {
7402            return;
7403        }
7404
7405        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7406    }
7407
7408    /**
7409     * @param uri This uri must NOT contain an embedded userId.
7410     * @param userId The userId in which the uri is to be resolved.
7411     */
7412    @Override
7413    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7414            final int modeFlags, int userId) {
7415        enforceNotIsolatedCaller("grantUriPermission");
7416        GrantUri grantUri = new GrantUri(userId, uri, false);
7417        synchronized(this) {
7418            final ProcessRecord r = getRecordForAppLocked(caller);
7419            if (r == null) {
7420                throw new SecurityException("Unable to find app for caller "
7421                        + caller
7422                        + " when granting permission to uri " + grantUri);
7423            }
7424            if (targetPkg == null) {
7425                throw new IllegalArgumentException("null target");
7426            }
7427            if (grantUri == null) {
7428                throw new IllegalArgumentException("null uri");
7429            }
7430
7431            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7432                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7433                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7434                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7435
7436            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7437                    UserHandle.getUserId(r.uid));
7438        }
7439    }
7440
7441    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7442        if (perm.modeFlags == 0) {
7443            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7444                    perm.targetUid);
7445            if (perms != null) {
7446                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7447                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7448
7449                perms.remove(perm.uri);
7450                if (perms.isEmpty()) {
7451                    mGrantedUriPermissions.remove(perm.targetUid);
7452                }
7453            }
7454        }
7455    }
7456
7457    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7458        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7459
7460        final IPackageManager pm = AppGlobals.getPackageManager();
7461        final String authority = grantUri.uri.getAuthority();
7462        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7463        if (pi == null) {
7464            Slog.w(TAG, "No content provider found for permission revoke: "
7465                    + grantUri.toSafeString());
7466            return;
7467        }
7468
7469        // Does the caller have this permission on the URI?
7470        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7471            // Right now, if you are not the original owner of the permission,
7472            // you are not allowed to revoke it.
7473            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7474                throw new SecurityException("Uid " + callingUid
7475                        + " does not have permission to uri " + grantUri);
7476            //}
7477        }
7478
7479        boolean persistChanged = false;
7480
7481        // Go through all of the permissions and remove any that match.
7482        int N = mGrantedUriPermissions.size();
7483        for (int i = 0; i < N; i++) {
7484            final int targetUid = mGrantedUriPermissions.keyAt(i);
7485            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7486
7487            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7488                final UriPermission perm = it.next();
7489                if (perm.uri.sourceUserId == grantUri.sourceUserId
7490                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7491                    if (DEBUG_URI_PERMISSION)
7492                        Slog.v(TAG,
7493                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7494                    persistChanged |= perm.revokeModes(
7495                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7496                    if (perm.modeFlags == 0) {
7497                        it.remove();
7498                    }
7499                }
7500            }
7501
7502            if (perms.isEmpty()) {
7503                mGrantedUriPermissions.remove(targetUid);
7504                N--;
7505                i--;
7506            }
7507        }
7508
7509        if (persistChanged) {
7510            schedulePersistUriGrants();
7511        }
7512    }
7513
7514    /**
7515     * @param uri This uri must NOT contain an embedded userId.
7516     * @param userId The userId in which the uri is to be resolved.
7517     */
7518    @Override
7519    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7520            int userId) {
7521        enforceNotIsolatedCaller("revokeUriPermission");
7522        synchronized(this) {
7523            final ProcessRecord r = getRecordForAppLocked(caller);
7524            if (r == null) {
7525                throw new SecurityException("Unable to find app for caller "
7526                        + caller
7527                        + " when revoking permission to uri " + uri);
7528            }
7529            if (uri == null) {
7530                Slog.w(TAG, "revokeUriPermission: null uri");
7531                return;
7532            }
7533
7534            if (!Intent.isAccessUriMode(modeFlags)) {
7535                return;
7536            }
7537
7538            final IPackageManager pm = AppGlobals.getPackageManager();
7539            final String authority = uri.getAuthority();
7540            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7541            if (pi == null) {
7542                Slog.w(TAG, "No content provider found for permission revoke: "
7543                        + uri.toSafeString());
7544                return;
7545            }
7546
7547            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7548        }
7549    }
7550
7551    /**
7552     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7553     * given package.
7554     *
7555     * @param packageName Package name to match, or {@code null} to apply to all
7556     *            packages.
7557     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7558     *            to all users.
7559     * @param persistable If persistable grants should be removed.
7560     */
7561    private void removeUriPermissionsForPackageLocked(
7562            String packageName, int userHandle, boolean persistable) {
7563        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7564            throw new IllegalArgumentException("Must narrow by either package or user");
7565        }
7566
7567        boolean persistChanged = false;
7568
7569        int N = mGrantedUriPermissions.size();
7570        for (int i = 0; i < N; i++) {
7571            final int targetUid = mGrantedUriPermissions.keyAt(i);
7572            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7573
7574            // Only inspect grants matching user
7575            if (userHandle == UserHandle.USER_ALL
7576                    || userHandle == UserHandle.getUserId(targetUid)) {
7577                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7578                    final UriPermission perm = it.next();
7579
7580                    // Only inspect grants matching package
7581                    if (packageName == null || perm.sourcePkg.equals(packageName)
7582                            || perm.targetPkg.equals(packageName)) {
7583                        persistChanged |= perm.revokeModes(
7584                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7585
7586                        // Only remove when no modes remain; any persisted grants
7587                        // will keep this alive.
7588                        if (perm.modeFlags == 0) {
7589                            it.remove();
7590                        }
7591                    }
7592                }
7593
7594                if (perms.isEmpty()) {
7595                    mGrantedUriPermissions.remove(targetUid);
7596                    N--;
7597                    i--;
7598                }
7599            }
7600        }
7601
7602        if (persistChanged) {
7603            schedulePersistUriGrants();
7604        }
7605    }
7606
7607    @Override
7608    public IBinder newUriPermissionOwner(String name) {
7609        enforceNotIsolatedCaller("newUriPermissionOwner");
7610        synchronized(this) {
7611            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7612            return owner.getExternalTokenLocked();
7613        }
7614    }
7615
7616    /**
7617     * @param uri This uri must NOT contain an embedded userId.
7618     * @param sourceUserId The userId in which the uri is to be resolved.
7619     * @param targetUserId The userId of the app that receives the grant.
7620     */
7621    @Override
7622    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7623            final int modeFlags, int sourceUserId, int targetUserId) {
7624        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7625                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7626        synchronized(this) {
7627            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7628            if (owner == null) {
7629                throw new IllegalArgumentException("Unknown owner: " + token);
7630            }
7631            if (fromUid != Binder.getCallingUid()) {
7632                if (Binder.getCallingUid() != Process.myUid()) {
7633                    // Only system code can grant URI permissions on behalf
7634                    // of other users.
7635                    throw new SecurityException("nice try");
7636                }
7637            }
7638            if (targetPkg == null) {
7639                throw new IllegalArgumentException("null target");
7640            }
7641            if (uri == null) {
7642                throw new IllegalArgumentException("null uri");
7643            }
7644
7645            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7646                    modeFlags, owner, targetUserId);
7647        }
7648    }
7649
7650    /**
7651     * @param uri This uri must NOT contain an embedded userId.
7652     * @param userId The userId in which the uri is to be resolved.
7653     */
7654    @Override
7655    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7656        synchronized(this) {
7657            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7658            if (owner == null) {
7659                throw new IllegalArgumentException("Unknown owner: " + token);
7660            }
7661
7662            if (uri == null) {
7663                owner.removeUriPermissionsLocked(mode);
7664            } else {
7665                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7666            }
7667        }
7668    }
7669
7670    private void schedulePersistUriGrants() {
7671        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7672            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7673                    10 * DateUtils.SECOND_IN_MILLIS);
7674        }
7675    }
7676
7677    private void writeGrantedUriPermissions() {
7678        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7679
7680        // Snapshot permissions so we can persist without lock
7681        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7682        synchronized (this) {
7683            final int size = mGrantedUriPermissions.size();
7684            for (int i = 0; i < size; i++) {
7685                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7686                for (UriPermission perm : perms.values()) {
7687                    if (perm.persistedModeFlags != 0) {
7688                        persist.add(perm.snapshot());
7689                    }
7690                }
7691            }
7692        }
7693
7694        FileOutputStream fos = null;
7695        try {
7696            fos = mGrantFile.startWrite();
7697
7698            XmlSerializer out = new FastXmlSerializer();
7699            out.setOutput(fos, "utf-8");
7700            out.startDocument(null, true);
7701            out.startTag(null, TAG_URI_GRANTS);
7702            for (UriPermission.Snapshot perm : persist) {
7703                out.startTag(null, TAG_URI_GRANT);
7704                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7705                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7706                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7707                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7708                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7709                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7710                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7711                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7712                out.endTag(null, TAG_URI_GRANT);
7713            }
7714            out.endTag(null, TAG_URI_GRANTS);
7715            out.endDocument();
7716
7717            mGrantFile.finishWrite(fos);
7718        } catch (IOException e) {
7719            if (fos != null) {
7720                mGrantFile.failWrite(fos);
7721            }
7722        }
7723    }
7724
7725    private void readGrantedUriPermissionsLocked() {
7726        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7727
7728        final long now = System.currentTimeMillis();
7729
7730        FileInputStream fis = null;
7731        try {
7732            fis = mGrantFile.openRead();
7733            final XmlPullParser in = Xml.newPullParser();
7734            in.setInput(fis, null);
7735
7736            int type;
7737            while ((type = in.next()) != END_DOCUMENT) {
7738                final String tag = in.getName();
7739                if (type == START_TAG) {
7740                    if (TAG_URI_GRANT.equals(tag)) {
7741                        final int sourceUserId;
7742                        final int targetUserId;
7743                        final int userHandle = readIntAttribute(in,
7744                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7745                        if (userHandle != UserHandle.USER_NULL) {
7746                            // For backwards compatibility.
7747                            sourceUserId = userHandle;
7748                            targetUserId = userHandle;
7749                        } else {
7750                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7751                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7752                        }
7753                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7754                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7755                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7756                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7757                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7758                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7759
7760                        // Sanity check that provider still belongs to source package
7761                        final ProviderInfo pi = getProviderInfoLocked(
7762                                uri.getAuthority(), sourceUserId);
7763                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7764                            int targetUid = -1;
7765                            try {
7766                                targetUid = AppGlobals.getPackageManager()
7767                                        .getPackageUid(targetPkg, targetUserId);
7768                            } catch (RemoteException e) {
7769                            }
7770                            if (targetUid != -1) {
7771                                final UriPermission perm = findOrCreateUriPermissionLocked(
7772                                        sourcePkg, targetPkg, targetUid,
7773                                        new GrantUri(sourceUserId, uri, prefix));
7774                                perm.initPersistedModes(modeFlags, createdTime);
7775                            }
7776                        } else {
7777                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7778                                    + " but instead found " + pi);
7779                        }
7780                    }
7781                }
7782            }
7783        } catch (FileNotFoundException e) {
7784            // Missing grants is okay
7785        } catch (IOException e) {
7786            Log.wtf(TAG, "Failed reading Uri grants", e);
7787        } catch (XmlPullParserException e) {
7788            Log.wtf(TAG, "Failed reading Uri grants", e);
7789        } finally {
7790            IoUtils.closeQuietly(fis);
7791        }
7792    }
7793
7794    /**
7795     * @param uri This uri must NOT contain an embedded userId.
7796     * @param userId The userId in which the uri is to be resolved.
7797     */
7798    @Override
7799    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7800        enforceNotIsolatedCaller("takePersistableUriPermission");
7801
7802        Preconditions.checkFlagsArgument(modeFlags,
7803                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7804
7805        synchronized (this) {
7806            final int callingUid = Binder.getCallingUid();
7807            boolean persistChanged = false;
7808            GrantUri grantUri = new GrantUri(userId, uri, false);
7809
7810            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7811                    new GrantUri(userId, uri, false));
7812            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7813                    new GrantUri(userId, uri, true));
7814
7815            final boolean exactValid = (exactPerm != null)
7816                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7817            final boolean prefixValid = (prefixPerm != null)
7818                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7819
7820            if (!(exactValid || prefixValid)) {
7821                throw new SecurityException("No persistable permission grants found for UID "
7822                        + callingUid + " and Uri " + grantUri.toSafeString());
7823            }
7824
7825            if (exactValid) {
7826                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7827            }
7828            if (prefixValid) {
7829                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7830            }
7831
7832            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7833
7834            if (persistChanged) {
7835                schedulePersistUriGrants();
7836            }
7837        }
7838    }
7839
7840    /**
7841     * @param uri This uri must NOT contain an embedded userId.
7842     * @param userId The userId in which the uri is to be resolved.
7843     */
7844    @Override
7845    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7846        enforceNotIsolatedCaller("releasePersistableUriPermission");
7847
7848        Preconditions.checkFlagsArgument(modeFlags,
7849                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7850
7851        synchronized (this) {
7852            final int callingUid = Binder.getCallingUid();
7853            boolean persistChanged = false;
7854
7855            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7856                    new GrantUri(userId, uri, false));
7857            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7858                    new GrantUri(userId, uri, true));
7859            if (exactPerm == null && prefixPerm == null) {
7860                throw new SecurityException("No permission grants found for UID " + callingUid
7861                        + " and Uri " + uri.toSafeString());
7862            }
7863
7864            if (exactPerm != null) {
7865                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7866                removeUriPermissionIfNeededLocked(exactPerm);
7867            }
7868            if (prefixPerm != null) {
7869                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7870                removeUriPermissionIfNeededLocked(prefixPerm);
7871            }
7872
7873            if (persistChanged) {
7874                schedulePersistUriGrants();
7875            }
7876        }
7877    }
7878
7879    /**
7880     * Prune any older {@link UriPermission} for the given UID until outstanding
7881     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7882     *
7883     * @return if any mutations occured that require persisting.
7884     */
7885    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7886        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7887        if (perms == null) return false;
7888        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7889
7890        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7891        for (UriPermission perm : perms.values()) {
7892            if (perm.persistedModeFlags != 0) {
7893                persisted.add(perm);
7894            }
7895        }
7896
7897        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7898        if (trimCount <= 0) return false;
7899
7900        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7901        for (int i = 0; i < trimCount; i++) {
7902            final UriPermission perm = persisted.get(i);
7903
7904            if (DEBUG_URI_PERMISSION) {
7905                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7906            }
7907
7908            perm.releasePersistableModes(~0);
7909            removeUriPermissionIfNeededLocked(perm);
7910        }
7911
7912        return true;
7913    }
7914
7915    @Override
7916    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7917            String packageName, boolean incoming) {
7918        enforceNotIsolatedCaller("getPersistedUriPermissions");
7919        Preconditions.checkNotNull(packageName, "packageName");
7920
7921        final int callingUid = Binder.getCallingUid();
7922        final IPackageManager pm = AppGlobals.getPackageManager();
7923        try {
7924            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7925            if (packageUid != callingUid) {
7926                throw new SecurityException(
7927                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7928            }
7929        } catch (RemoteException e) {
7930            throw new SecurityException("Failed to verify package name ownership");
7931        }
7932
7933        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7934        synchronized (this) {
7935            if (incoming) {
7936                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7937                        callingUid);
7938                if (perms == null) {
7939                    Slog.w(TAG, "No permission grants found for " + packageName);
7940                } else {
7941                    for (UriPermission perm : perms.values()) {
7942                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7943                            result.add(perm.buildPersistedPublicApiObject());
7944                        }
7945                    }
7946                }
7947            } else {
7948                final int size = mGrantedUriPermissions.size();
7949                for (int i = 0; i < size; i++) {
7950                    final ArrayMap<GrantUri, UriPermission> perms =
7951                            mGrantedUriPermissions.valueAt(i);
7952                    for (UriPermission perm : perms.values()) {
7953                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7954                            result.add(perm.buildPersistedPublicApiObject());
7955                        }
7956                    }
7957                }
7958            }
7959        }
7960        return new ParceledListSlice<android.content.UriPermission>(result);
7961    }
7962
7963    @Override
7964    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7965        synchronized (this) {
7966            ProcessRecord app =
7967                who != null ? getRecordForAppLocked(who) : null;
7968            if (app == null) return;
7969
7970            Message msg = Message.obtain();
7971            msg.what = WAIT_FOR_DEBUGGER_MSG;
7972            msg.obj = app;
7973            msg.arg1 = waiting ? 1 : 0;
7974            mHandler.sendMessage(msg);
7975        }
7976    }
7977
7978    @Override
7979    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7980        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7981        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7982        outInfo.availMem = Process.getFreeMemory();
7983        outInfo.totalMem = Process.getTotalMemory();
7984        outInfo.threshold = homeAppMem;
7985        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7986        outInfo.hiddenAppThreshold = cachedAppMem;
7987        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7988                ProcessList.SERVICE_ADJ);
7989        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7990                ProcessList.VISIBLE_APP_ADJ);
7991        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7992                ProcessList.FOREGROUND_APP_ADJ);
7993    }
7994
7995    // =========================================================
7996    // TASK MANAGEMENT
7997    // =========================================================
7998
7999    @Override
8000    public List<IAppTask> getAppTasks(String callingPackage) {
8001        int callingUid = Binder.getCallingUid();
8002        long ident = Binder.clearCallingIdentity();
8003
8004        synchronized(this) {
8005            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8006            try {
8007                if (localLOGV) Slog.v(TAG, "getAppTasks");
8008
8009                final int N = mRecentTasks.size();
8010                for (int i = 0; i < N; i++) {
8011                    TaskRecord tr = mRecentTasks.get(i);
8012                    // Skip tasks that do not match the caller.  We don't need to verify
8013                    // callingPackage, because we are also limiting to callingUid and know
8014                    // that will limit to the correct security sandbox.
8015                    if (tr.effectiveUid != callingUid) {
8016                        continue;
8017                    }
8018                    Intent intent = tr.getBaseIntent();
8019                    if (intent == null ||
8020                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8021                        continue;
8022                    }
8023                    ActivityManager.RecentTaskInfo taskInfo =
8024                            createRecentTaskInfoFromTaskRecord(tr);
8025                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8026                    list.add(taskImpl);
8027                }
8028            } finally {
8029                Binder.restoreCallingIdentity(ident);
8030            }
8031            return list;
8032        }
8033    }
8034
8035    @Override
8036    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8037        final int callingUid = Binder.getCallingUid();
8038        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8039
8040        synchronized(this) {
8041            if (localLOGV) Slog.v(
8042                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8043
8044            final boolean allowed = checkCallingPermission(
8045                    android.Manifest.permission.GET_TASKS)
8046                    == PackageManager.PERMISSION_GRANTED;
8047            if (!allowed) {
8048                Slog.w(TAG, "getTasks: caller " + callingUid
8049                        + " does not hold GET_TASKS; limiting output");
8050            }
8051
8052            // TODO: Improve with MRU list from all ActivityStacks.
8053            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8054        }
8055
8056        return list;
8057    }
8058
8059    TaskRecord getMostRecentTask() {
8060        return mRecentTasks.get(0);
8061    }
8062
8063    /**
8064     * Creates a new RecentTaskInfo from a TaskRecord.
8065     */
8066    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8067        // Update the task description to reflect any changes in the task stack
8068        tr.updateTaskDescription();
8069
8070        // Compose the recent task info
8071        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8072        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8073        rti.persistentId = tr.taskId;
8074        rti.baseIntent = new Intent(tr.getBaseIntent());
8075        rti.origActivity = tr.origActivity;
8076        rti.description = tr.lastDescription;
8077        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8078        rti.userId = tr.userId;
8079        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8080        rti.firstActiveTime = tr.firstActiveTime;
8081        rti.lastActiveTime = tr.lastActiveTime;
8082        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8083        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8084        return rti;
8085    }
8086
8087    @Override
8088    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8089        final int callingUid = Binder.getCallingUid();
8090        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8091                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8092
8093        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8094        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8095        synchronized (this) {
8096            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8097                    == PackageManager.PERMISSION_GRANTED;
8098            if (!allowed) {
8099                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8100                        + " does not hold GET_TASKS; limiting output");
8101            }
8102            final boolean detailed = checkCallingPermission(
8103                    android.Manifest.permission.GET_DETAILED_TASKS)
8104                    == PackageManager.PERMISSION_GRANTED;
8105
8106            final int N = mRecentTasks.size();
8107            ArrayList<ActivityManager.RecentTaskInfo> res
8108                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8109                            maxNum < N ? maxNum : N);
8110
8111            final Set<Integer> includedUsers;
8112            if (includeProfiles) {
8113                includedUsers = getProfileIdsLocked(userId);
8114            } else {
8115                includedUsers = new HashSet<Integer>();
8116            }
8117            includedUsers.add(Integer.valueOf(userId));
8118
8119            for (int i=0; i<N && maxNum > 0; i++) {
8120                TaskRecord tr = mRecentTasks.get(i);
8121                // Only add calling user or related users recent tasks
8122                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8123                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8124                    continue;
8125                }
8126
8127                // Return the entry if desired by the caller.  We always return
8128                // the first entry, because callers always expect this to be the
8129                // foreground app.  We may filter others if the caller has
8130                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8131                // we should exclude the entry.
8132
8133                if (i == 0
8134                        || withExcluded
8135                        || (tr.intent == null)
8136                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8137                                == 0)) {
8138                    if (!allowed) {
8139                        // If the caller doesn't have the GET_TASKS permission, then only
8140                        // allow them to see a small subset of tasks -- their own and home.
8141                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8142                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8143                            continue;
8144                        }
8145                    }
8146                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8147                        if (tr.stack != null && tr.stack.isHomeStack()) {
8148                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8149                            continue;
8150                        }
8151                    }
8152                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8153                        // Don't include auto remove tasks that are finished or finishing.
8154                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8155                                + tr);
8156                        continue;
8157                    }
8158                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8159                            && !tr.isAvailable) {
8160                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8161                        continue;
8162                    }
8163
8164                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8165                    if (!detailed) {
8166                        rti.baseIntent.replaceExtras((Bundle)null);
8167                    }
8168
8169                    res.add(rti);
8170                    maxNum--;
8171                }
8172            }
8173            return res;
8174        }
8175    }
8176
8177    private TaskRecord recentTaskForIdLocked(int id) {
8178        final int N = mRecentTasks.size();
8179            for (int i=0; i<N; i++) {
8180                TaskRecord tr = mRecentTasks.get(i);
8181                if (tr.taskId == id) {
8182                    return tr;
8183                }
8184            }
8185            return null;
8186    }
8187
8188    @Override
8189    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8190        synchronized (this) {
8191            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8192                    "getTaskThumbnail()");
8193            TaskRecord tr = recentTaskForIdLocked(id);
8194            if (tr != null) {
8195                return tr.getTaskThumbnailLocked();
8196            }
8197        }
8198        return null;
8199    }
8200
8201    @Override
8202    public int addAppTask(IBinder activityToken, Intent intent,
8203            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8204        final int callingUid = Binder.getCallingUid();
8205        final long callingIdent = Binder.clearCallingIdentity();
8206
8207        try {
8208            synchronized (this) {
8209                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8210                if (r == null) {
8211                    throw new IllegalArgumentException("Activity does not exist; token="
8212                            + activityToken);
8213                }
8214                ComponentName comp = intent.getComponent();
8215                if (comp == null) {
8216                    throw new IllegalArgumentException("Intent " + intent
8217                            + " must specify explicit component");
8218                }
8219                if (thumbnail.getWidth() != mThumbnailWidth
8220                        || thumbnail.getHeight() != mThumbnailHeight) {
8221                    throw new IllegalArgumentException("Bad thumbnail size: got "
8222                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8223                            + mThumbnailWidth + "x" + mThumbnailHeight);
8224                }
8225                if (intent.getSelector() != null) {
8226                    intent.setSelector(null);
8227                }
8228                if (intent.getSourceBounds() != null) {
8229                    intent.setSourceBounds(null);
8230                }
8231                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8232                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8233                        // The caller has added this as an auto-remove task...  that makes no
8234                        // sense, so turn off auto-remove.
8235                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8236                    }
8237                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8238                    // Must be a new task.
8239                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8240                }
8241                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8242                    mLastAddedTaskActivity = null;
8243                }
8244                ActivityInfo ainfo = mLastAddedTaskActivity;
8245                if (ainfo == null) {
8246                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8247                            comp, 0, UserHandle.getUserId(callingUid));
8248                    if (ainfo.applicationInfo.uid != callingUid) {
8249                        throw new SecurityException(
8250                                "Can't add task for another application: target uid="
8251                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8252                    }
8253                }
8254
8255                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8256                        intent, description);
8257
8258                int trimIdx = trimRecentsForTask(task, false);
8259                if (trimIdx >= 0) {
8260                    // If this would have caused a trim, then we'll abort because that
8261                    // means it would be added at the end of the list but then just removed.
8262                    return -1;
8263                }
8264
8265                final int N = mRecentTasks.size();
8266                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8267                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8268                    tr.removedFromRecents(mTaskPersister);
8269                }
8270
8271                task.inRecents = true;
8272                mRecentTasks.add(task);
8273                r.task.stack.addTask(task, false, false);
8274
8275                task.setLastThumbnail(thumbnail);
8276                task.freeLastThumbnail();
8277
8278                return task.taskId;
8279            }
8280        } finally {
8281            Binder.restoreCallingIdentity(callingIdent);
8282        }
8283    }
8284
8285    @Override
8286    public Point getAppTaskThumbnailSize() {
8287        synchronized (this) {
8288            return new Point(mThumbnailWidth,  mThumbnailHeight);
8289        }
8290    }
8291
8292    @Override
8293    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8294        synchronized (this) {
8295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8296            if (r != null) {
8297                r.taskDescription = td;
8298                r.task.updateTaskDescription();
8299            }
8300        }
8301    }
8302
8303    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8304        mRecentTasks.remove(tr);
8305        tr.removedFromRecents(mTaskPersister);
8306        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8307        Intent baseIntent = new Intent(
8308                tr.intent != null ? tr.intent : tr.affinityIntent);
8309        ComponentName component = baseIntent.getComponent();
8310        if (component == null) {
8311            Slog.w(TAG, "Now component for base intent of task: " + tr);
8312            return;
8313        }
8314
8315        // Find any running services associated with this app.
8316        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8317
8318        if (killProcesses) {
8319            // Find any running processes associated with this app.
8320            final String pkg = component.getPackageName();
8321            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8322            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8323            for (int i=0; i<pmap.size(); i++) {
8324                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8325                for (int j=0; j<uids.size(); j++) {
8326                    ProcessRecord proc = uids.valueAt(j);
8327                    if (proc.userId != tr.userId) {
8328                        continue;
8329                    }
8330                    if (!proc.pkgList.containsKey(pkg)) {
8331                        continue;
8332                    }
8333                    procs.add(proc);
8334                }
8335            }
8336
8337            // Kill the running processes.
8338            for (int i=0; i<procs.size(); i++) {
8339                ProcessRecord pr = procs.get(i);
8340                if (pr == mHomeProcess) {
8341                    // Don't kill the home process along with tasks from the same package.
8342                    continue;
8343                }
8344                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8345                    pr.kill("remove task", true);
8346                } else {
8347                    pr.waitingToKill = "remove task";
8348                }
8349            }
8350        }
8351    }
8352
8353    /**
8354     * Removes the task with the specified task id.
8355     *
8356     * @param taskId Identifier of the task to be removed.
8357     * @param flags Additional operational flags.  May be 0 or
8358     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8359     * @return Returns true if the given task was found and removed.
8360     */
8361    private boolean removeTaskByIdLocked(int taskId, int flags) {
8362        TaskRecord tr = recentTaskForIdLocked(taskId);
8363        if (tr != null) {
8364            tr.removeTaskActivitiesLocked();
8365            cleanUpRemovedTaskLocked(tr, flags);
8366            if (tr.isPersistable) {
8367                notifyTaskPersisterLocked(null, true);
8368            }
8369            return true;
8370        }
8371        return false;
8372    }
8373
8374    @Override
8375    public boolean removeTask(int taskId, int flags) {
8376        synchronized (this) {
8377            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8378                    "removeTask()");
8379            long ident = Binder.clearCallingIdentity();
8380            try {
8381                return removeTaskByIdLocked(taskId, flags);
8382            } finally {
8383                Binder.restoreCallingIdentity(ident);
8384            }
8385        }
8386    }
8387
8388    /**
8389     * TODO: Add mController hook
8390     */
8391    @Override
8392    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8393        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8394                "moveTaskToFront()");
8395
8396        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8397        synchronized(this) {
8398            moveTaskToFrontLocked(taskId, flags, options);
8399        }
8400    }
8401
8402    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8403        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8404                Binder.getCallingUid(), "Task to front")) {
8405            ActivityOptions.abort(options);
8406            return;
8407        }
8408        final long origId = Binder.clearCallingIdentity();
8409        try {
8410            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8411            if (task == null) {
8412                return;
8413            }
8414            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8415                mStackSupervisor.showLockTaskToast();
8416                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8417                return;
8418            }
8419            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8420            if (prev != null && prev.isRecentsActivity()) {
8421                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8422            }
8423            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8424        } finally {
8425            Binder.restoreCallingIdentity(origId);
8426        }
8427        ActivityOptions.abort(options);
8428    }
8429
8430    @Override
8431    public void moveTaskToBack(int taskId) {
8432        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8433                "moveTaskToBack()");
8434
8435        synchronized(this) {
8436            TaskRecord tr = recentTaskForIdLocked(taskId);
8437            if (tr != null) {
8438                if (tr == mStackSupervisor.mLockTaskModeTask) {
8439                    mStackSupervisor.showLockTaskToast();
8440                    return;
8441                }
8442                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8443                ActivityStack stack = tr.stack;
8444                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8445                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8446                            Binder.getCallingUid(), "Task to back")) {
8447                        return;
8448                    }
8449                }
8450                final long origId = Binder.clearCallingIdentity();
8451                try {
8452                    stack.moveTaskToBackLocked(taskId, null);
8453                } finally {
8454                    Binder.restoreCallingIdentity(origId);
8455                }
8456            }
8457        }
8458    }
8459
8460    /**
8461     * Moves an activity, and all of the other activities within the same task, to the bottom
8462     * of the history stack.  The activity's order within the task is unchanged.
8463     *
8464     * @param token A reference to the activity we wish to move
8465     * @param nonRoot If false then this only works if the activity is the root
8466     *                of a task; if true it will work for any activity in a task.
8467     * @return Returns true if the move completed, false if not.
8468     */
8469    @Override
8470    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8471        enforceNotIsolatedCaller("moveActivityTaskToBack");
8472        synchronized(this) {
8473            final long origId = Binder.clearCallingIdentity();
8474            try {
8475                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8476                if (taskId >= 0) {
8477                    if ((mStackSupervisor.mLockTaskModeTask != null)
8478                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8479                        mStackSupervisor.showLockTaskToast();
8480                        return false;
8481                    }
8482                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8483                }
8484            } finally {
8485                Binder.restoreCallingIdentity(origId);
8486            }
8487        }
8488        return false;
8489    }
8490
8491    @Override
8492    public void moveTaskBackwards(int task) {
8493        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8494                "moveTaskBackwards()");
8495
8496        synchronized(this) {
8497            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8498                    Binder.getCallingUid(), "Task backwards")) {
8499                return;
8500            }
8501            final long origId = Binder.clearCallingIdentity();
8502            moveTaskBackwardsLocked(task);
8503            Binder.restoreCallingIdentity(origId);
8504        }
8505    }
8506
8507    private final void moveTaskBackwardsLocked(int task) {
8508        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8509    }
8510
8511    @Override
8512    public IBinder getHomeActivityToken() throws RemoteException {
8513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8514                "getHomeActivityToken()");
8515        synchronized (this) {
8516            return mStackSupervisor.getHomeActivityToken();
8517        }
8518    }
8519
8520    @Override
8521    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8522            IActivityContainerCallback callback) throws RemoteException {
8523        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8524                "createActivityContainer()");
8525        synchronized (this) {
8526            if (parentActivityToken == null) {
8527                throw new IllegalArgumentException("parent token must not be null");
8528            }
8529            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8530            if (r == null) {
8531                return null;
8532            }
8533            if (callback == null) {
8534                throw new IllegalArgumentException("callback must not be null");
8535            }
8536            return mStackSupervisor.createActivityContainer(r, callback);
8537        }
8538    }
8539
8540    @Override
8541    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8542        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8543                "deleteActivityContainer()");
8544        synchronized (this) {
8545            mStackSupervisor.deleteActivityContainer(container);
8546        }
8547    }
8548
8549    @Override
8550    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8551            throws RemoteException {
8552        synchronized (this) {
8553            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8554            if (stack != null) {
8555                return stack.mActivityContainer;
8556            }
8557            return null;
8558        }
8559    }
8560
8561    @Override
8562    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8563        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8564                "moveTaskToStack()");
8565        if (stackId == HOME_STACK_ID) {
8566            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8567                    new RuntimeException("here").fillInStackTrace());
8568        }
8569        synchronized (this) {
8570            long ident = Binder.clearCallingIdentity();
8571            try {
8572                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8573                        + stackId + " toTop=" + toTop);
8574                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8575            } finally {
8576                Binder.restoreCallingIdentity(ident);
8577            }
8578        }
8579    }
8580
8581    @Override
8582    public void resizeStack(int stackBoxId, Rect bounds) {
8583        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8584                "resizeStackBox()");
8585        long ident = Binder.clearCallingIdentity();
8586        try {
8587            mWindowManager.resizeStack(stackBoxId, bounds);
8588        } finally {
8589            Binder.restoreCallingIdentity(ident);
8590        }
8591    }
8592
8593    @Override
8594    public List<StackInfo> getAllStackInfos() {
8595        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8596                "getAllStackInfos()");
8597        long ident = Binder.clearCallingIdentity();
8598        try {
8599            synchronized (this) {
8600                return mStackSupervisor.getAllStackInfosLocked();
8601            }
8602        } finally {
8603            Binder.restoreCallingIdentity(ident);
8604        }
8605    }
8606
8607    @Override
8608    public StackInfo getStackInfo(int stackId) {
8609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8610                "getStackInfo()");
8611        long ident = Binder.clearCallingIdentity();
8612        try {
8613            synchronized (this) {
8614                return mStackSupervisor.getStackInfoLocked(stackId);
8615            }
8616        } finally {
8617            Binder.restoreCallingIdentity(ident);
8618        }
8619    }
8620
8621    @Override
8622    public boolean isInHomeStack(int taskId) {
8623        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8624                "getStackInfo()");
8625        long ident = Binder.clearCallingIdentity();
8626        try {
8627            synchronized (this) {
8628                TaskRecord tr = recentTaskForIdLocked(taskId);
8629                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8630            }
8631        } finally {
8632            Binder.restoreCallingIdentity(ident);
8633        }
8634    }
8635
8636    @Override
8637    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8638        synchronized(this) {
8639            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8640        }
8641    }
8642
8643    private boolean isLockTaskAuthorized(String pkg) {
8644        final DevicePolicyManager dpm = (DevicePolicyManager)
8645                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8646        try {
8647            int uid = mContext.getPackageManager().getPackageUid(pkg,
8648                    Binder.getCallingUserHandle().getIdentifier());
8649            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8650        } catch (NameNotFoundException e) {
8651            return false;
8652        }
8653    }
8654
8655    void startLockTaskMode(TaskRecord task) {
8656        final String pkg;
8657        synchronized (this) {
8658            pkg = task.intent.getComponent().getPackageName();
8659        }
8660        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8661        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8662            final TaskRecord taskRecord = task;
8663            mHandler.post(new Runnable() {
8664                @Override
8665                public void run() {
8666                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8667                }
8668            });
8669            return;
8670        }
8671        long ident = Binder.clearCallingIdentity();
8672        try {
8673            synchronized (this) {
8674                // Since we lost lock on task, make sure it is still there.
8675                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8676                if (task != null) {
8677                    if (!isSystemInitiated
8678                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8679                        throw new IllegalArgumentException("Invalid task, not in foreground");
8680                    }
8681                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8682                }
8683            }
8684        } finally {
8685            Binder.restoreCallingIdentity(ident);
8686        }
8687    }
8688
8689    @Override
8690    public void startLockTaskMode(int taskId) {
8691        final TaskRecord task;
8692        long ident = Binder.clearCallingIdentity();
8693        try {
8694            synchronized (this) {
8695                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8696            }
8697        } finally {
8698            Binder.restoreCallingIdentity(ident);
8699        }
8700        if (task != null) {
8701            startLockTaskMode(task);
8702        }
8703    }
8704
8705    @Override
8706    public void startLockTaskMode(IBinder token) {
8707        final TaskRecord task;
8708        long ident = Binder.clearCallingIdentity();
8709        try {
8710            synchronized (this) {
8711                final ActivityRecord r = ActivityRecord.forToken(token);
8712                if (r == null) {
8713                    return;
8714                }
8715                task = r.task;
8716            }
8717        } finally {
8718            Binder.restoreCallingIdentity(ident);
8719        }
8720        if (task != null) {
8721            startLockTaskMode(task);
8722        }
8723    }
8724
8725    @Override
8726    public void startLockTaskModeOnCurrent() throws RemoteException {
8727        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8728                "startLockTaskModeOnCurrent");
8729        ActivityRecord r = null;
8730        synchronized (this) {
8731            r = mStackSupervisor.topRunningActivityLocked();
8732        }
8733        startLockTaskMode(r.task);
8734    }
8735
8736    @Override
8737    public void stopLockTaskMode() {
8738        // Verify that the user matches the package of the intent for the TaskRecord
8739        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8740        // and stopLockTaskMode.
8741        final int callingUid = Binder.getCallingUid();
8742        if (callingUid != Process.SYSTEM_UID) {
8743            try {
8744                String pkg =
8745                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8746                int uid = mContext.getPackageManager().getPackageUid(pkg,
8747                        Binder.getCallingUserHandle().getIdentifier());
8748                if (uid != callingUid) {
8749                    throw new SecurityException("Invalid uid, expected " + uid);
8750                }
8751            } catch (NameNotFoundException e) {
8752                Log.d(TAG, "stopLockTaskMode " + e);
8753                return;
8754            }
8755        }
8756        long ident = Binder.clearCallingIdentity();
8757        try {
8758            Log.d(TAG, "stopLockTaskMode");
8759            // Stop lock task
8760            synchronized (this) {
8761                mStackSupervisor.setLockTaskModeLocked(null, false);
8762            }
8763        } finally {
8764            Binder.restoreCallingIdentity(ident);
8765        }
8766    }
8767
8768    @Override
8769    public void stopLockTaskModeOnCurrent() throws RemoteException {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "stopLockTaskModeOnCurrent");
8772        long ident = Binder.clearCallingIdentity();
8773        try {
8774            stopLockTaskMode();
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public boolean isInLockTaskMode() {
8782        synchronized (this) {
8783            return mStackSupervisor.isInLockTaskMode();
8784        }
8785    }
8786
8787    // =========================================================
8788    // CONTENT PROVIDERS
8789    // =========================================================
8790
8791    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8792        List<ProviderInfo> providers = null;
8793        try {
8794            providers = AppGlobals.getPackageManager().
8795                queryContentProviders(app.processName, app.uid,
8796                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8797        } catch (RemoteException ex) {
8798        }
8799        if (DEBUG_MU)
8800            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8801        int userId = app.userId;
8802        if (providers != null) {
8803            int N = providers.size();
8804            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8805            for (int i=0; i<N; i++) {
8806                ProviderInfo cpi =
8807                    (ProviderInfo)providers.get(i);
8808                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8809                        cpi.name, cpi.flags);
8810                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8811                    // This is a singleton provider, but a user besides the
8812                    // default user is asking to initialize a process it runs
8813                    // in...  well, no, it doesn't actually run in this process,
8814                    // it runs in the process of the default user.  Get rid of it.
8815                    providers.remove(i);
8816                    N--;
8817                    i--;
8818                    continue;
8819                }
8820
8821                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8822                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8823                if (cpr == null) {
8824                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8825                    mProviderMap.putProviderByClass(comp, cpr);
8826                }
8827                if (DEBUG_MU)
8828                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8829                app.pubProviders.put(cpi.name, cpr);
8830                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8831                    // Don't add this if it is a platform component that is marked
8832                    // to run in multiple processes, because this is actually
8833                    // part of the framework so doesn't make sense to track as a
8834                    // separate apk in the process.
8835                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8836                            mProcessStats);
8837                }
8838                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8839            }
8840        }
8841        return providers;
8842    }
8843
8844    /**
8845     * Check if {@link ProcessRecord} has a possible chance at accessing the
8846     * given {@link ProviderInfo}. Final permission checking is always done
8847     * in {@link ContentProvider}.
8848     */
8849    private final String checkContentProviderPermissionLocked(
8850            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8851        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8852        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8853        boolean checkedGrants = false;
8854        if (checkUser) {
8855            // Looking for cross-user grants before enforcing the typical cross-users permissions
8856            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8857            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8858                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8859                    return null;
8860                }
8861                checkedGrants = true;
8862            }
8863            userId = handleIncomingUser(callingPid, callingUid, userId,
8864                    false, ALLOW_NON_FULL,
8865                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8866            if (userId != tmpTargetUserId) {
8867                // When we actually went to determine the final targer user ID, this ended
8868                // up different than our initial check for the authority.  This is because
8869                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8870                // SELF.  So we need to re-check the grants again.
8871                checkedGrants = false;
8872            }
8873        }
8874        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8875                cpi.applicationInfo.uid, cpi.exported)
8876                == PackageManager.PERMISSION_GRANTED) {
8877            return null;
8878        }
8879        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8880                cpi.applicationInfo.uid, cpi.exported)
8881                == PackageManager.PERMISSION_GRANTED) {
8882            return null;
8883        }
8884
8885        PathPermission[] pps = cpi.pathPermissions;
8886        if (pps != null) {
8887            int i = pps.length;
8888            while (i > 0) {
8889                i--;
8890                PathPermission pp = pps[i];
8891                String pprperm = pp.getReadPermission();
8892                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8893                        cpi.applicationInfo.uid, cpi.exported)
8894                        == PackageManager.PERMISSION_GRANTED) {
8895                    return null;
8896                }
8897                String ppwperm = pp.getWritePermission();
8898                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8899                        cpi.applicationInfo.uid, cpi.exported)
8900                        == PackageManager.PERMISSION_GRANTED) {
8901                    return null;
8902                }
8903            }
8904        }
8905        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8906            return null;
8907        }
8908
8909        String msg;
8910        if (!cpi.exported) {
8911            msg = "Permission Denial: opening provider " + cpi.name
8912                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8913                    + ", uid=" + callingUid + ") that is not exported from uid "
8914                    + cpi.applicationInfo.uid;
8915        } else {
8916            msg = "Permission Denial: opening provider " + cpi.name
8917                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8918                    + ", uid=" + callingUid + ") requires "
8919                    + cpi.readPermission + " or " + cpi.writePermission;
8920        }
8921        Slog.w(TAG, msg);
8922        return msg;
8923    }
8924
8925    /**
8926     * Returns if the ContentProvider has granted a uri to callingUid
8927     */
8928    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8929        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8930        if (perms != null) {
8931            for (int i=perms.size()-1; i>=0; i--) {
8932                GrantUri grantUri = perms.keyAt(i);
8933                if (grantUri.sourceUserId == userId || !checkUser) {
8934                    if (matchesProvider(grantUri.uri, cpi)) {
8935                        return true;
8936                    }
8937                }
8938            }
8939        }
8940        return false;
8941    }
8942
8943    /**
8944     * Returns true if the uri authority is one of the authorities specified in the provider.
8945     */
8946    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8947        String uriAuth = uri.getAuthority();
8948        String cpiAuth = cpi.authority;
8949        if (cpiAuth.indexOf(';') == -1) {
8950            return cpiAuth.equals(uriAuth);
8951        }
8952        String[] cpiAuths = cpiAuth.split(";");
8953        int length = cpiAuths.length;
8954        for (int i = 0; i < length; i++) {
8955            if (cpiAuths[i].equals(uriAuth)) return true;
8956        }
8957        return false;
8958    }
8959
8960    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8961            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8962        if (r != null) {
8963            for (int i=0; i<r.conProviders.size(); i++) {
8964                ContentProviderConnection conn = r.conProviders.get(i);
8965                if (conn.provider == cpr) {
8966                    if (DEBUG_PROVIDER) Slog.v(TAG,
8967                            "Adding provider requested by "
8968                            + r.processName + " from process "
8969                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8970                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8971                    if (stable) {
8972                        conn.stableCount++;
8973                        conn.numStableIncs++;
8974                    } else {
8975                        conn.unstableCount++;
8976                        conn.numUnstableIncs++;
8977                    }
8978                    return conn;
8979                }
8980            }
8981            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8982            if (stable) {
8983                conn.stableCount = 1;
8984                conn.numStableIncs = 1;
8985            } else {
8986                conn.unstableCount = 1;
8987                conn.numUnstableIncs = 1;
8988            }
8989            cpr.connections.add(conn);
8990            r.conProviders.add(conn);
8991            return conn;
8992        }
8993        cpr.addExternalProcessHandleLocked(externalProcessToken);
8994        return null;
8995    }
8996
8997    boolean decProviderCountLocked(ContentProviderConnection conn,
8998            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8999        if (conn != null) {
9000            cpr = conn.provider;
9001            if (DEBUG_PROVIDER) Slog.v(TAG,
9002                    "Removing provider requested by "
9003                    + conn.client.processName + " from process "
9004                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9005                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9006            if (stable) {
9007                conn.stableCount--;
9008            } else {
9009                conn.unstableCount--;
9010            }
9011            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9012                cpr.connections.remove(conn);
9013                conn.client.conProviders.remove(conn);
9014                return true;
9015            }
9016            return false;
9017        }
9018        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9019        return false;
9020    }
9021
9022    private void checkTime(long startTime, String where) {
9023        long now = SystemClock.elapsedRealtime();
9024        if ((now-startTime) > 1000) {
9025            // If we are taking more than a second, log about it.
9026            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9027        }
9028    }
9029
9030    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9031            String name, IBinder token, boolean stable, int userId) {
9032        ContentProviderRecord cpr;
9033        ContentProviderConnection conn = null;
9034        ProviderInfo cpi = null;
9035
9036        synchronized(this) {
9037            long startTime = SystemClock.elapsedRealtime();
9038
9039            ProcessRecord r = null;
9040            if (caller != null) {
9041                r = getRecordForAppLocked(caller);
9042                if (r == null) {
9043                    throw new SecurityException(
9044                            "Unable to find app for caller " + caller
9045                          + " (pid=" + Binder.getCallingPid()
9046                          + ") when getting content provider " + name);
9047                }
9048            }
9049
9050            boolean checkCrossUser = true;
9051
9052            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9053
9054            // First check if this content provider has been published...
9055            cpr = mProviderMap.getProviderByName(name, userId);
9056            // If that didn't work, check if it exists for user 0 and then
9057            // verify that it's a singleton provider before using it.
9058            if (cpr == null && userId != UserHandle.USER_OWNER) {
9059                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9060                if (cpr != null) {
9061                    cpi = cpr.info;
9062                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9063                            cpi.name, cpi.flags)
9064                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9065                        userId = UserHandle.USER_OWNER;
9066                        checkCrossUser = false;
9067                    } else {
9068                        cpr = null;
9069                        cpi = null;
9070                    }
9071                }
9072            }
9073
9074            boolean providerRunning = cpr != null;
9075            if (providerRunning) {
9076                cpi = cpr.info;
9077                String msg;
9078                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9079                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9080                        != null) {
9081                    throw new SecurityException(msg);
9082                }
9083                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9084
9085                if (r != null && cpr.canRunHere(r)) {
9086                    // This provider has been published or is in the process
9087                    // of being published...  but it is also allowed to run
9088                    // in the caller's process, so don't make a connection
9089                    // and just let the caller instantiate its own instance.
9090                    ContentProviderHolder holder = cpr.newHolder(null);
9091                    // don't give caller the provider object, it needs
9092                    // to make its own.
9093                    holder.provider = null;
9094                    return holder;
9095                }
9096
9097                final long origId = Binder.clearCallingIdentity();
9098
9099                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9100
9101                // In this case the provider instance already exists, so we can
9102                // return it right away.
9103                conn = incProviderCountLocked(r, cpr, token, stable);
9104                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9105                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9106                        // If this is a perceptible app accessing the provider,
9107                        // make sure to count it as being accessed and thus
9108                        // back up on the LRU list.  This is good because
9109                        // content providers are often expensive to start.
9110                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9111                        updateLruProcessLocked(cpr.proc, false, null);
9112                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9113                    }
9114                }
9115
9116                if (cpr.proc != null) {
9117                    if (false) {
9118                        if (cpr.name.flattenToShortString().equals(
9119                                "com.android.providers.calendar/.CalendarProvider2")) {
9120                            Slog.v(TAG, "****************** KILLING "
9121                                + cpr.name.flattenToShortString());
9122                            Process.killProcess(cpr.proc.pid);
9123                        }
9124                    }
9125                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9126                    boolean success = updateOomAdjLocked(cpr.proc);
9127                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9128                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9129                    // NOTE: there is still a race here where a signal could be
9130                    // pending on the process even though we managed to update its
9131                    // adj level.  Not sure what to do about this, but at least
9132                    // the race is now smaller.
9133                    if (!success) {
9134                        // Uh oh...  it looks like the provider's process
9135                        // has been killed on us.  We need to wait for a new
9136                        // process to be started, and make sure its death
9137                        // doesn't kill our process.
9138                        Slog.i(TAG,
9139                                "Existing provider " + cpr.name.flattenToShortString()
9140                                + " is crashing; detaching " + r);
9141                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9142                        checkTime(startTime, "getContentProviderImpl: before appDied");
9143                        appDiedLocked(cpr.proc);
9144                        checkTime(startTime, "getContentProviderImpl: after appDied");
9145                        if (!lastRef) {
9146                            // This wasn't the last ref our process had on
9147                            // the provider...  we have now been killed, bail.
9148                            return null;
9149                        }
9150                        providerRunning = false;
9151                        conn = null;
9152                    }
9153                }
9154
9155                Binder.restoreCallingIdentity(origId);
9156            }
9157
9158            boolean singleton;
9159            if (!providerRunning) {
9160                try {
9161                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9162                    cpi = AppGlobals.getPackageManager().
9163                        resolveContentProvider(name,
9164                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9165                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9166                } catch (RemoteException ex) {
9167                }
9168                if (cpi == null) {
9169                    return null;
9170                }
9171                // If the provider is a singleton AND
9172                // (it's a call within the same user || the provider is a
9173                // privileged app)
9174                // Then allow connecting to the singleton provider
9175                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9176                        cpi.name, cpi.flags)
9177                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9178                if (singleton) {
9179                    userId = UserHandle.USER_OWNER;
9180                }
9181                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9182                checkTime(startTime, "getContentProviderImpl: got app info for user");
9183
9184                String msg;
9185                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9186                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9187                        != null) {
9188                    throw new SecurityException(msg);
9189                }
9190                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9191
9192                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9193                        && !cpi.processName.equals("system")) {
9194                    // If this content provider does not run in the system
9195                    // process, and the system is not yet ready to run other
9196                    // processes, then fail fast instead of hanging.
9197                    throw new IllegalArgumentException(
9198                            "Attempt to launch content provider before system ready");
9199                }
9200
9201                // Make sure that the user who owns this provider is started.  If not,
9202                // we don't want to allow it to run.
9203                if (mStartedUsers.get(userId) == null) {
9204                    Slog.w(TAG, "Unable to launch app "
9205                            + cpi.applicationInfo.packageName + "/"
9206                            + cpi.applicationInfo.uid + " for provider "
9207                            + name + ": user " + userId + " is stopped");
9208                    return null;
9209                }
9210
9211                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9212                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9213                cpr = mProviderMap.getProviderByClass(comp, userId);
9214                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9215                final boolean firstClass = cpr == null;
9216                if (firstClass) {
9217                    try {
9218                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9219                        ApplicationInfo ai =
9220                            AppGlobals.getPackageManager().
9221                                getApplicationInfo(
9222                                        cpi.applicationInfo.packageName,
9223                                        STOCK_PM_FLAGS, userId);
9224                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9225                        if (ai == null) {
9226                            Slog.w(TAG, "No package info for content provider "
9227                                    + cpi.name);
9228                            return null;
9229                        }
9230                        ai = getAppInfoForUser(ai, userId);
9231                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9232                    } catch (RemoteException ex) {
9233                        // pm is in same process, this will never happen.
9234                    }
9235                }
9236
9237                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9238
9239                if (r != null && cpr.canRunHere(r)) {
9240                    // If this is a multiprocess provider, then just return its
9241                    // info and allow the caller to instantiate it.  Only do
9242                    // this if the provider is the same user as the caller's
9243                    // process, or can run as root (so can be in any process).
9244                    return cpr.newHolder(null);
9245                }
9246
9247                if (DEBUG_PROVIDER) {
9248                    RuntimeException e = new RuntimeException("here");
9249                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9250                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9251                }
9252
9253                // This is single process, and our app is now connecting to it.
9254                // See if we are already in the process of launching this
9255                // provider.
9256                final int N = mLaunchingProviders.size();
9257                int i;
9258                for (i=0; i<N; i++) {
9259                    if (mLaunchingProviders.get(i) == cpr) {
9260                        break;
9261                    }
9262                }
9263
9264                // If the provider is not already being launched, then get it
9265                // started.
9266                if (i >= N) {
9267                    final long origId = Binder.clearCallingIdentity();
9268
9269                    try {
9270                        // Content provider is now in use, its package can't be stopped.
9271                        try {
9272                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9273                            AppGlobals.getPackageManager().setPackageStoppedState(
9274                                    cpr.appInfo.packageName, false, userId);
9275                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9276                        } catch (RemoteException e) {
9277                        } catch (IllegalArgumentException e) {
9278                            Slog.w(TAG, "Failed trying to unstop package "
9279                                    + cpr.appInfo.packageName + ": " + e);
9280                        }
9281
9282                        // Use existing process if already started
9283                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9284                        ProcessRecord proc = getProcessRecordLocked(
9285                                cpi.processName, cpr.appInfo.uid, false);
9286                        if (proc != null && proc.thread != null) {
9287                            if (DEBUG_PROVIDER) {
9288                                Slog.d(TAG, "Installing in existing process " + proc);
9289                            }
9290                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9291                            proc.pubProviders.put(cpi.name, cpr);
9292                            try {
9293                                proc.thread.scheduleInstallProvider(cpi);
9294                            } catch (RemoteException e) {
9295                            }
9296                        } else {
9297                            checkTime(startTime, "getContentProviderImpl: before start process");
9298                            proc = startProcessLocked(cpi.processName,
9299                                    cpr.appInfo, false, 0, "content provider",
9300                                    new ComponentName(cpi.applicationInfo.packageName,
9301                                            cpi.name), false, false, false);
9302                            checkTime(startTime, "getContentProviderImpl: after start process");
9303                            if (proc == null) {
9304                                Slog.w(TAG, "Unable to launch app "
9305                                        + cpi.applicationInfo.packageName + "/"
9306                                        + cpi.applicationInfo.uid + " for provider "
9307                                        + name + ": process is bad");
9308                                return null;
9309                            }
9310                        }
9311                        cpr.launchingApp = proc;
9312                        mLaunchingProviders.add(cpr);
9313                    } finally {
9314                        Binder.restoreCallingIdentity(origId);
9315                    }
9316                }
9317
9318                checkTime(startTime, "getContentProviderImpl: updating data structures");
9319
9320                // Make sure the provider is published (the same provider class
9321                // may be published under multiple names).
9322                if (firstClass) {
9323                    mProviderMap.putProviderByClass(comp, cpr);
9324                }
9325
9326                mProviderMap.putProviderByName(name, cpr);
9327                conn = incProviderCountLocked(r, cpr, token, stable);
9328                if (conn != null) {
9329                    conn.waiting = true;
9330                }
9331            }
9332            checkTime(startTime, "getContentProviderImpl: done!");
9333        }
9334
9335        // Wait for the provider to be published...
9336        synchronized (cpr) {
9337            while (cpr.provider == null) {
9338                if (cpr.launchingApp == null) {
9339                    Slog.w(TAG, "Unable to launch app "
9340                            + cpi.applicationInfo.packageName + "/"
9341                            + cpi.applicationInfo.uid + " for provider "
9342                            + name + ": launching app became null");
9343                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9344                            UserHandle.getUserId(cpi.applicationInfo.uid),
9345                            cpi.applicationInfo.packageName,
9346                            cpi.applicationInfo.uid, name);
9347                    return null;
9348                }
9349                try {
9350                    if (DEBUG_MU) {
9351                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9352                                + cpr.launchingApp);
9353                    }
9354                    if (conn != null) {
9355                        conn.waiting = true;
9356                    }
9357                    cpr.wait();
9358                } catch (InterruptedException ex) {
9359                } finally {
9360                    if (conn != null) {
9361                        conn.waiting = false;
9362                    }
9363                }
9364            }
9365        }
9366        return cpr != null ? cpr.newHolder(conn) : null;
9367    }
9368
9369    @Override
9370    public final ContentProviderHolder getContentProvider(
9371            IApplicationThread caller, String name, int userId, boolean stable) {
9372        enforceNotIsolatedCaller("getContentProvider");
9373        if (caller == null) {
9374            String msg = "null IApplicationThread when getting content provider "
9375                    + name;
9376            Slog.w(TAG, msg);
9377            throw new SecurityException(msg);
9378        }
9379        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9380        // with cross-user grant.
9381        return getContentProviderImpl(caller, name, null, stable, userId);
9382    }
9383
9384    public ContentProviderHolder getContentProviderExternal(
9385            String name, int userId, IBinder token) {
9386        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9387            "Do not have permission in call getContentProviderExternal()");
9388        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9389                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9390        return getContentProviderExternalUnchecked(name, token, userId);
9391    }
9392
9393    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9394            IBinder token, int userId) {
9395        return getContentProviderImpl(null, name, token, true, userId);
9396    }
9397
9398    /**
9399     * Drop a content provider from a ProcessRecord's bookkeeping
9400     */
9401    public void removeContentProvider(IBinder connection, boolean stable) {
9402        enforceNotIsolatedCaller("removeContentProvider");
9403        long ident = Binder.clearCallingIdentity();
9404        try {
9405            synchronized (this) {
9406                ContentProviderConnection conn;
9407                try {
9408                    conn = (ContentProviderConnection)connection;
9409                } catch (ClassCastException e) {
9410                    String msg ="removeContentProvider: " + connection
9411                            + " not a ContentProviderConnection";
9412                    Slog.w(TAG, msg);
9413                    throw new IllegalArgumentException(msg);
9414                }
9415                if (conn == null) {
9416                    throw new NullPointerException("connection is null");
9417                }
9418                if (decProviderCountLocked(conn, null, null, stable)) {
9419                    updateOomAdjLocked();
9420                }
9421            }
9422        } finally {
9423            Binder.restoreCallingIdentity(ident);
9424        }
9425    }
9426
9427    public void removeContentProviderExternal(String name, IBinder token) {
9428        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9429            "Do not have permission in call removeContentProviderExternal()");
9430        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9431    }
9432
9433    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9434        synchronized (this) {
9435            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9436            if(cpr == null) {
9437                //remove from mProvidersByClass
9438                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9439                return;
9440            }
9441
9442            //update content provider record entry info
9443            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9444            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9445            if (localCpr.hasExternalProcessHandles()) {
9446                if (localCpr.removeExternalProcessHandleLocked(token)) {
9447                    updateOomAdjLocked();
9448                } else {
9449                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9450                            + " with no external reference for token: "
9451                            + token + ".");
9452                }
9453            } else {
9454                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9455                        + " with no external references.");
9456            }
9457        }
9458    }
9459
9460    public final void publishContentProviders(IApplicationThread caller,
9461            List<ContentProviderHolder> providers) {
9462        if (providers == null) {
9463            return;
9464        }
9465
9466        enforceNotIsolatedCaller("publishContentProviders");
9467        synchronized (this) {
9468            final ProcessRecord r = getRecordForAppLocked(caller);
9469            if (DEBUG_MU)
9470                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9471            if (r == null) {
9472                throw new SecurityException(
9473                        "Unable to find app for caller " + caller
9474                      + " (pid=" + Binder.getCallingPid()
9475                      + ") when publishing content providers");
9476            }
9477
9478            final long origId = Binder.clearCallingIdentity();
9479
9480            final int N = providers.size();
9481            for (int i=0; i<N; i++) {
9482                ContentProviderHolder src = providers.get(i);
9483                if (src == null || src.info == null || src.provider == null) {
9484                    continue;
9485                }
9486                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9487                if (DEBUG_MU)
9488                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9489                if (dst != null) {
9490                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9491                    mProviderMap.putProviderByClass(comp, dst);
9492                    String names[] = dst.info.authority.split(";");
9493                    for (int j = 0; j < names.length; j++) {
9494                        mProviderMap.putProviderByName(names[j], dst);
9495                    }
9496
9497                    int NL = mLaunchingProviders.size();
9498                    int j;
9499                    for (j=0; j<NL; j++) {
9500                        if (mLaunchingProviders.get(j) == dst) {
9501                            mLaunchingProviders.remove(j);
9502                            j--;
9503                            NL--;
9504                        }
9505                    }
9506                    synchronized (dst) {
9507                        dst.provider = src.provider;
9508                        dst.proc = r;
9509                        dst.notifyAll();
9510                    }
9511                    updateOomAdjLocked(r);
9512                }
9513            }
9514
9515            Binder.restoreCallingIdentity(origId);
9516        }
9517    }
9518
9519    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9520        ContentProviderConnection conn;
9521        try {
9522            conn = (ContentProviderConnection)connection;
9523        } catch (ClassCastException e) {
9524            String msg ="refContentProvider: " + connection
9525                    + " not a ContentProviderConnection";
9526            Slog.w(TAG, msg);
9527            throw new IllegalArgumentException(msg);
9528        }
9529        if (conn == null) {
9530            throw new NullPointerException("connection is null");
9531        }
9532
9533        synchronized (this) {
9534            if (stable > 0) {
9535                conn.numStableIncs += stable;
9536            }
9537            stable = conn.stableCount + stable;
9538            if (stable < 0) {
9539                throw new IllegalStateException("stableCount < 0: " + stable);
9540            }
9541
9542            if (unstable > 0) {
9543                conn.numUnstableIncs += unstable;
9544            }
9545            unstable = conn.unstableCount + unstable;
9546            if (unstable < 0) {
9547                throw new IllegalStateException("unstableCount < 0: " + unstable);
9548            }
9549
9550            if ((stable+unstable) <= 0) {
9551                throw new IllegalStateException("ref counts can't go to zero here: stable="
9552                        + stable + " unstable=" + unstable);
9553            }
9554            conn.stableCount = stable;
9555            conn.unstableCount = unstable;
9556            return !conn.dead;
9557        }
9558    }
9559
9560    public void unstableProviderDied(IBinder connection) {
9561        ContentProviderConnection conn;
9562        try {
9563            conn = (ContentProviderConnection)connection;
9564        } catch (ClassCastException e) {
9565            String msg ="refContentProvider: " + connection
9566                    + " not a ContentProviderConnection";
9567            Slog.w(TAG, msg);
9568            throw new IllegalArgumentException(msg);
9569        }
9570        if (conn == null) {
9571            throw new NullPointerException("connection is null");
9572        }
9573
9574        // Safely retrieve the content provider associated with the connection.
9575        IContentProvider provider;
9576        synchronized (this) {
9577            provider = conn.provider.provider;
9578        }
9579
9580        if (provider == null) {
9581            // Um, yeah, we're way ahead of you.
9582            return;
9583        }
9584
9585        // Make sure the caller is being honest with us.
9586        if (provider.asBinder().pingBinder()) {
9587            // Er, no, still looks good to us.
9588            synchronized (this) {
9589                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9590                        + " says " + conn + " died, but we don't agree");
9591                return;
9592            }
9593        }
9594
9595        // Well look at that!  It's dead!
9596        synchronized (this) {
9597            if (conn.provider.provider != provider) {
9598                // But something changed...  good enough.
9599                return;
9600            }
9601
9602            ProcessRecord proc = conn.provider.proc;
9603            if (proc == null || proc.thread == null) {
9604                // Seems like the process is already cleaned up.
9605                return;
9606            }
9607
9608            // As far as we're concerned, this is just like receiving a
9609            // death notification...  just a bit prematurely.
9610            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9611                    + ") early provider death");
9612            final long ident = Binder.clearCallingIdentity();
9613            try {
9614                appDiedLocked(proc);
9615            } finally {
9616                Binder.restoreCallingIdentity(ident);
9617            }
9618        }
9619    }
9620
9621    @Override
9622    public void appNotRespondingViaProvider(IBinder connection) {
9623        enforceCallingPermission(
9624                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9625
9626        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9627        if (conn == null) {
9628            Slog.w(TAG, "ContentProviderConnection is null");
9629            return;
9630        }
9631
9632        final ProcessRecord host = conn.provider.proc;
9633        if (host == null) {
9634            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9635            return;
9636        }
9637
9638        final long token = Binder.clearCallingIdentity();
9639        try {
9640            appNotResponding(host, null, null, false, "ContentProvider not responding");
9641        } finally {
9642            Binder.restoreCallingIdentity(token);
9643        }
9644    }
9645
9646    public final void installSystemProviders() {
9647        List<ProviderInfo> providers;
9648        synchronized (this) {
9649            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9650            providers = generateApplicationProvidersLocked(app);
9651            if (providers != null) {
9652                for (int i=providers.size()-1; i>=0; i--) {
9653                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9654                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9655                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9656                                + ": not system .apk");
9657                        providers.remove(i);
9658                    }
9659                }
9660            }
9661        }
9662        if (providers != null) {
9663            mSystemThread.installSystemProviders(providers);
9664        }
9665
9666        mCoreSettingsObserver = new CoreSettingsObserver(this);
9667
9668        //mUsageStatsService.monitorPackages();
9669    }
9670
9671    /**
9672     * Allows apps to retrieve the MIME type of a URI.
9673     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9674     * users, then it does not need permission to access the ContentProvider.
9675     * Either, it needs cross-user uri grants.
9676     *
9677     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9678     *
9679     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9680     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9681     */
9682    public String getProviderMimeType(Uri uri, int userId) {
9683        enforceNotIsolatedCaller("getProviderMimeType");
9684        final String name = uri.getAuthority();
9685        int callingUid = Binder.getCallingUid();
9686        int callingPid = Binder.getCallingPid();
9687        long ident = 0;
9688        boolean clearedIdentity = false;
9689        userId = unsafeConvertIncomingUser(userId);
9690        if (UserHandle.getUserId(callingUid) != userId) {
9691            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9692                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9693                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9694                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9695                clearedIdentity = true;
9696                ident = Binder.clearCallingIdentity();
9697            }
9698        }
9699        ContentProviderHolder holder = null;
9700        try {
9701            holder = getContentProviderExternalUnchecked(name, null, userId);
9702            if (holder != null) {
9703                return holder.provider.getType(uri);
9704            }
9705        } catch (RemoteException e) {
9706            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9707            return null;
9708        } finally {
9709            // We need to clear the identity to call removeContentProviderExternalUnchecked
9710            if (!clearedIdentity) {
9711                ident = Binder.clearCallingIdentity();
9712            }
9713            try {
9714                if (holder != null) {
9715                    removeContentProviderExternalUnchecked(name, null, userId);
9716                }
9717            } finally {
9718                Binder.restoreCallingIdentity(ident);
9719            }
9720        }
9721
9722        return null;
9723    }
9724
9725    // =========================================================
9726    // GLOBAL MANAGEMENT
9727    // =========================================================
9728
9729    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9730            boolean isolated, int isolatedUid) {
9731        String proc = customProcess != null ? customProcess : info.processName;
9732        BatteryStatsImpl.Uid.Proc ps = null;
9733        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9734        int uid = info.uid;
9735        if (isolated) {
9736            if (isolatedUid == 0) {
9737                int userId = UserHandle.getUserId(uid);
9738                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9739                while (true) {
9740                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9741                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9742                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9743                    }
9744                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9745                    mNextIsolatedProcessUid++;
9746                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9747                        // No process for this uid, use it.
9748                        break;
9749                    }
9750                    stepsLeft--;
9751                    if (stepsLeft <= 0) {
9752                        return null;
9753                    }
9754                }
9755            } else {
9756                // Special case for startIsolatedProcess (internal only), where
9757                // the uid of the isolated process is specified by the caller.
9758                uid = isolatedUid;
9759            }
9760        }
9761        return new ProcessRecord(stats, info, proc, uid);
9762    }
9763
9764    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9765            String abiOverride) {
9766        ProcessRecord app;
9767        if (!isolated) {
9768            app = getProcessRecordLocked(info.processName, info.uid, true);
9769        } else {
9770            app = null;
9771        }
9772
9773        if (app == null) {
9774            app = newProcessRecordLocked(info, null, isolated, 0);
9775            mProcessNames.put(info.processName, app.uid, app);
9776            if (isolated) {
9777                mIsolatedProcesses.put(app.uid, app);
9778            }
9779            updateLruProcessLocked(app, false, null);
9780            updateOomAdjLocked();
9781        }
9782
9783        // This package really, really can not be stopped.
9784        try {
9785            AppGlobals.getPackageManager().setPackageStoppedState(
9786                    info.packageName, false, UserHandle.getUserId(app.uid));
9787        } catch (RemoteException e) {
9788        } catch (IllegalArgumentException e) {
9789            Slog.w(TAG, "Failed trying to unstop package "
9790                    + info.packageName + ": " + e);
9791        }
9792
9793        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9794                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9795            app.persistent = true;
9796            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9797        }
9798        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9799            mPersistentStartingProcesses.add(app);
9800            startProcessLocked(app, "added application", app.processName, abiOverride,
9801                    null /* entryPoint */, null /* entryPointArgs */);
9802        }
9803
9804        return app;
9805    }
9806
9807    public void unhandledBack() {
9808        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9809                "unhandledBack()");
9810
9811        synchronized(this) {
9812            final long origId = Binder.clearCallingIdentity();
9813            try {
9814                getFocusedStack().unhandledBackLocked();
9815            } finally {
9816                Binder.restoreCallingIdentity(origId);
9817            }
9818        }
9819    }
9820
9821    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9822        enforceNotIsolatedCaller("openContentUri");
9823        final int userId = UserHandle.getCallingUserId();
9824        String name = uri.getAuthority();
9825        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9826        ParcelFileDescriptor pfd = null;
9827        if (cph != null) {
9828            // We record the binder invoker's uid in thread-local storage before
9829            // going to the content provider to open the file.  Later, in the code
9830            // that handles all permissions checks, we look for this uid and use
9831            // that rather than the Activity Manager's own uid.  The effect is that
9832            // we do the check against the caller's permissions even though it looks
9833            // to the content provider like the Activity Manager itself is making
9834            // the request.
9835            sCallerIdentity.set(new Identity(
9836                    Binder.getCallingPid(), Binder.getCallingUid()));
9837            try {
9838                pfd = cph.provider.openFile(null, uri, "r", null);
9839            } catch (FileNotFoundException e) {
9840                // do nothing; pfd will be returned null
9841            } finally {
9842                // Ensure that whatever happens, we clean up the identity state
9843                sCallerIdentity.remove();
9844            }
9845
9846            // We've got the fd now, so we're done with the provider.
9847            removeContentProviderExternalUnchecked(name, null, userId);
9848        } else {
9849            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9850        }
9851        return pfd;
9852    }
9853
9854    // Actually is sleeping or shutting down or whatever else in the future
9855    // is an inactive state.
9856    public boolean isSleepingOrShuttingDown() {
9857        return mSleeping || mShuttingDown;
9858    }
9859
9860    public boolean isSleeping() {
9861        return mSleeping;
9862    }
9863
9864    void goingToSleep() {
9865        synchronized(this) {
9866            mWentToSleep = true;
9867            updateEventDispatchingLocked();
9868            goToSleepIfNeededLocked();
9869        }
9870    }
9871
9872    void finishRunningVoiceLocked() {
9873        if (mRunningVoice) {
9874            mRunningVoice = false;
9875            goToSleepIfNeededLocked();
9876        }
9877    }
9878
9879    void goToSleepIfNeededLocked() {
9880        if (mWentToSleep && !mRunningVoice) {
9881            if (!mSleeping) {
9882                mSleeping = true;
9883                mStackSupervisor.goingToSleepLocked();
9884
9885                // Initialize the wake times of all processes.
9886                checkExcessivePowerUsageLocked(false);
9887                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9888                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9889                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9890            }
9891        }
9892    }
9893
9894    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9895        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9896            // Never persist the home stack.
9897            return;
9898        }
9899        mTaskPersister.wakeup(task, flush);
9900    }
9901
9902    @Override
9903    public boolean shutdown(int timeout) {
9904        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9905                != PackageManager.PERMISSION_GRANTED) {
9906            throw new SecurityException("Requires permission "
9907                    + android.Manifest.permission.SHUTDOWN);
9908        }
9909
9910        boolean timedout = false;
9911
9912        synchronized(this) {
9913            mShuttingDown = true;
9914            updateEventDispatchingLocked();
9915            timedout = mStackSupervisor.shutdownLocked(timeout);
9916        }
9917
9918        mAppOpsService.shutdown();
9919        if (mUsageStatsService != null) {
9920            mUsageStatsService.prepareShutdown();
9921        }
9922        mBatteryStatsService.shutdown();
9923        synchronized (this) {
9924            mProcessStats.shutdownLocked();
9925        }
9926        notifyTaskPersisterLocked(null, true);
9927
9928        return timedout;
9929    }
9930
9931    public final void activitySlept(IBinder token) {
9932        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9933
9934        final long origId = Binder.clearCallingIdentity();
9935
9936        synchronized (this) {
9937            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9938            if (r != null) {
9939                mStackSupervisor.activitySleptLocked(r);
9940            }
9941        }
9942
9943        Binder.restoreCallingIdentity(origId);
9944    }
9945
9946    void logLockScreen(String msg) {
9947        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9948                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9949                mWentToSleep + " mSleeping=" + mSleeping);
9950    }
9951
9952    private void comeOutOfSleepIfNeededLocked() {
9953        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9954            if (mSleeping) {
9955                mSleeping = false;
9956                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9957            }
9958        }
9959    }
9960
9961    void wakingUp() {
9962        synchronized(this) {
9963            mWentToSleep = false;
9964            updateEventDispatchingLocked();
9965            comeOutOfSleepIfNeededLocked();
9966        }
9967    }
9968
9969    void startRunningVoiceLocked() {
9970        if (!mRunningVoice) {
9971            mRunningVoice = true;
9972            comeOutOfSleepIfNeededLocked();
9973        }
9974    }
9975
9976    private void updateEventDispatchingLocked() {
9977        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9978    }
9979
9980    public void setLockScreenShown(boolean shown) {
9981        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9982                != PackageManager.PERMISSION_GRANTED) {
9983            throw new SecurityException("Requires permission "
9984                    + android.Manifest.permission.DEVICE_POWER);
9985        }
9986
9987        synchronized(this) {
9988            long ident = Binder.clearCallingIdentity();
9989            try {
9990                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9991                mLockScreenShown = shown;
9992                comeOutOfSleepIfNeededLocked();
9993            } finally {
9994                Binder.restoreCallingIdentity(ident);
9995            }
9996        }
9997    }
9998
9999    @Override
10000    public void stopAppSwitches() {
10001        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10002                != PackageManager.PERMISSION_GRANTED) {
10003            throw new SecurityException("Requires permission "
10004                    + android.Manifest.permission.STOP_APP_SWITCHES);
10005        }
10006
10007        synchronized(this) {
10008            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10009                    + APP_SWITCH_DELAY_TIME;
10010            mDidAppSwitch = false;
10011            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10012            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10013            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10014        }
10015    }
10016
10017    public void resumeAppSwitches() {
10018        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10019                != PackageManager.PERMISSION_GRANTED) {
10020            throw new SecurityException("Requires permission "
10021                    + android.Manifest.permission.STOP_APP_SWITCHES);
10022        }
10023
10024        synchronized(this) {
10025            // Note that we don't execute any pending app switches... we will
10026            // let those wait until either the timeout, or the next start
10027            // activity request.
10028            mAppSwitchesAllowedTime = 0;
10029        }
10030    }
10031
10032    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10033            String name) {
10034        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10035            return true;
10036        }
10037
10038        final int perm = checkComponentPermission(
10039                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10040                callingUid, -1, true);
10041        if (perm == PackageManager.PERMISSION_GRANTED) {
10042            return true;
10043        }
10044
10045        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10046        return false;
10047    }
10048
10049    public void setDebugApp(String packageName, boolean waitForDebugger,
10050            boolean persistent) {
10051        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10052                "setDebugApp()");
10053
10054        long ident = Binder.clearCallingIdentity();
10055        try {
10056            // Note that this is not really thread safe if there are multiple
10057            // callers into it at the same time, but that's not a situation we
10058            // care about.
10059            if (persistent) {
10060                final ContentResolver resolver = mContext.getContentResolver();
10061                Settings.Global.putString(
10062                    resolver, Settings.Global.DEBUG_APP,
10063                    packageName);
10064                Settings.Global.putInt(
10065                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10066                    waitForDebugger ? 1 : 0);
10067            }
10068
10069            synchronized (this) {
10070                if (!persistent) {
10071                    mOrigDebugApp = mDebugApp;
10072                    mOrigWaitForDebugger = mWaitForDebugger;
10073                }
10074                mDebugApp = packageName;
10075                mWaitForDebugger = waitForDebugger;
10076                mDebugTransient = !persistent;
10077                if (packageName != null) {
10078                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10079                            false, UserHandle.USER_ALL, "set debug app");
10080                }
10081            }
10082        } finally {
10083            Binder.restoreCallingIdentity(ident);
10084        }
10085    }
10086
10087    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10088        synchronized (this) {
10089            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10090            if (!isDebuggable) {
10091                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10092                    throw new SecurityException("Process not debuggable: " + app.packageName);
10093                }
10094            }
10095
10096            mOpenGlTraceApp = processName;
10097        }
10098    }
10099
10100    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10101        synchronized (this) {
10102            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10103            if (!isDebuggable) {
10104                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10105                    throw new SecurityException("Process not debuggable: " + app.packageName);
10106                }
10107            }
10108            mProfileApp = processName;
10109            mProfileFile = profilerInfo.profileFile;
10110            if (mProfileFd != null) {
10111                try {
10112                    mProfileFd.close();
10113                } catch (IOException e) {
10114                }
10115                mProfileFd = null;
10116            }
10117            mProfileFd = profilerInfo.profileFd;
10118            mSamplingInterval = profilerInfo.samplingInterval;
10119            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10120            mProfileType = 0;
10121        }
10122    }
10123
10124    @Override
10125    public void setAlwaysFinish(boolean enabled) {
10126        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10127                "setAlwaysFinish()");
10128
10129        Settings.Global.putInt(
10130                mContext.getContentResolver(),
10131                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10132
10133        synchronized (this) {
10134            mAlwaysFinishActivities = enabled;
10135        }
10136    }
10137
10138    @Override
10139    public void setActivityController(IActivityController controller) {
10140        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10141                "setActivityController()");
10142        synchronized (this) {
10143            mController = controller;
10144            Watchdog.getInstance().setActivityController(controller);
10145        }
10146    }
10147
10148    @Override
10149    public void setUserIsMonkey(boolean userIsMonkey) {
10150        synchronized (this) {
10151            synchronized (mPidsSelfLocked) {
10152                final int callingPid = Binder.getCallingPid();
10153                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10154                if (precessRecord == null) {
10155                    throw new SecurityException("Unknown process: " + callingPid);
10156                }
10157                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10158                    throw new SecurityException("Only an instrumentation process "
10159                            + "with a UiAutomation can call setUserIsMonkey");
10160                }
10161            }
10162            mUserIsMonkey = userIsMonkey;
10163        }
10164    }
10165
10166    @Override
10167    public boolean isUserAMonkey() {
10168        synchronized (this) {
10169            // If there is a controller also implies the user is a monkey.
10170            return (mUserIsMonkey || mController != null);
10171        }
10172    }
10173
10174    public void requestBugReport() {
10175        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10176        SystemProperties.set("ctl.start", "bugreport");
10177    }
10178
10179    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10180        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10181    }
10182
10183    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10184        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10185            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10186        }
10187        return KEY_DISPATCHING_TIMEOUT;
10188    }
10189
10190    @Override
10191    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10192        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10193                != PackageManager.PERMISSION_GRANTED) {
10194            throw new SecurityException("Requires permission "
10195                    + android.Manifest.permission.FILTER_EVENTS);
10196        }
10197        ProcessRecord proc;
10198        long timeout;
10199        synchronized (this) {
10200            synchronized (mPidsSelfLocked) {
10201                proc = mPidsSelfLocked.get(pid);
10202            }
10203            timeout = getInputDispatchingTimeoutLocked(proc);
10204        }
10205
10206        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10207            return -1;
10208        }
10209
10210        return timeout;
10211    }
10212
10213    /**
10214     * Handle input dispatching timeouts.
10215     * Returns whether input dispatching should be aborted or not.
10216     */
10217    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10218            final ActivityRecord activity, final ActivityRecord parent,
10219            final boolean aboveSystem, String reason) {
10220        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10221                != PackageManager.PERMISSION_GRANTED) {
10222            throw new SecurityException("Requires permission "
10223                    + android.Manifest.permission.FILTER_EVENTS);
10224        }
10225
10226        final String annotation;
10227        if (reason == null) {
10228            annotation = "Input dispatching timed out";
10229        } else {
10230            annotation = "Input dispatching timed out (" + reason + ")";
10231        }
10232
10233        if (proc != null) {
10234            synchronized (this) {
10235                if (proc.debugging) {
10236                    return false;
10237                }
10238
10239                if (mDidDexOpt) {
10240                    // Give more time since we were dexopting.
10241                    mDidDexOpt = false;
10242                    return false;
10243                }
10244
10245                if (proc.instrumentationClass != null) {
10246                    Bundle info = new Bundle();
10247                    info.putString("shortMsg", "keyDispatchingTimedOut");
10248                    info.putString("longMsg", annotation);
10249                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10250                    return true;
10251                }
10252            }
10253            mHandler.post(new Runnable() {
10254                @Override
10255                public void run() {
10256                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10257                }
10258            });
10259        }
10260
10261        return true;
10262    }
10263
10264    public Bundle getAssistContextExtras(int requestType) {
10265        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10266                "getAssistContextExtras()");
10267        PendingAssistExtras pae;
10268        Bundle extras = new Bundle();
10269        synchronized (this) {
10270            ActivityRecord activity = getFocusedStack().mResumedActivity;
10271            if (activity == null) {
10272                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10273                return null;
10274            }
10275            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10276            if (activity.app == null || activity.app.thread == null) {
10277                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10278                return extras;
10279            }
10280            if (activity.app.pid == Binder.getCallingPid()) {
10281                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10282                return extras;
10283            }
10284            pae = new PendingAssistExtras(activity);
10285            try {
10286                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10287                        requestType);
10288                mPendingAssistExtras.add(pae);
10289                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10290            } catch (RemoteException e) {
10291                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10292                return extras;
10293            }
10294        }
10295        synchronized (pae) {
10296            while (!pae.haveResult) {
10297                try {
10298                    pae.wait();
10299                } catch (InterruptedException e) {
10300                }
10301            }
10302            if (pae.result != null) {
10303                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10304            }
10305        }
10306        synchronized (this) {
10307            mPendingAssistExtras.remove(pae);
10308            mHandler.removeCallbacks(pae);
10309        }
10310        return extras;
10311    }
10312
10313    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10314        PendingAssistExtras pae = (PendingAssistExtras)token;
10315        synchronized (pae) {
10316            pae.result = extras;
10317            pae.haveResult = true;
10318            pae.notifyAll();
10319        }
10320    }
10321
10322    public void registerProcessObserver(IProcessObserver observer) {
10323        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10324                "registerProcessObserver()");
10325        synchronized (this) {
10326            mProcessObservers.register(observer);
10327        }
10328    }
10329
10330    @Override
10331    public void unregisterProcessObserver(IProcessObserver observer) {
10332        synchronized (this) {
10333            mProcessObservers.unregister(observer);
10334        }
10335    }
10336
10337    @Override
10338    public boolean convertFromTranslucent(IBinder token) {
10339        final long origId = Binder.clearCallingIdentity();
10340        try {
10341            synchronized (this) {
10342                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10343                if (r == null) {
10344                    return false;
10345                }
10346                final boolean translucentChanged = r.changeWindowTranslucency(true);
10347                if (translucentChanged) {
10348                    r.task.stack.releaseBackgroundResources();
10349                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10350                }
10351                mWindowManager.setAppFullscreen(token, true);
10352                return translucentChanged;
10353            }
10354        } finally {
10355            Binder.restoreCallingIdentity(origId);
10356        }
10357    }
10358
10359    @Override
10360    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10361        final long origId = Binder.clearCallingIdentity();
10362        try {
10363            synchronized (this) {
10364                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10365                if (r == null) {
10366                    return false;
10367                }
10368                int index = r.task.mActivities.lastIndexOf(r);
10369                if (index > 0) {
10370                    ActivityRecord under = r.task.mActivities.get(index - 1);
10371                    under.returningOptions = options;
10372                }
10373                final boolean translucentChanged = r.changeWindowTranslucency(false);
10374                if (translucentChanged) {
10375                    r.task.stack.convertToTranslucent(r);
10376                }
10377                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10378                mWindowManager.setAppFullscreen(token, false);
10379                return translucentChanged;
10380            }
10381        } finally {
10382            Binder.restoreCallingIdentity(origId);
10383        }
10384    }
10385
10386    @Override
10387    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10388        final long origId = Binder.clearCallingIdentity();
10389        try {
10390            synchronized (this) {
10391                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10392                if (r != null) {
10393                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10394                }
10395            }
10396            return false;
10397        } finally {
10398            Binder.restoreCallingIdentity(origId);
10399        }
10400    }
10401
10402    @Override
10403    public boolean isBackgroundVisibleBehind(IBinder token) {
10404        final long origId = Binder.clearCallingIdentity();
10405        try {
10406            synchronized (this) {
10407                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10408                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10409                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10410                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10411                return visible;
10412            }
10413        } finally {
10414            Binder.restoreCallingIdentity(origId);
10415        }
10416    }
10417
10418    @Override
10419    public ActivityOptions getActivityOptions(IBinder token) {
10420        final long origId = Binder.clearCallingIdentity();
10421        try {
10422            synchronized (this) {
10423                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10424                if (r != null) {
10425                    final ActivityOptions activityOptions = r.pendingOptions;
10426                    r.pendingOptions = null;
10427                    return activityOptions;
10428                }
10429                return null;
10430            }
10431        } finally {
10432            Binder.restoreCallingIdentity(origId);
10433        }
10434    }
10435
10436    @Override
10437    public void setImmersive(IBinder token, boolean immersive) {
10438        synchronized(this) {
10439            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10440            if (r == null) {
10441                throw new IllegalArgumentException();
10442            }
10443            r.immersive = immersive;
10444
10445            // update associated state if we're frontmost
10446            if (r == mFocusedActivity) {
10447                if (DEBUG_IMMERSIVE) {
10448                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10449                }
10450                applyUpdateLockStateLocked(r);
10451            }
10452        }
10453    }
10454
10455    @Override
10456    public boolean isImmersive(IBinder token) {
10457        synchronized (this) {
10458            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10459            if (r == null) {
10460                throw new IllegalArgumentException();
10461            }
10462            return r.immersive;
10463        }
10464    }
10465
10466    public boolean isTopActivityImmersive() {
10467        enforceNotIsolatedCaller("startActivity");
10468        synchronized (this) {
10469            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10470            return (r != null) ? r.immersive : false;
10471        }
10472    }
10473
10474    @Override
10475    public boolean isTopOfTask(IBinder token) {
10476        synchronized (this) {
10477            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10478            if (r == null) {
10479                throw new IllegalArgumentException();
10480            }
10481            return r.task.getTopActivity() == r;
10482        }
10483    }
10484
10485    public final void enterSafeMode() {
10486        synchronized(this) {
10487            // It only makes sense to do this before the system is ready
10488            // and started launching other packages.
10489            if (!mSystemReady) {
10490                try {
10491                    AppGlobals.getPackageManager().enterSafeMode();
10492                } catch (RemoteException e) {
10493                }
10494            }
10495
10496            mSafeMode = true;
10497        }
10498    }
10499
10500    public final void showSafeModeOverlay() {
10501        View v = LayoutInflater.from(mContext).inflate(
10502                com.android.internal.R.layout.safe_mode, null);
10503        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10504        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10505        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10506        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10507        lp.gravity = Gravity.BOTTOM | Gravity.START;
10508        lp.format = v.getBackground().getOpacity();
10509        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10510                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10511        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10512        ((WindowManager)mContext.getSystemService(
10513                Context.WINDOW_SERVICE)).addView(v, lp);
10514    }
10515
10516    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10517        if (!(sender instanceof PendingIntentRecord)) {
10518            return;
10519        }
10520        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10521        synchronized (stats) {
10522            if (mBatteryStatsService.isOnBattery()) {
10523                mBatteryStatsService.enforceCallingPermission();
10524                PendingIntentRecord rec = (PendingIntentRecord)sender;
10525                int MY_UID = Binder.getCallingUid();
10526                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10527                BatteryStatsImpl.Uid.Pkg pkg =
10528                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10529                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10530                pkg.incWakeupsLocked();
10531            }
10532        }
10533    }
10534
10535    public boolean killPids(int[] pids, String pReason, boolean secure) {
10536        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10537            throw new SecurityException("killPids only available to the system");
10538        }
10539        String reason = (pReason == null) ? "Unknown" : pReason;
10540        // XXX Note: don't acquire main activity lock here, because the window
10541        // manager calls in with its locks held.
10542
10543        boolean killed = false;
10544        synchronized (mPidsSelfLocked) {
10545            int[] types = new int[pids.length];
10546            int worstType = 0;
10547            for (int i=0; i<pids.length; i++) {
10548                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10549                if (proc != null) {
10550                    int type = proc.setAdj;
10551                    types[i] = type;
10552                    if (type > worstType) {
10553                        worstType = type;
10554                    }
10555                }
10556            }
10557
10558            // If the worst oom_adj is somewhere in the cached proc LRU range,
10559            // then constrain it so we will kill all cached procs.
10560            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10561                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10562                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10563            }
10564
10565            // If this is not a secure call, don't let it kill processes that
10566            // are important.
10567            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10568                worstType = ProcessList.SERVICE_ADJ;
10569            }
10570
10571            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10572            for (int i=0; i<pids.length; i++) {
10573                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10574                if (proc == null) {
10575                    continue;
10576                }
10577                int adj = proc.setAdj;
10578                if (adj >= worstType && !proc.killedByAm) {
10579                    proc.kill(reason, true);
10580                    killed = true;
10581                }
10582            }
10583        }
10584        return killed;
10585    }
10586
10587    @Override
10588    public void killUid(int uid, String reason) {
10589        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10590            throw new SecurityException("killUid only available to the system");
10591        }
10592        synchronized (this) {
10593            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10594                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10595                    reason != null ? reason : "kill uid");
10596        }
10597    }
10598
10599    @Override
10600    public boolean killProcessesBelowForeground(String reason) {
10601        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10602            throw new SecurityException("killProcessesBelowForeground() only available to system");
10603        }
10604
10605        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10606    }
10607
10608    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10609        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10610            throw new SecurityException("killProcessesBelowAdj() only available to system");
10611        }
10612
10613        boolean killed = false;
10614        synchronized (mPidsSelfLocked) {
10615            final int size = mPidsSelfLocked.size();
10616            for (int i = 0; i < size; i++) {
10617                final int pid = mPidsSelfLocked.keyAt(i);
10618                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10619                if (proc == null) continue;
10620
10621                final int adj = proc.setAdj;
10622                if (adj > belowAdj && !proc.killedByAm) {
10623                    proc.kill(reason, true);
10624                    killed = true;
10625                }
10626            }
10627        }
10628        return killed;
10629    }
10630
10631    @Override
10632    public void hang(final IBinder who, boolean allowRestart) {
10633        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10634                != PackageManager.PERMISSION_GRANTED) {
10635            throw new SecurityException("Requires permission "
10636                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10637        }
10638
10639        final IBinder.DeathRecipient death = new DeathRecipient() {
10640            @Override
10641            public void binderDied() {
10642                synchronized (this) {
10643                    notifyAll();
10644                }
10645            }
10646        };
10647
10648        try {
10649            who.linkToDeath(death, 0);
10650        } catch (RemoteException e) {
10651            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10652            return;
10653        }
10654
10655        synchronized (this) {
10656            Watchdog.getInstance().setAllowRestart(allowRestart);
10657            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10658            synchronized (death) {
10659                while (who.isBinderAlive()) {
10660                    try {
10661                        death.wait();
10662                    } catch (InterruptedException e) {
10663                    }
10664                }
10665            }
10666            Watchdog.getInstance().setAllowRestart(true);
10667        }
10668    }
10669
10670    @Override
10671    public void restart() {
10672        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10673                != PackageManager.PERMISSION_GRANTED) {
10674            throw new SecurityException("Requires permission "
10675                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10676        }
10677
10678        Log.i(TAG, "Sending shutdown broadcast...");
10679
10680        BroadcastReceiver br = new BroadcastReceiver() {
10681            @Override public void onReceive(Context context, Intent intent) {
10682                // Now the broadcast is done, finish up the low-level shutdown.
10683                Log.i(TAG, "Shutting down activity manager...");
10684                shutdown(10000);
10685                Log.i(TAG, "Shutdown complete, restarting!");
10686                Process.killProcess(Process.myPid());
10687                System.exit(10);
10688            }
10689        };
10690
10691        // First send the high-level shut down broadcast.
10692        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10693        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10694        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10695        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10696        mContext.sendOrderedBroadcastAsUser(intent,
10697                UserHandle.ALL, null, br, mHandler, 0, null, null);
10698        */
10699        br.onReceive(mContext, intent);
10700    }
10701
10702    private long getLowRamTimeSinceIdle(long now) {
10703        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10704    }
10705
10706    @Override
10707    public void performIdleMaintenance() {
10708        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10709                != PackageManager.PERMISSION_GRANTED) {
10710            throw new SecurityException("Requires permission "
10711                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10712        }
10713
10714        synchronized (this) {
10715            final long now = SystemClock.uptimeMillis();
10716            final long timeSinceLastIdle = now - mLastIdleTime;
10717            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10718            mLastIdleTime = now;
10719            mLowRamTimeSinceLastIdle = 0;
10720            if (mLowRamStartTime != 0) {
10721                mLowRamStartTime = now;
10722            }
10723
10724            StringBuilder sb = new StringBuilder(128);
10725            sb.append("Idle maintenance over ");
10726            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10727            sb.append(" low RAM for ");
10728            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10729            Slog.i(TAG, sb.toString());
10730
10731            // If at least 1/3 of our time since the last idle period has been spent
10732            // with RAM low, then we want to kill processes.
10733            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10734
10735            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10736                ProcessRecord proc = mLruProcesses.get(i);
10737                if (proc.notCachedSinceIdle) {
10738                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10739                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10740                        if (doKilling && proc.initialIdlePss != 0
10741                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10742                            proc.kill("idle maint (pss " + proc.lastPss
10743                                    + " from " + proc.initialIdlePss + ")", true);
10744                        }
10745                    }
10746                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10747                    proc.notCachedSinceIdle = true;
10748                    proc.initialIdlePss = 0;
10749                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10750                            isSleeping(), now);
10751                }
10752            }
10753
10754            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10755            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10756        }
10757    }
10758
10759    private void retrieveSettings() {
10760        final ContentResolver resolver = mContext.getContentResolver();
10761        String debugApp = Settings.Global.getString(
10762            resolver, Settings.Global.DEBUG_APP);
10763        boolean waitForDebugger = Settings.Global.getInt(
10764            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10765        boolean alwaysFinishActivities = Settings.Global.getInt(
10766            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10767        boolean forceRtl = Settings.Global.getInt(
10768                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10769        // Transfer any global setting for forcing RTL layout, into a System Property
10770        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10771
10772        Configuration configuration = new Configuration();
10773        Settings.System.getConfiguration(resolver, configuration);
10774        if (forceRtl) {
10775            // This will take care of setting the correct layout direction flags
10776            configuration.setLayoutDirection(configuration.locale);
10777        }
10778
10779        synchronized (this) {
10780            mDebugApp = mOrigDebugApp = debugApp;
10781            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10782            mAlwaysFinishActivities = alwaysFinishActivities;
10783            // This happens before any activities are started, so we can
10784            // change mConfiguration in-place.
10785            updateConfigurationLocked(configuration, null, false, true);
10786            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10787        }
10788    }
10789
10790    /** Loads resources after the current configuration has been set. */
10791    private void loadResourcesOnSystemReady() {
10792        final Resources res = mContext.getResources();
10793        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10794        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10795        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10796    }
10797
10798    public boolean testIsSystemReady() {
10799        // no need to synchronize(this) just to read & return the value
10800        return mSystemReady;
10801    }
10802
10803    private static File getCalledPreBootReceiversFile() {
10804        File dataDir = Environment.getDataDirectory();
10805        File systemDir = new File(dataDir, "system");
10806        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10807        return fname;
10808    }
10809
10810    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10811        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10812        File file = getCalledPreBootReceiversFile();
10813        FileInputStream fis = null;
10814        try {
10815            fis = new FileInputStream(file);
10816            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10817            int fvers = dis.readInt();
10818            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10819                String vers = dis.readUTF();
10820                String codename = dis.readUTF();
10821                String build = dis.readUTF();
10822                if (android.os.Build.VERSION.RELEASE.equals(vers)
10823                        && android.os.Build.VERSION.CODENAME.equals(codename)
10824                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10825                    int num = dis.readInt();
10826                    while (num > 0) {
10827                        num--;
10828                        String pkg = dis.readUTF();
10829                        String cls = dis.readUTF();
10830                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10831                    }
10832                }
10833            }
10834        } catch (FileNotFoundException e) {
10835        } catch (IOException e) {
10836            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10837        } finally {
10838            if (fis != null) {
10839                try {
10840                    fis.close();
10841                } catch (IOException e) {
10842                }
10843            }
10844        }
10845        return lastDoneReceivers;
10846    }
10847
10848    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10849        File file = getCalledPreBootReceiversFile();
10850        FileOutputStream fos = null;
10851        DataOutputStream dos = null;
10852        try {
10853            fos = new FileOutputStream(file);
10854            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10855            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10856            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10857            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10858            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10859            dos.writeInt(list.size());
10860            for (int i=0; i<list.size(); i++) {
10861                dos.writeUTF(list.get(i).getPackageName());
10862                dos.writeUTF(list.get(i).getClassName());
10863            }
10864        } catch (IOException e) {
10865            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10866            file.delete();
10867        } finally {
10868            FileUtils.sync(fos);
10869            if (dos != null) {
10870                try {
10871                    dos.close();
10872                } catch (IOException e) {
10873                    // TODO Auto-generated catch block
10874                    e.printStackTrace();
10875                }
10876            }
10877        }
10878    }
10879
10880    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10881            ArrayList<ComponentName> doneReceivers, int userId) {
10882        boolean waitingUpdate = false;
10883        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10884        List<ResolveInfo> ris = null;
10885        try {
10886            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10887                    intent, null, 0, userId);
10888        } catch (RemoteException e) {
10889        }
10890        if (ris != null) {
10891            for (int i=ris.size()-1; i>=0; i--) {
10892                if ((ris.get(i).activityInfo.applicationInfo.flags
10893                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10894                    ris.remove(i);
10895                }
10896            }
10897            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10898
10899            // For User 0, load the version number. When delivering to a new user, deliver
10900            // to all receivers.
10901            if (userId == UserHandle.USER_OWNER) {
10902                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10903                for (int i=0; i<ris.size(); i++) {
10904                    ActivityInfo ai = ris.get(i).activityInfo;
10905                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10906                    if (lastDoneReceivers.contains(comp)) {
10907                        // We already did the pre boot receiver for this app with the current
10908                        // platform version, so don't do it again...
10909                        ris.remove(i);
10910                        i--;
10911                        // ...however, do keep it as one that has been done, so we don't
10912                        // forget about it when rewriting the file of last done receivers.
10913                        doneReceivers.add(comp);
10914                    }
10915                }
10916            }
10917
10918            // If primary user, send broadcast to all available users, else just to userId
10919            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10920                    : new int[] { userId };
10921            for (int i = 0; i < ris.size(); i++) {
10922                ActivityInfo ai = ris.get(i).activityInfo;
10923                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10924                doneReceivers.add(comp);
10925                intent.setComponent(comp);
10926                for (int j=0; j<users.length; j++) {
10927                    IIntentReceiver finisher = null;
10928                    // On last receiver and user, set up a completion callback
10929                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10930                        finisher = new IIntentReceiver.Stub() {
10931                            public void performReceive(Intent intent, int resultCode,
10932                                    String data, Bundle extras, boolean ordered,
10933                                    boolean sticky, int sendingUser) {
10934                                // The raw IIntentReceiver interface is called
10935                                // with the AM lock held, so redispatch to
10936                                // execute our code without the lock.
10937                                mHandler.post(onFinishCallback);
10938                            }
10939                        };
10940                    }
10941                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10942                            + " for user " + users[j]);
10943                    broadcastIntentLocked(null, null, intent, null, finisher,
10944                            0, null, null, null, AppOpsManager.OP_NONE,
10945                            true, false, MY_PID, Process.SYSTEM_UID,
10946                            users[j]);
10947                    if (finisher != null) {
10948                        waitingUpdate = true;
10949                    }
10950                }
10951            }
10952        }
10953
10954        return waitingUpdate;
10955    }
10956
10957    public void systemReady(final Runnable goingCallback) {
10958        synchronized(this) {
10959            if (mSystemReady) {
10960                // If we're done calling all the receivers, run the next "boot phase" passed in
10961                // by the SystemServer
10962                if (goingCallback != null) {
10963                    goingCallback.run();
10964                }
10965                return;
10966            }
10967
10968            // Make sure we have the current profile info, since it is needed for
10969            // security checks.
10970            updateCurrentProfileIdsLocked();
10971
10972            if (mRecentTasks == null) {
10973                mRecentTasks = mTaskPersister.restoreTasksLocked();
10974                if (!mRecentTasks.isEmpty()) {
10975                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10976                }
10977                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10978                mTaskPersister.startPersisting();
10979            }
10980
10981            // Check to see if there are any update receivers to run.
10982            if (!mDidUpdate) {
10983                if (mWaitingUpdate) {
10984                    return;
10985                }
10986                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10987                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10988                    public void run() {
10989                        synchronized (ActivityManagerService.this) {
10990                            mDidUpdate = true;
10991                        }
10992                        writeLastDonePreBootReceivers(doneReceivers);
10993                        showBootMessage(mContext.getText(
10994                                R.string.android_upgrading_complete),
10995                                false);
10996                        systemReady(goingCallback);
10997                    }
10998                }, doneReceivers, UserHandle.USER_OWNER);
10999
11000                if (mWaitingUpdate) {
11001                    return;
11002                }
11003                mDidUpdate = true;
11004            }
11005
11006            mAppOpsService.systemReady();
11007            mSystemReady = true;
11008        }
11009
11010        ArrayList<ProcessRecord> procsToKill = null;
11011        synchronized(mPidsSelfLocked) {
11012            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11013                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11014                if (!isAllowedWhileBooting(proc.info)){
11015                    if (procsToKill == null) {
11016                        procsToKill = new ArrayList<ProcessRecord>();
11017                    }
11018                    procsToKill.add(proc);
11019                }
11020            }
11021        }
11022
11023        synchronized(this) {
11024            if (procsToKill != null) {
11025                for (int i=procsToKill.size()-1; i>=0; i--) {
11026                    ProcessRecord proc = procsToKill.get(i);
11027                    Slog.i(TAG, "Removing system update proc: " + proc);
11028                    removeProcessLocked(proc, true, false, "system update done");
11029                }
11030            }
11031
11032            // Now that we have cleaned up any update processes, we
11033            // are ready to start launching real processes and know that
11034            // we won't trample on them any more.
11035            mProcessesReady = true;
11036        }
11037
11038        Slog.i(TAG, "System now ready");
11039        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11040            SystemClock.uptimeMillis());
11041
11042        synchronized(this) {
11043            // Make sure we have no pre-ready processes sitting around.
11044
11045            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11046                ResolveInfo ri = mContext.getPackageManager()
11047                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11048                                STOCK_PM_FLAGS);
11049                CharSequence errorMsg = null;
11050                if (ri != null) {
11051                    ActivityInfo ai = ri.activityInfo;
11052                    ApplicationInfo app = ai.applicationInfo;
11053                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11054                        mTopAction = Intent.ACTION_FACTORY_TEST;
11055                        mTopData = null;
11056                        mTopComponent = new ComponentName(app.packageName,
11057                                ai.name);
11058                    } else {
11059                        errorMsg = mContext.getResources().getText(
11060                                com.android.internal.R.string.factorytest_not_system);
11061                    }
11062                } else {
11063                    errorMsg = mContext.getResources().getText(
11064                            com.android.internal.R.string.factorytest_no_action);
11065                }
11066                if (errorMsg != null) {
11067                    mTopAction = null;
11068                    mTopData = null;
11069                    mTopComponent = null;
11070                    Message msg = Message.obtain();
11071                    msg.what = SHOW_FACTORY_ERROR_MSG;
11072                    msg.getData().putCharSequence("msg", errorMsg);
11073                    mHandler.sendMessage(msg);
11074                }
11075            }
11076        }
11077
11078        retrieveSettings();
11079        loadResourcesOnSystemReady();
11080
11081        synchronized (this) {
11082            readGrantedUriPermissionsLocked();
11083        }
11084
11085        if (goingCallback != null) goingCallback.run();
11086
11087        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11088                Integer.toString(mCurrentUserId), mCurrentUserId);
11089        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11090                Integer.toString(mCurrentUserId), mCurrentUserId);
11091        mSystemServiceManager.startUser(mCurrentUserId);
11092
11093        synchronized (this) {
11094            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11095                try {
11096                    List apps = AppGlobals.getPackageManager().
11097                        getPersistentApplications(STOCK_PM_FLAGS);
11098                    if (apps != null) {
11099                        int N = apps.size();
11100                        int i;
11101                        for (i=0; i<N; i++) {
11102                            ApplicationInfo info
11103                                = (ApplicationInfo)apps.get(i);
11104                            if (info != null &&
11105                                    !info.packageName.equals("android")) {
11106                                addAppLocked(info, false, null /* ABI override */);
11107                            }
11108                        }
11109                    }
11110                } catch (RemoteException ex) {
11111                    // pm is in same process, this will never happen.
11112                }
11113            }
11114
11115            // Start up initial activity.
11116            mBooting = true;
11117
11118            try {
11119                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11120                    Message msg = Message.obtain();
11121                    msg.what = SHOW_UID_ERROR_MSG;
11122                    mHandler.sendMessage(msg);
11123                }
11124            } catch (RemoteException e) {
11125            }
11126
11127            long ident = Binder.clearCallingIdentity();
11128            try {
11129                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11130                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11131                        | Intent.FLAG_RECEIVER_FOREGROUND);
11132                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11133                broadcastIntentLocked(null, null, intent,
11134                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11135                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11136                intent = new Intent(Intent.ACTION_USER_STARTING);
11137                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11138                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11139                broadcastIntentLocked(null, null, intent,
11140                        null, new IIntentReceiver.Stub() {
11141                            @Override
11142                            public void performReceive(Intent intent, int resultCode, String data,
11143                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11144                                    throws RemoteException {
11145                            }
11146                        }, 0, null, null,
11147                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11148                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11149            } catch (Throwable t) {
11150                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11151            } finally {
11152                Binder.restoreCallingIdentity(ident);
11153            }
11154            mStackSupervisor.resumeTopActivitiesLocked();
11155            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11156        }
11157    }
11158
11159    private boolean makeAppCrashingLocked(ProcessRecord app,
11160            String shortMsg, String longMsg, String stackTrace) {
11161        app.crashing = true;
11162        app.crashingReport = generateProcessError(app,
11163                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11164        startAppProblemLocked(app);
11165        app.stopFreezingAllLocked();
11166        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11167    }
11168
11169    private void makeAppNotRespondingLocked(ProcessRecord app,
11170            String activity, String shortMsg, String longMsg) {
11171        app.notResponding = true;
11172        app.notRespondingReport = generateProcessError(app,
11173                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11174                activity, shortMsg, longMsg, null);
11175        startAppProblemLocked(app);
11176        app.stopFreezingAllLocked();
11177    }
11178
11179    /**
11180     * Generate a process error record, suitable for attachment to a ProcessRecord.
11181     *
11182     * @param app The ProcessRecord in which the error occurred.
11183     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11184     *                      ActivityManager.AppErrorStateInfo
11185     * @param activity The activity associated with the crash, if known.
11186     * @param shortMsg Short message describing the crash.
11187     * @param longMsg Long message describing the crash.
11188     * @param stackTrace Full crash stack trace, may be null.
11189     *
11190     * @return Returns a fully-formed AppErrorStateInfo record.
11191     */
11192    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11193            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11194        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11195
11196        report.condition = condition;
11197        report.processName = app.processName;
11198        report.pid = app.pid;
11199        report.uid = app.info.uid;
11200        report.tag = activity;
11201        report.shortMsg = shortMsg;
11202        report.longMsg = longMsg;
11203        report.stackTrace = stackTrace;
11204
11205        return report;
11206    }
11207
11208    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11209        synchronized (this) {
11210            app.crashing = false;
11211            app.crashingReport = null;
11212            app.notResponding = false;
11213            app.notRespondingReport = null;
11214            if (app.anrDialog == fromDialog) {
11215                app.anrDialog = null;
11216            }
11217            if (app.waitDialog == fromDialog) {
11218                app.waitDialog = null;
11219            }
11220            if (app.pid > 0 && app.pid != MY_PID) {
11221                handleAppCrashLocked(app, null, null, null);
11222                app.kill("user request after error", true);
11223            }
11224        }
11225    }
11226
11227    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11228            String stackTrace) {
11229        long now = SystemClock.uptimeMillis();
11230
11231        Long crashTime;
11232        if (!app.isolated) {
11233            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11234        } else {
11235            crashTime = null;
11236        }
11237        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11238            // This process loses!
11239            Slog.w(TAG, "Process " + app.info.processName
11240                    + " has crashed too many times: killing!");
11241            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11242                    app.userId, app.info.processName, app.uid);
11243            mStackSupervisor.handleAppCrashLocked(app);
11244            if (!app.persistent) {
11245                // We don't want to start this process again until the user
11246                // explicitly does so...  but for persistent process, we really
11247                // need to keep it running.  If a persistent process is actually
11248                // repeatedly crashing, then badness for everyone.
11249                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11250                        app.info.processName);
11251                if (!app.isolated) {
11252                    // XXX We don't have a way to mark isolated processes
11253                    // as bad, since they don't have a peristent identity.
11254                    mBadProcesses.put(app.info.processName, app.uid,
11255                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11256                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11257                }
11258                app.bad = true;
11259                app.removed = true;
11260                // Don't let services in this process be restarted and potentially
11261                // annoy the user repeatedly.  Unless it is persistent, since those
11262                // processes run critical code.
11263                removeProcessLocked(app, false, false, "crash");
11264                mStackSupervisor.resumeTopActivitiesLocked();
11265                return false;
11266            }
11267            mStackSupervisor.resumeTopActivitiesLocked();
11268        } else {
11269            mStackSupervisor.finishTopRunningActivityLocked(app);
11270        }
11271
11272        // Bump up the crash count of any services currently running in the proc.
11273        for (int i=app.services.size()-1; i>=0; i--) {
11274            // Any services running in the application need to be placed
11275            // back in the pending list.
11276            ServiceRecord sr = app.services.valueAt(i);
11277            sr.crashCount++;
11278        }
11279
11280        // If the crashing process is what we consider to be the "home process" and it has been
11281        // replaced by a third-party app, clear the package preferred activities from packages
11282        // with a home activity running in the process to prevent a repeatedly crashing app
11283        // from blocking the user to manually clear the list.
11284        final ArrayList<ActivityRecord> activities = app.activities;
11285        if (app == mHomeProcess && activities.size() > 0
11286                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11287            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11288                final ActivityRecord r = activities.get(activityNdx);
11289                if (r.isHomeActivity()) {
11290                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11291                    try {
11292                        ActivityThread.getPackageManager()
11293                                .clearPackagePreferredActivities(r.packageName);
11294                    } catch (RemoteException c) {
11295                        // pm is in same process, this will never happen.
11296                    }
11297                }
11298            }
11299        }
11300
11301        if (!app.isolated) {
11302            // XXX Can't keep track of crash times for isolated processes,
11303            // because they don't have a perisistent identity.
11304            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11305        }
11306
11307        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11308        return true;
11309    }
11310
11311    void startAppProblemLocked(ProcessRecord app) {
11312        // If this app is not running under the current user, then we
11313        // can't give it a report button because that would require
11314        // launching the report UI under a different user.
11315        app.errorReportReceiver = null;
11316
11317        for (int userId : mCurrentProfileIds) {
11318            if (app.userId == userId) {
11319                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11320                        mContext, app.info.packageName, app.info.flags);
11321            }
11322        }
11323        skipCurrentReceiverLocked(app);
11324    }
11325
11326    void skipCurrentReceiverLocked(ProcessRecord app) {
11327        for (BroadcastQueue queue : mBroadcastQueues) {
11328            queue.skipCurrentReceiverLocked(app);
11329        }
11330    }
11331
11332    /**
11333     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11334     * The application process will exit immediately after this call returns.
11335     * @param app object of the crashing app, null for the system server
11336     * @param crashInfo describing the exception
11337     */
11338    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11339        ProcessRecord r = findAppProcess(app, "Crash");
11340        final String processName = app == null ? "system_server"
11341                : (r == null ? "unknown" : r.processName);
11342
11343        handleApplicationCrashInner("crash", r, processName, crashInfo);
11344    }
11345
11346    /* Native crash reporting uses this inner version because it needs to be somewhat
11347     * decoupled from the AM-managed cleanup lifecycle
11348     */
11349    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11350            ApplicationErrorReport.CrashInfo crashInfo) {
11351        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11352                UserHandle.getUserId(Binder.getCallingUid()), processName,
11353                r == null ? -1 : r.info.flags,
11354                crashInfo.exceptionClassName,
11355                crashInfo.exceptionMessage,
11356                crashInfo.throwFileName,
11357                crashInfo.throwLineNumber);
11358
11359        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11360
11361        crashApplication(r, crashInfo);
11362    }
11363
11364    public void handleApplicationStrictModeViolation(
11365            IBinder app,
11366            int violationMask,
11367            StrictMode.ViolationInfo info) {
11368        ProcessRecord r = findAppProcess(app, "StrictMode");
11369        if (r == null) {
11370            return;
11371        }
11372
11373        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11374            Integer stackFingerprint = info.hashCode();
11375            boolean logIt = true;
11376            synchronized (mAlreadyLoggedViolatedStacks) {
11377                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11378                    logIt = false;
11379                    // TODO: sub-sample into EventLog for these, with
11380                    // the info.durationMillis?  Then we'd get
11381                    // the relative pain numbers, without logging all
11382                    // the stack traces repeatedly.  We'd want to do
11383                    // likewise in the client code, which also does
11384                    // dup suppression, before the Binder call.
11385                } else {
11386                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11387                        mAlreadyLoggedViolatedStacks.clear();
11388                    }
11389                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11390                }
11391            }
11392            if (logIt) {
11393                logStrictModeViolationToDropBox(r, info);
11394            }
11395        }
11396
11397        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11398            AppErrorResult result = new AppErrorResult();
11399            synchronized (this) {
11400                final long origId = Binder.clearCallingIdentity();
11401
11402                Message msg = Message.obtain();
11403                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11404                HashMap<String, Object> data = new HashMap<String, Object>();
11405                data.put("result", result);
11406                data.put("app", r);
11407                data.put("violationMask", violationMask);
11408                data.put("info", info);
11409                msg.obj = data;
11410                mHandler.sendMessage(msg);
11411
11412                Binder.restoreCallingIdentity(origId);
11413            }
11414            int res = result.get();
11415            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11416        }
11417    }
11418
11419    // Depending on the policy in effect, there could be a bunch of
11420    // these in quick succession so we try to batch these together to
11421    // minimize disk writes, number of dropbox entries, and maximize
11422    // compression, by having more fewer, larger records.
11423    private void logStrictModeViolationToDropBox(
11424            ProcessRecord process,
11425            StrictMode.ViolationInfo info) {
11426        if (info == null) {
11427            return;
11428        }
11429        final boolean isSystemApp = process == null ||
11430                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11431                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11432        final String processName = process == null ? "unknown" : process.processName;
11433        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11434        final DropBoxManager dbox = (DropBoxManager)
11435                mContext.getSystemService(Context.DROPBOX_SERVICE);
11436
11437        // Exit early if the dropbox isn't configured to accept this report type.
11438        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11439
11440        boolean bufferWasEmpty;
11441        boolean needsFlush;
11442        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11443        synchronized (sb) {
11444            bufferWasEmpty = sb.length() == 0;
11445            appendDropBoxProcessHeaders(process, processName, sb);
11446            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11447            sb.append("System-App: ").append(isSystemApp).append("\n");
11448            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11449            if (info.violationNumThisLoop != 0) {
11450                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11451            }
11452            if (info.numAnimationsRunning != 0) {
11453                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11454            }
11455            if (info.broadcastIntentAction != null) {
11456                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11457            }
11458            if (info.durationMillis != -1) {
11459                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11460            }
11461            if (info.numInstances != -1) {
11462                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11463            }
11464            if (info.tags != null) {
11465                for (String tag : info.tags) {
11466                    sb.append("Span-Tag: ").append(tag).append("\n");
11467                }
11468            }
11469            sb.append("\n");
11470            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11471                sb.append(info.crashInfo.stackTrace);
11472            }
11473            sb.append("\n");
11474
11475            // Only buffer up to ~64k.  Various logging bits truncate
11476            // things at 128k.
11477            needsFlush = (sb.length() > 64 * 1024);
11478        }
11479
11480        // Flush immediately if the buffer's grown too large, or this
11481        // is a non-system app.  Non-system apps are isolated with a
11482        // different tag & policy and not batched.
11483        //
11484        // Batching is useful during internal testing with
11485        // StrictMode settings turned up high.  Without batching,
11486        // thousands of separate files could be created on boot.
11487        if (!isSystemApp || needsFlush) {
11488            new Thread("Error dump: " + dropboxTag) {
11489                @Override
11490                public void run() {
11491                    String report;
11492                    synchronized (sb) {
11493                        report = sb.toString();
11494                        sb.delete(0, sb.length());
11495                        sb.trimToSize();
11496                    }
11497                    if (report.length() != 0) {
11498                        dbox.addText(dropboxTag, report);
11499                    }
11500                }
11501            }.start();
11502            return;
11503        }
11504
11505        // System app batching:
11506        if (!bufferWasEmpty) {
11507            // An existing dropbox-writing thread is outstanding, so
11508            // we don't need to start it up.  The existing thread will
11509            // catch the buffer appends we just did.
11510            return;
11511        }
11512
11513        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11514        // (After this point, we shouldn't access AMS internal data structures.)
11515        new Thread("Error dump: " + dropboxTag) {
11516            @Override
11517            public void run() {
11518                // 5 second sleep to let stacks arrive and be batched together
11519                try {
11520                    Thread.sleep(5000);  // 5 seconds
11521                } catch (InterruptedException e) {}
11522
11523                String errorReport;
11524                synchronized (mStrictModeBuffer) {
11525                    errorReport = mStrictModeBuffer.toString();
11526                    if (errorReport.length() == 0) {
11527                        return;
11528                    }
11529                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11530                    mStrictModeBuffer.trimToSize();
11531                }
11532                dbox.addText(dropboxTag, errorReport);
11533            }
11534        }.start();
11535    }
11536
11537    /**
11538     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11539     * @param app object of the crashing app, null for the system server
11540     * @param tag reported by the caller
11541     * @param system whether this wtf is coming from the system
11542     * @param crashInfo describing the context of the error
11543     * @return true if the process should exit immediately (WTF is fatal)
11544     */
11545    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11546            final ApplicationErrorReport.CrashInfo crashInfo) {
11547        final ProcessRecord r = findAppProcess(app, "WTF");
11548        final String processName = app == null ? "system_server"
11549                : (r == null ? "unknown" : r.processName);
11550
11551        EventLog.writeEvent(EventLogTags.AM_WTF,
11552                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11553                processName,
11554                r == null ? -1 : r.info.flags,
11555                tag, crashInfo.exceptionMessage);
11556
11557        if (system) {
11558            // If this is coming from the system, we could very well have low-level
11559            // system locks held, so we want to do this all asynchronously.  And we
11560            // never want this to become fatal, so there is that too.
11561            mHandler.post(new Runnable() {
11562                @Override public void run() {
11563                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11564                            crashInfo);
11565                }
11566            });
11567            return false;
11568        }
11569
11570        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11571
11572        if (r != null && r.pid != Process.myPid() &&
11573                Settings.Global.getInt(mContext.getContentResolver(),
11574                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11575            crashApplication(r, crashInfo);
11576            return true;
11577        } else {
11578            return false;
11579        }
11580    }
11581
11582    /**
11583     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11584     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11585     */
11586    private ProcessRecord findAppProcess(IBinder app, String reason) {
11587        if (app == null) {
11588            return null;
11589        }
11590
11591        synchronized (this) {
11592            final int NP = mProcessNames.getMap().size();
11593            for (int ip=0; ip<NP; ip++) {
11594                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11595                final int NA = apps.size();
11596                for (int ia=0; ia<NA; ia++) {
11597                    ProcessRecord p = apps.valueAt(ia);
11598                    if (p.thread != null && p.thread.asBinder() == app) {
11599                        return p;
11600                    }
11601                }
11602            }
11603
11604            Slog.w(TAG, "Can't find mystery application for " + reason
11605                    + " from pid=" + Binder.getCallingPid()
11606                    + " uid=" + Binder.getCallingUid() + ": " + app);
11607            return null;
11608        }
11609    }
11610
11611    /**
11612     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11613     * to append various headers to the dropbox log text.
11614     */
11615    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11616            StringBuilder sb) {
11617        // Watchdog thread ends up invoking this function (with
11618        // a null ProcessRecord) to add the stack file to dropbox.
11619        // Do not acquire a lock on this (am) in such cases, as it
11620        // could cause a potential deadlock, if and when watchdog
11621        // is invoked due to unavailability of lock on am and it
11622        // would prevent watchdog from killing system_server.
11623        if (process == null) {
11624            sb.append("Process: ").append(processName).append("\n");
11625            return;
11626        }
11627        // Note: ProcessRecord 'process' is guarded by the service
11628        // instance.  (notably process.pkgList, which could otherwise change
11629        // concurrently during execution of this method)
11630        synchronized (this) {
11631            sb.append("Process: ").append(processName).append("\n");
11632            int flags = process.info.flags;
11633            IPackageManager pm = AppGlobals.getPackageManager();
11634            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11635            for (int ip=0; ip<process.pkgList.size(); ip++) {
11636                String pkg = process.pkgList.keyAt(ip);
11637                sb.append("Package: ").append(pkg);
11638                try {
11639                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11640                    if (pi != null) {
11641                        sb.append(" v").append(pi.versionCode);
11642                        if (pi.versionName != null) {
11643                            sb.append(" (").append(pi.versionName).append(")");
11644                        }
11645                    }
11646                } catch (RemoteException e) {
11647                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11648                }
11649                sb.append("\n");
11650            }
11651        }
11652    }
11653
11654    private static String processClass(ProcessRecord process) {
11655        if (process == null || process.pid == MY_PID) {
11656            return "system_server";
11657        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11658            return "system_app";
11659        } else {
11660            return "data_app";
11661        }
11662    }
11663
11664    /**
11665     * Write a description of an error (crash, WTF, ANR) to the drop box.
11666     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11667     * @param process which caused the error, null means the system server
11668     * @param activity which triggered the error, null if unknown
11669     * @param parent activity related to the error, null if unknown
11670     * @param subject line related to the error, null if absent
11671     * @param report in long form describing the error, null if absent
11672     * @param logFile to include in the report, null if none
11673     * @param crashInfo giving an application stack trace, null if absent
11674     */
11675    public void addErrorToDropBox(String eventType,
11676            ProcessRecord process, String processName, ActivityRecord activity,
11677            ActivityRecord parent, String subject,
11678            final String report, final File logFile,
11679            final ApplicationErrorReport.CrashInfo crashInfo) {
11680        // NOTE -- this must never acquire the ActivityManagerService lock,
11681        // otherwise the watchdog may be prevented from resetting the system.
11682
11683        final String dropboxTag = processClass(process) + "_" + eventType;
11684        final DropBoxManager dbox = (DropBoxManager)
11685                mContext.getSystemService(Context.DROPBOX_SERVICE);
11686
11687        // Exit early if the dropbox isn't configured to accept this report type.
11688        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11689
11690        final StringBuilder sb = new StringBuilder(1024);
11691        appendDropBoxProcessHeaders(process, processName, sb);
11692        if (activity != null) {
11693            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11694        }
11695        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11696            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11697        }
11698        if (parent != null && parent != activity) {
11699            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11700        }
11701        if (subject != null) {
11702            sb.append("Subject: ").append(subject).append("\n");
11703        }
11704        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11705        if (Debug.isDebuggerConnected()) {
11706            sb.append("Debugger: Connected\n");
11707        }
11708        sb.append("\n");
11709
11710        // Do the rest in a worker thread to avoid blocking the caller on I/O
11711        // (After this point, we shouldn't access AMS internal data structures.)
11712        Thread worker = new Thread("Error dump: " + dropboxTag) {
11713            @Override
11714            public void run() {
11715                if (report != null) {
11716                    sb.append(report);
11717                }
11718                if (logFile != null) {
11719                    try {
11720                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11721                                    "\n\n[[TRUNCATED]]"));
11722                    } catch (IOException e) {
11723                        Slog.e(TAG, "Error reading " + logFile, e);
11724                    }
11725                }
11726                if (crashInfo != null && crashInfo.stackTrace != null) {
11727                    sb.append(crashInfo.stackTrace);
11728                }
11729
11730                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11731                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11732                if (lines > 0) {
11733                    sb.append("\n");
11734
11735                    // Merge several logcat streams, and take the last N lines
11736                    InputStreamReader input = null;
11737                    try {
11738                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11739                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11740                                "-b", "crash",
11741                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11742
11743                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11744                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11745                        input = new InputStreamReader(logcat.getInputStream());
11746
11747                        int num;
11748                        char[] buf = new char[8192];
11749                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11750                    } catch (IOException e) {
11751                        Slog.e(TAG, "Error running logcat", e);
11752                    } finally {
11753                        if (input != null) try { input.close(); } catch (IOException e) {}
11754                    }
11755                }
11756
11757                dbox.addText(dropboxTag, sb.toString());
11758            }
11759        };
11760
11761        if (process == null) {
11762            // If process is null, we are being called from some internal code
11763            // and may be about to die -- run this synchronously.
11764            worker.run();
11765        } else {
11766            worker.start();
11767        }
11768    }
11769
11770    /**
11771     * Bring up the "unexpected error" dialog box for a crashing app.
11772     * Deal with edge cases (intercepts from instrumented applications,
11773     * ActivityController, error intent receivers, that sort of thing).
11774     * @param r the application crashing
11775     * @param crashInfo describing the failure
11776     */
11777    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11778        long timeMillis = System.currentTimeMillis();
11779        String shortMsg = crashInfo.exceptionClassName;
11780        String longMsg = crashInfo.exceptionMessage;
11781        String stackTrace = crashInfo.stackTrace;
11782        if (shortMsg != null && longMsg != null) {
11783            longMsg = shortMsg + ": " + longMsg;
11784        } else if (shortMsg != null) {
11785            longMsg = shortMsg;
11786        }
11787
11788        AppErrorResult result = new AppErrorResult();
11789        synchronized (this) {
11790            if (mController != null) {
11791                try {
11792                    String name = r != null ? r.processName : null;
11793                    int pid = r != null ? r.pid : Binder.getCallingPid();
11794                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11795                    if (!mController.appCrashed(name, pid,
11796                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11797                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11798                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11799                            Slog.w(TAG, "Skip killing native crashed app " + name
11800                                    + "(" + pid + ") during testing");
11801                        } else {
11802                            Slog.w(TAG, "Force-killing crashed app " + name
11803                                    + " at watcher's request");
11804                            if (r != null) {
11805                                r.kill("crash", true);
11806                            } else {
11807                                // Huh.
11808                                Process.killProcess(pid);
11809                                Process.killProcessGroup(uid, pid);
11810                            }
11811                        }
11812                        return;
11813                    }
11814                } catch (RemoteException e) {
11815                    mController = null;
11816                    Watchdog.getInstance().setActivityController(null);
11817                }
11818            }
11819
11820            final long origId = Binder.clearCallingIdentity();
11821
11822            // If this process is running instrumentation, finish it.
11823            if (r != null && r.instrumentationClass != null) {
11824                Slog.w(TAG, "Error in app " + r.processName
11825                      + " running instrumentation " + r.instrumentationClass + ":");
11826                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11827                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11828                Bundle info = new Bundle();
11829                info.putString("shortMsg", shortMsg);
11830                info.putString("longMsg", longMsg);
11831                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11832                Binder.restoreCallingIdentity(origId);
11833                return;
11834            }
11835
11836            // If we can't identify the process or it's already exceeded its crash quota,
11837            // quit right away without showing a crash dialog.
11838            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11839                Binder.restoreCallingIdentity(origId);
11840                return;
11841            }
11842
11843            Message msg = Message.obtain();
11844            msg.what = SHOW_ERROR_MSG;
11845            HashMap data = new HashMap();
11846            data.put("result", result);
11847            data.put("app", r);
11848            msg.obj = data;
11849            mHandler.sendMessage(msg);
11850
11851            Binder.restoreCallingIdentity(origId);
11852        }
11853
11854        int res = result.get();
11855
11856        Intent appErrorIntent = null;
11857        synchronized (this) {
11858            if (r != null && !r.isolated) {
11859                // XXX Can't keep track of crash time for isolated processes,
11860                // since they don't have a persistent identity.
11861                mProcessCrashTimes.put(r.info.processName, r.uid,
11862                        SystemClock.uptimeMillis());
11863            }
11864            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11865                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11866            }
11867        }
11868
11869        if (appErrorIntent != null) {
11870            try {
11871                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11872            } catch (ActivityNotFoundException e) {
11873                Slog.w(TAG, "bug report receiver dissappeared", e);
11874            }
11875        }
11876    }
11877
11878    Intent createAppErrorIntentLocked(ProcessRecord r,
11879            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11880        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11881        if (report == null) {
11882            return null;
11883        }
11884        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11885        result.setComponent(r.errorReportReceiver);
11886        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11887        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11888        return result;
11889    }
11890
11891    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11892            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11893        if (r.errorReportReceiver == null) {
11894            return null;
11895        }
11896
11897        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11898            return null;
11899        }
11900
11901        ApplicationErrorReport report = new ApplicationErrorReport();
11902        report.packageName = r.info.packageName;
11903        report.installerPackageName = r.errorReportReceiver.getPackageName();
11904        report.processName = r.processName;
11905        report.time = timeMillis;
11906        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11907
11908        if (r.crashing || r.forceCrashReport) {
11909            report.type = ApplicationErrorReport.TYPE_CRASH;
11910            report.crashInfo = crashInfo;
11911        } else if (r.notResponding) {
11912            report.type = ApplicationErrorReport.TYPE_ANR;
11913            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11914
11915            report.anrInfo.activity = r.notRespondingReport.tag;
11916            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11917            report.anrInfo.info = r.notRespondingReport.longMsg;
11918        }
11919
11920        return report;
11921    }
11922
11923    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11924        enforceNotIsolatedCaller("getProcessesInErrorState");
11925        // assume our apps are happy - lazy create the list
11926        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11927
11928        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11929                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11930        int userId = UserHandle.getUserId(Binder.getCallingUid());
11931
11932        synchronized (this) {
11933
11934            // iterate across all processes
11935            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11936                ProcessRecord app = mLruProcesses.get(i);
11937                if (!allUsers && app.userId != userId) {
11938                    continue;
11939                }
11940                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11941                    // This one's in trouble, so we'll generate a report for it
11942                    // crashes are higher priority (in case there's a crash *and* an anr)
11943                    ActivityManager.ProcessErrorStateInfo report = null;
11944                    if (app.crashing) {
11945                        report = app.crashingReport;
11946                    } else if (app.notResponding) {
11947                        report = app.notRespondingReport;
11948                    }
11949
11950                    if (report != null) {
11951                        if (errList == null) {
11952                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11953                        }
11954                        errList.add(report);
11955                    } else {
11956                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11957                                " crashing = " + app.crashing +
11958                                " notResponding = " + app.notResponding);
11959                    }
11960                }
11961            }
11962        }
11963
11964        return errList;
11965    }
11966
11967    static int procStateToImportance(int procState, int memAdj,
11968            ActivityManager.RunningAppProcessInfo currApp) {
11969        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11970        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11971            currApp.lru = memAdj;
11972        } else {
11973            currApp.lru = 0;
11974        }
11975        return imp;
11976    }
11977
11978    private void fillInProcMemInfo(ProcessRecord app,
11979            ActivityManager.RunningAppProcessInfo outInfo) {
11980        outInfo.pid = app.pid;
11981        outInfo.uid = app.info.uid;
11982        if (mHeavyWeightProcess == app) {
11983            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11984        }
11985        if (app.persistent) {
11986            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11987        }
11988        if (app.activities.size() > 0) {
11989            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11990        }
11991        outInfo.lastTrimLevel = app.trimMemoryLevel;
11992        int adj = app.curAdj;
11993        int procState = app.curProcState;
11994        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11995        outInfo.importanceReasonCode = app.adjTypeCode;
11996        outInfo.processState = app.curProcState;
11997    }
11998
11999    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12000        enforceNotIsolatedCaller("getRunningAppProcesses");
12001        // Lazy instantiation of list
12002        List<ActivityManager.RunningAppProcessInfo> runList = null;
12003        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12004                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12005        int userId = UserHandle.getUserId(Binder.getCallingUid());
12006        synchronized (this) {
12007            // Iterate across all processes
12008            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12009                ProcessRecord app = mLruProcesses.get(i);
12010                if (!allUsers && app.userId != userId) {
12011                    continue;
12012                }
12013                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12014                    // Generate process state info for running application
12015                    ActivityManager.RunningAppProcessInfo currApp =
12016                        new ActivityManager.RunningAppProcessInfo(app.processName,
12017                                app.pid, app.getPackageList());
12018                    fillInProcMemInfo(app, currApp);
12019                    if (app.adjSource instanceof ProcessRecord) {
12020                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12021                        currApp.importanceReasonImportance =
12022                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12023                                        app.adjSourceProcState);
12024                    } else if (app.adjSource instanceof ActivityRecord) {
12025                        ActivityRecord r = (ActivityRecord)app.adjSource;
12026                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12027                    }
12028                    if (app.adjTarget instanceof ComponentName) {
12029                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12030                    }
12031                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12032                    //        + " lru=" + currApp.lru);
12033                    if (runList == null) {
12034                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12035                    }
12036                    runList.add(currApp);
12037                }
12038            }
12039        }
12040        return runList;
12041    }
12042
12043    public List<ApplicationInfo> getRunningExternalApplications() {
12044        enforceNotIsolatedCaller("getRunningExternalApplications");
12045        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12046        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12047        if (runningApps != null && runningApps.size() > 0) {
12048            Set<String> extList = new HashSet<String>();
12049            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12050                if (app.pkgList != null) {
12051                    for (String pkg : app.pkgList) {
12052                        extList.add(pkg);
12053                    }
12054                }
12055            }
12056            IPackageManager pm = AppGlobals.getPackageManager();
12057            for (String pkg : extList) {
12058                try {
12059                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12060                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12061                        retList.add(info);
12062                    }
12063                } catch (RemoteException e) {
12064                }
12065            }
12066        }
12067        return retList;
12068    }
12069
12070    @Override
12071    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12072        enforceNotIsolatedCaller("getMyMemoryState");
12073        synchronized (this) {
12074            ProcessRecord proc;
12075            synchronized (mPidsSelfLocked) {
12076                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12077            }
12078            fillInProcMemInfo(proc, outInfo);
12079        }
12080    }
12081
12082    @Override
12083    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12084        if (checkCallingPermission(android.Manifest.permission.DUMP)
12085                != PackageManager.PERMISSION_GRANTED) {
12086            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12087                    + Binder.getCallingPid()
12088                    + ", uid=" + Binder.getCallingUid()
12089                    + " without permission "
12090                    + android.Manifest.permission.DUMP);
12091            return;
12092        }
12093
12094        boolean dumpAll = false;
12095        boolean dumpClient = false;
12096        String dumpPackage = null;
12097
12098        int opti = 0;
12099        while (opti < args.length) {
12100            String opt = args[opti];
12101            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12102                break;
12103            }
12104            opti++;
12105            if ("-a".equals(opt)) {
12106                dumpAll = true;
12107            } else if ("-c".equals(opt)) {
12108                dumpClient = true;
12109            } else if ("-h".equals(opt)) {
12110                pw.println("Activity manager dump options:");
12111                pw.println("  [-a] [-c] [-h] [cmd] ...");
12112                pw.println("  cmd may be one of:");
12113                pw.println("    a[ctivities]: activity stack state");
12114                pw.println("    r[recents]: recent activities state");
12115                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12116                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12117                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12118                pw.println("    o[om]: out of memory management");
12119                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12120                pw.println("    provider [COMP_SPEC]: provider client-side state");
12121                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12122                pw.println("    service [COMP_SPEC]: service client-side state");
12123                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12124                pw.println("    all: dump all activities");
12125                pw.println("    top: dump the top activity");
12126                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12127                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12128                pw.println("    a partial substring in a component name, a");
12129                pw.println("    hex object identifier.");
12130                pw.println("  -a: include all available server state.");
12131                pw.println("  -c: include client state.");
12132                return;
12133            } else {
12134                pw.println("Unknown argument: " + opt + "; use -h for help");
12135            }
12136        }
12137
12138        long origId = Binder.clearCallingIdentity();
12139        boolean more = false;
12140        // Is the caller requesting to dump a particular piece of data?
12141        if (opti < args.length) {
12142            String cmd = args[opti];
12143            opti++;
12144            if ("activities".equals(cmd) || "a".equals(cmd)) {
12145                synchronized (this) {
12146                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12147                }
12148            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12149                synchronized (this) {
12150                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12151                }
12152            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12153                String[] newArgs;
12154                String name;
12155                if (opti >= args.length) {
12156                    name = null;
12157                    newArgs = EMPTY_STRING_ARRAY;
12158                } else {
12159                    name = args[opti];
12160                    opti++;
12161                    newArgs = new String[args.length - opti];
12162                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12163                            args.length - opti);
12164                }
12165                synchronized (this) {
12166                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12167                }
12168            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12169                String[] newArgs;
12170                String name;
12171                if (opti >= args.length) {
12172                    name = null;
12173                    newArgs = EMPTY_STRING_ARRAY;
12174                } else {
12175                    name = args[opti];
12176                    opti++;
12177                    newArgs = new String[args.length - opti];
12178                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12179                            args.length - opti);
12180                }
12181                synchronized (this) {
12182                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12183                }
12184            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12185                String[] newArgs;
12186                String name;
12187                if (opti >= args.length) {
12188                    name = null;
12189                    newArgs = EMPTY_STRING_ARRAY;
12190                } else {
12191                    name = args[opti];
12192                    opti++;
12193                    newArgs = new String[args.length - opti];
12194                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12195                            args.length - opti);
12196                }
12197                synchronized (this) {
12198                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12199                }
12200            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12201                synchronized (this) {
12202                    dumpOomLocked(fd, pw, args, opti, true);
12203                }
12204            } else if ("provider".equals(cmd)) {
12205                String[] newArgs;
12206                String name;
12207                if (opti >= args.length) {
12208                    name = null;
12209                    newArgs = EMPTY_STRING_ARRAY;
12210                } else {
12211                    name = args[opti];
12212                    opti++;
12213                    newArgs = new String[args.length - opti];
12214                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12215                }
12216                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12217                    pw.println("No providers match: " + name);
12218                    pw.println("Use -h for help.");
12219                }
12220            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12221                synchronized (this) {
12222                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12223                }
12224            } else if ("service".equals(cmd)) {
12225                String[] newArgs;
12226                String name;
12227                if (opti >= args.length) {
12228                    name = null;
12229                    newArgs = EMPTY_STRING_ARRAY;
12230                } else {
12231                    name = args[opti];
12232                    opti++;
12233                    newArgs = new String[args.length - opti];
12234                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12235                            args.length - opti);
12236                }
12237                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12238                    pw.println("No services match: " + name);
12239                    pw.println("Use -h for help.");
12240                }
12241            } else if ("package".equals(cmd)) {
12242                String[] newArgs;
12243                if (opti >= args.length) {
12244                    pw.println("package: no package name specified");
12245                    pw.println("Use -h for help.");
12246                } else {
12247                    dumpPackage = args[opti];
12248                    opti++;
12249                    newArgs = new String[args.length - opti];
12250                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12251                            args.length - opti);
12252                    args = newArgs;
12253                    opti = 0;
12254                    more = true;
12255                }
12256            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12257                synchronized (this) {
12258                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12259                }
12260            } else {
12261                // Dumping a single activity?
12262                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12263                    pw.println("Bad activity command, or no activities match: " + cmd);
12264                    pw.println("Use -h for help.");
12265                }
12266            }
12267            if (!more) {
12268                Binder.restoreCallingIdentity(origId);
12269                return;
12270            }
12271        }
12272
12273        // No piece of data specified, dump everything.
12274        synchronized (this) {
12275            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12276            pw.println();
12277            if (dumpAll) {
12278                pw.println("-------------------------------------------------------------------------------");
12279            }
12280            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12281            pw.println();
12282            if (dumpAll) {
12283                pw.println("-------------------------------------------------------------------------------");
12284            }
12285            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12286            pw.println();
12287            if (dumpAll) {
12288                pw.println("-------------------------------------------------------------------------------");
12289            }
12290            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12291            pw.println();
12292            if (dumpAll) {
12293                pw.println("-------------------------------------------------------------------------------");
12294            }
12295            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12296            pw.println();
12297            if (dumpAll) {
12298                pw.println("-------------------------------------------------------------------------------");
12299            }
12300            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12301            pw.println();
12302            if (dumpAll) {
12303                pw.println("-------------------------------------------------------------------------------");
12304            }
12305            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12306        }
12307        Binder.restoreCallingIdentity(origId);
12308    }
12309
12310    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12311            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12312        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12313
12314        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12315                dumpPackage);
12316        boolean needSep = printedAnything;
12317
12318        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12319                dumpPackage, needSep, "  mFocusedActivity: ");
12320        if (printed) {
12321            printedAnything = true;
12322            needSep = false;
12323        }
12324
12325        if (dumpPackage == null) {
12326            if (needSep) {
12327                pw.println();
12328            }
12329            needSep = true;
12330            printedAnything = true;
12331            mStackSupervisor.dump(pw, "  ");
12332        }
12333
12334        if (!printedAnything) {
12335            pw.println("  (nothing)");
12336        }
12337    }
12338
12339    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12340            int opti, boolean dumpAll, String dumpPackage) {
12341        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12342
12343        boolean printedAnything = false;
12344
12345        if (mRecentTasks.size() > 0) {
12346            boolean printedHeader = false;
12347
12348            final int N = mRecentTasks.size();
12349            for (int i=0; i<N; i++) {
12350                TaskRecord tr = mRecentTasks.get(i);
12351                if (dumpPackage != null) {
12352                    if (tr.realActivity == null ||
12353                            !dumpPackage.equals(tr.realActivity)) {
12354                        continue;
12355                    }
12356                }
12357                if (!printedHeader) {
12358                    pw.println("  Recent tasks:");
12359                    printedHeader = true;
12360                    printedAnything = true;
12361                }
12362                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12363                        pw.println(tr);
12364                if (dumpAll) {
12365                    mRecentTasks.get(i).dump(pw, "    ");
12366                }
12367            }
12368        }
12369
12370        if (!printedAnything) {
12371            pw.println("  (nothing)");
12372        }
12373    }
12374
12375    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12376            int opti, boolean dumpAll, String dumpPackage) {
12377        boolean needSep = false;
12378        boolean printedAnything = false;
12379        int numPers = 0;
12380
12381        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12382
12383        if (dumpAll) {
12384            final int NP = mProcessNames.getMap().size();
12385            for (int ip=0; ip<NP; ip++) {
12386                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12387                final int NA = procs.size();
12388                for (int ia=0; ia<NA; ia++) {
12389                    ProcessRecord r = procs.valueAt(ia);
12390                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12391                        continue;
12392                    }
12393                    if (!needSep) {
12394                        pw.println("  All known processes:");
12395                        needSep = true;
12396                        printedAnything = true;
12397                    }
12398                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12399                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12400                        pw.print(" "); pw.println(r);
12401                    r.dump(pw, "    ");
12402                    if (r.persistent) {
12403                        numPers++;
12404                    }
12405                }
12406            }
12407        }
12408
12409        if (mIsolatedProcesses.size() > 0) {
12410            boolean printed = false;
12411            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12412                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12413                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12414                    continue;
12415                }
12416                if (!printed) {
12417                    if (needSep) {
12418                        pw.println();
12419                    }
12420                    pw.println("  Isolated process list (sorted by uid):");
12421                    printedAnything = true;
12422                    printed = true;
12423                    needSep = true;
12424                }
12425                pw.println(String.format("%sIsolated #%2d: %s",
12426                        "    ", i, r.toString()));
12427            }
12428        }
12429
12430        if (mLruProcesses.size() > 0) {
12431            if (needSep) {
12432                pw.println();
12433            }
12434            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12435                    pw.print(" total, non-act at ");
12436                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12437                    pw.print(", non-svc at ");
12438                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12439                    pw.println("):");
12440            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12441            needSep = true;
12442            printedAnything = true;
12443        }
12444
12445        if (dumpAll || dumpPackage != null) {
12446            synchronized (mPidsSelfLocked) {
12447                boolean printed = false;
12448                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12449                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12450                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12451                        continue;
12452                    }
12453                    if (!printed) {
12454                        if (needSep) pw.println();
12455                        needSep = true;
12456                        pw.println("  PID mappings:");
12457                        printed = true;
12458                        printedAnything = true;
12459                    }
12460                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12461                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12462                }
12463            }
12464        }
12465
12466        if (mForegroundProcesses.size() > 0) {
12467            synchronized (mPidsSelfLocked) {
12468                boolean printed = false;
12469                for (int i=0; i<mForegroundProcesses.size(); i++) {
12470                    ProcessRecord r = mPidsSelfLocked.get(
12471                            mForegroundProcesses.valueAt(i).pid);
12472                    if (dumpPackage != null && (r == null
12473                            || !r.pkgList.containsKey(dumpPackage))) {
12474                        continue;
12475                    }
12476                    if (!printed) {
12477                        if (needSep) pw.println();
12478                        needSep = true;
12479                        pw.println("  Foreground Processes:");
12480                        printed = true;
12481                        printedAnything = true;
12482                    }
12483                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12484                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12485                }
12486            }
12487        }
12488
12489        if (mPersistentStartingProcesses.size() > 0) {
12490            if (needSep) pw.println();
12491            needSep = true;
12492            printedAnything = true;
12493            pw.println("  Persisent processes that are starting:");
12494            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12495                    "Starting Norm", "Restarting PERS", dumpPackage);
12496        }
12497
12498        if (mRemovedProcesses.size() > 0) {
12499            if (needSep) pw.println();
12500            needSep = true;
12501            printedAnything = true;
12502            pw.println("  Processes that are being removed:");
12503            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12504                    "Removed Norm", "Removed PERS", dumpPackage);
12505        }
12506
12507        if (mProcessesOnHold.size() > 0) {
12508            if (needSep) pw.println();
12509            needSep = true;
12510            printedAnything = true;
12511            pw.println("  Processes that are on old until the system is ready:");
12512            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12513                    "OnHold Norm", "OnHold PERS", dumpPackage);
12514        }
12515
12516        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12517
12518        if (mProcessCrashTimes.getMap().size() > 0) {
12519            boolean printed = false;
12520            long now = SystemClock.uptimeMillis();
12521            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12522            final int NP = pmap.size();
12523            for (int ip=0; ip<NP; ip++) {
12524                String pname = pmap.keyAt(ip);
12525                SparseArray<Long> uids = pmap.valueAt(ip);
12526                final int N = uids.size();
12527                for (int i=0; i<N; i++) {
12528                    int puid = uids.keyAt(i);
12529                    ProcessRecord r = mProcessNames.get(pname, puid);
12530                    if (dumpPackage != null && (r == null
12531                            || !r.pkgList.containsKey(dumpPackage))) {
12532                        continue;
12533                    }
12534                    if (!printed) {
12535                        if (needSep) pw.println();
12536                        needSep = true;
12537                        pw.println("  Time since processes crashed:");
12538                        printed = true;
12539                        printedAnything = true;
12540                    }
12541                    pw.print("    Process "); pw.print(pname);
12542                            pw.print(" uid "); pw.print(puid);
12543                            pw.print(": last crashed ");
12544                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12545                            pw.println(" ago");
12546                }
12547            }
12548        }
12549
12550        if (mBadProcesses.getMap().size() > 0) {
12551            boolean printed = false;
12552            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12553            final int NP = pmap.size();
12554            for (int ip=0; ip<NP; ip++) {
12555                String pname = pmap.keyAt(ip);
12556                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12557                final int N = uids.size();
12558                for (int i=0; i<N; i++) {
12559                    int puid = uids.keyAt(i);
12560                    ProcessRecord r = mProcessNames.get(pname, puid);
12561                    if (dumpPackage != null && (r == null
12562                            || !r.pkgList.containsKey(dumpPackage))) {
12563                        continue;
12564                    }
12565                    if (!printed) {
12566                        if (needSep) pw.println();
12567                        needSep = true;
12568                        pw.println("  Bad processes:");
12569                        printedAnything = true;
12570                    }
12571                    BadProcessInfo info = uids.valueAt(i);
12572                    pw.print("    Bad process "); pw.print(pname);
12573                            pw.print(" uid "); pw.print(puid);
12574                            pw.print(": crashed at time "); pw.println(info.time);
12575                    if (info.shortMsg != null) {
12576                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12577                    }
12578                    if (info.longMsg != null) {
12579                        pw.print("      Long msg: "); pw.println(info.longMsg);
12580                    }
12581                    if (info.stack != null) {
12582                        pw.println("      Stack:");
12583                        int lastPos = 0;
12584                        for (int pos=0; pos<info.stack.length(); pos++) {
12585                            if (info.stack.charAt(pos) == '\n') {
12586                                pw.print("        ");
12587                                pw.write(info.stack, lastPos, pos-lastPos);
12588                                pw.println();
12589                                lastPos = pos+1;
12590                            }
12591                        }
12592                        if (lastPos < info.stack.length()) {
12593                            pw.print("        ");
12594                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12595                            pw.println();
12596                        }
12597                    }
12598                }
12599            }
12600        }
12601
12602        if (dumpPackage == null) {
12603            pw.println();
12604            needSep = false;
12605            pw.println("  mStartedUsers:");
12606            for (int i=0; i<mStartedUsers.size(); i++) {
12607                UserStartedState uss = mStartedUsers.valueAt(i);
12608                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12609                        pw.print(": "); uss.dump("", pw);
12610            }
12611            pw.print("  mStartedUserArray: [");
12612            for (int i=0; i<mStartedUserArray.length; i++) {
12613                if (i > 0) pw.print(", ");
12614                pw.print(mStartedUserArray[i]);
12615            }
12616            pw.println("]");
12617            pw.print("  mUserLru: [");
12618            for (int i=0; i<mUserLru.size(); i++) {
12619                if (i > 0) pw.print(", ");
12620                pw.print(mUserLru.get(i));
12621            }
12622            pw.println("]");
12623            if (dumpAll) {
12624                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12625            }
12626            synchronized (mUserProfileGroupIdsSelfLocked) {
12627                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12628                    pw.println("  mUserProfileGroupIds:");
12629                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12630                        pw.print("    User #");
12631                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12632                        pw.print(" -> profile #");
12633                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12634                    }
12635                }
12636            }
12637        }
12638        if (mHomeProcess != null && (dumpPackage == null
12639                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12640            if (needSep) {
12641                pw.println();
12642                needSep = false;
12643            }
12644            pw.println("  mHomeProcess: " + mHomeProcess);
12645        }
12646        if (mPreviousProcess != null && (dumpPackage == null
12647                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12648            if (needSep) {
12649                pw.println();
12650                needSep = false;
12651            }
12652            pw.println("  mPreviousProcess: " + mPreviousProcess);
12653        }
12654        if (dumpAll) {
12655            StringBuilder sb = new StringBuilder(128);
12656            sb.append("  mPreviousProcessVisibleTime: ");
12657            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12658            pw.println(sb);
12659        }
12660        if (mHeavyWeightProcess != null && (dumpPackage == null
12661                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12662            if (needSep) {
12663                pw.println();
12664                needSep = false;
12665            }
12666            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12667        }
12668        if (dumpPackage == null) {
12669            pw.println("  mConfiguration: " + mConfiguration);
12670        }
12671        if (dumpAll) {
12672            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12673            if (mCompatModePackages.getPackages().size() > 0) {
12674                boolean printed = false;
12675                for (Map.Entry<String, Integer> entry
12676                        : mCompatModePackages.getPackages().entrySet()) {
12677                    String pkg = entry.getKey();
12678                    int mode = entry.getValue();
12679                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12680                        continue;
12681                    }
12682                    if (!printed) {
12683                        pw.println("  mScreenCompatPackages:");
12684                        printed = true;
12685                    }
12686                    pw.print("    "); pw.print(pkg); pw.print(": ");
12687                            pw.print(mode); pw.println();
12688                }
12689            }
12690        }
12691        if (dumpPackage == null) {
12692            if (mSleeping || mWentToSleep || mLockScreenShown) {
12693                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12694                        + " mLockScreenShown " + mLockScreenShown);
12695            }
12696            if (mShuttingDown || mRunningVoice) {
12697                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12698            }
12699        }
12700        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12701                || mOrigWaitForDebugger) {
12702            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12703                    || dumpPackage.equals(mOrigDebugApp)) {
12704                if (needSep) {
12705                    pw.println();
12706                    needSep = false;
12707                }
12708                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12709                        + " mDebugTransient=" + mDebugTransient
12710                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12711            }
12712        }
12713        if (mOpenGlTraceApp != null) {
12714            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12715                if (needSep) {
12716                    pw.println();
12717                    needSep = false;
12718                }
12719                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12720            }
12721        }
12722        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12723                || mProfileFd != null) {
12724            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12725                if (needSep) {
12726                    pw.println();
12727                    needSep = false;
12728                }
12729                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12730                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12731                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12732                        + mAutoStopProfiler);
12733                pw.println("  mProfileType=" + mProfileType);
12734            }
12735        }
12736        if (dumpPackage == null) {
12737            if (mAlwaysFinishActivities || mController != null) {
12738                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12739                        + " mController=" + mController);
12740            }
12741            if (dumpAll) {
12742                pw.println("  Total persistent processes: " + numPers);
12743                pw.println("  mProcessesReady=" + mProcessesReady
12744                        + " mSystemReady=" + mSystemReady);
12745                pw.println("  mBooting=" + mBooting
12746                        + " mBooted=" + mBooted
12747                        + " mFactoryTest=" + mFactoryTest);
12748                pw.print("  mLastPowerCheckRealtime=");
12749                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12750                        pw.println("");
12751                pw.print("  mLastPowerCheckUptime=");
12752                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12753                        pw.println("");
12754                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12755                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12756                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12757                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12758                        + " (" + mLruProcesses.size() + " total)"
12759                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12760                        + " mNumServiceProcs=" + mNumServiceProcs
12761                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12762                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12763                        + " mLastMemoryLevel" + mLastMemoryLevel
12764                        + " mLastNumProcesses" + mLastNumProcesses);
12765                long now = SystemClock.uptimeMillis();
12766                pw.print("  mLastIdleTime=");
12767                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12768                        pw.print(" mLowRamSinceLastIdle=");
12769                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12770                        pw.println();
12771            }
12772        }
12773
12774        if (!printedAnything) {
12775            pw.println("  (nothing)");
12776        }
12777    }
12778
12779    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12780            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12781        if (mProcessesToGc.size() > 0) {
12782            boolean printed = false;
12783            long now = SystemClock.uptimeMillis();
12784            for (int i=0; i<mProcessesToGc.size(); i++) {
12785                ProcessRecord proc = mProcessesToGc.get(i);
12786                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12787                    continue;
12788                }
12789                if (!printed) {
12790                    if (needSep) pw.println();
12791                    needSep = true;
12792                    pw.println("  Processes that are waiting to GC:");
12793                    printed = true;
12794                }
12795                pw.print("    Process "); pw.println(proc);
12796                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12797                        pw.print(", last gced=");
12798                        pw.print(now-proc.lastRequestedGc);
12799                        pw.print(" ms ago, last lowMem=");
12800                        pw.print(now-proc.lastLowMemory);
12801                        pw.println(" ms ago");
12802
12803            }
12804        }
12805        return needSep;
12806    }
12807
12808    void printOomLevel(PrintWriter pw, String name, int adj) {
12809        pw.print("    ");
12810        if (adj >= 0) {
12811            pw.print(' ');
12812            if (adj < 10) pw.print(' ');
12813        } else {
12814            if (adj > -10) pw.print(' ');
12815        }
12816        pw.print(adj);
12817        pw.print(": ");
12818        pw.print(name);
12819        pw.print(" (");
12820        pw.print(mProcessList.getMemLevel(adj)/1024);
12821        pw.println(" kB)");
12822    }
12823
12824    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12825            int opti, boolean dumpAll) {
12826        boolean needSep = false;
12827
12828        if (mLruProcesses.size() > 0) {
12829            if (needSep) pw.println();
12830            needSep = true;
12831            pw.println("  OOM levels:");
12832            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12833            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12834            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12835            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12836            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12837            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12838            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12839            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12840            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12841            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12842            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12843            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12844            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12845
12846            if (needSep) pw.println();
12847            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12848                    pw.print(" total, non-act at ");
12849                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12850                    pw.print(", non-svc at ");
12851                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12852                    pw.println("):");
12853            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12854            needSep = true;
12855        }
12856
12857        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12858
12859        pw.println();
12860        pw.println("  mHomeProcess: " + mHomeProcess);
12861        pw.println("  mPreviousProcess: " + mPreviousProcess);
12862        if (mHeavyWeightProcess != null) {
12863            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12864        }
12865
12866        return true;
12867    }
12868
12869    /**
12870     * There are three ways to call this:
12871     *  - no provider specified: dump all the providers
12872     *  - a flattened component name that matched an existing provider was specified as the
12873     *    first arg: dump that one provider
12874     *  - the first arg isn't the flattened component name of an existing provider:
12875     *    dump all providers whose component contains the first arg as a substring
12876     */
12877    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12878            int opti, boolean dumpAll) {
12879        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12880    }
12881
12882    static class ItemMatcher {
12883        ArrayList<ComponentName> components;
12884        ArrayList<String> strings;
12885        ArrayList<Integer> objects;
12886        boolean all;
12887
12888        ItemMatcher() {
12889            all = true;
12890        }
12891
12892        void build(String name) {
12893            ComponentName componentName = ComponentName.unflattenFromString(name);
12894            if (componentName != null) {
12895                if (components == null) {
12896                    components = new ArrayList<ComponentName>();
12897                }
12898                components.add(componentName);
12899                all = false;
12900            } else {
12901                int objectId = 0;
12902                // Not a '/' separated full component name; maybe an object ID?
12903                try {
12904                    objectId = Integer.parseInt(name, 16);
12905                    if (objects == null) {
12906                        objects = new ArrayList<Integer>();
12907                    }
12908                    objects.add(objectId);
12909                    all = false;
12910                } catch (RuntimeException e) {
12911                    // Not an integer; just do string match.
12912                    if (strings == null) {
12913                        strings = new ArrayList<String>();
12914                    }
12915                    strings.add(name);
12916                    all = false;
12917                }
12918            }
12919        }
12920
12921        int build(String[] args, int opti) {
12922            for (; opti<args.length; opti++) {
12923                String name = args[opti];
12924                if ("--".equals(name)) {
12925                    return opti+1;
12926                }
12927                build(name);
12928            }
12929            return opti;
12930        }
12931
12932        boolean match(Object object, ComponentName comp) {
12933            if (all) {
12934                return true;
12935            }
12936            if (components != null) {
12937                for (int i=0; i<components.size(); i++) {
12938                    if (components.get(i).equals(comp)) {
12939                        return true;
12940                    }
12941                }
12942            }
12943            if (objects != null) {
12944                for (int i=0; i<objects.size(); i++) {
12945                    if (System.identityHashCode(object) == objects.get(i)) {
12946                        return true;
12947                    }
12948                }
12949            }
12950            if (strings != null) {
12951                String flat = comp.flattenToString();
12952                for (int i=0; i<strings.size(); i++) {
12953                    if (flat.contains(strings.get(i))) {
12954                        return true;
12955                    }
12956                }
12957            }
12958            return false;
12959        }
12960    }
12961
12962    /**
12963     * There are three things that cmd can be:
12964     *  - a flattened component name that matches an existing activity
12965     *  - the cmd arg isn't the flattened component name of an existing activity:
12966     *    dump all activity whose component contains the cmd as a substring
12967     *  - A hex number of the ActivityRecord object instance.
12968     */
12969    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12970            int opti, boolean dumpAll) {
12971        ArrayList<ActivityRecord> activities;
12972
12973        synchronized (this) {
12974            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12975        }
12976
12977        if (activities.size() <= 0) {
12978            return false;
12979        }
12980
12981        String[] newArgs = new String[args.length - opti];
12982        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12983
12984        TaskRecord lastTask = null;
12985        boolean needSep = false;
12986        for (int i=activities.size()-1; i>=0; i--) {
12987            ActivityRecord r = activities.get(i);
12988            if (needSep) {
12989                pw.println();
12990            }
12991            needSep = true;
12992            synchronized (this) {
12993                if (lastTask != r.task) {
12994                    lastTask = r.task;
12995                    pw.print("TASK "); pw.print(lastTask.affinity);
12996                            pw.print(" id="); pw.println(lastTask.taskId);
12997                    if (dumpAll) {
12998                        lastTask.dump(pw, "  ");
12999                    }
13000                }
13001            }
13002            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13003        }
13004        return true;
13005    }
13006
13007    /**
13008     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13009     * there is a thread associated with the activity.
13010     */
13011    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13012            final ActivityRecord r, String[] args, boolean dumpAll) {
13013        String innerPrefix = prefix + "  ";
13014        synchronized (this) {
13015            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13016                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13017                    pw.print(" pid=");
13018                    if (r.app != null) pw.println(r.app.pid);
13019                    else pw.println("(not running)");
13020            if (dumpAll) {
13021                r.dump(pw, innerPrefix);
13022            }
13023        }
13024        if (r.app != null && r.app.thread != null) {
13025            // flush anything that is already in the PrintWriter since the thread is going
13026            // to write to the file descriptor directly
13027            pw.flush();
13028            try {
13029                TransferPipe tp = new TransferPipe();
13030                try {
13031                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13032                            r.appToken, innerPrefix, args);
13033                    tp.go(fd);
13034                } finally {
13035                    tp.kill();
13036                }
13037            } catch (IOException e) {
13038                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13039            } catch (RemoteException e) {
13040                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13041            }
13042        }
13043    }
13044
13045    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13046            int opti, boolean dumpAll, String dumpPackage) {
13047        boolean needSep = false;
13048        boolean onlyHistory = false;
13049        boolean printedAnything = false;
13050
13051        if ("history".equals(dumpPackage)) {
13052            if (opti < args.length && "-s".equals(args[opti])) {
13053                dumpAll = false;
13054            }
13055            onlyHistory = true;
13056            dumpPackage = null;
13057        }
13058
13059        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13060        if (!onlyHistory && dumpAll) {
13061            if (mRegisteredReceivers.size() > 0) {
13062                boolean printed = false;
13063                Iterator it = mRegisteredReceivers.values().iterator();
13064                while (it.hasNext()) {
13065                    ReceiverList r = (ReceiverList)it.next();
13066                    if (dumpPackage != null && (r.app == null ||
13067                            !dumpPackage.equals(r.app.info.packageName))) {
13068                        continue;
13069                    }
13070                    if (!printed) {
13071                        pw.println("  Registered Receivers:");
13072                        needSep = true;
13073                        printed = true;
13074                        printedAnything = true;
13075                    }
13076                    pw.print("  * "); pw.println(r);
13077                    r.dump(pw, "    ");
13078                }
13079            }
13080
13081            if (mReceiverResolver.dump(pw, needSep ?
13082                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13083                    "    ", dumpPackage, false)) {
13084                needSep = true;
13085                printedAnything = true;
13086            }
13087        }
13088
13089        for (BroadcastQueue q : mBroadcastQueues) {
13090            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13091            printedAnything |= needSep;
13092        }
13093
13094        needSep = true;
13095
13096        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13097            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13098                if (needSep) {
13099                    pw.println();
13100                }
13101                needSep = true;
13102                printedAnything = true;
13103                pw.print("  Sticky broadcasts for user ");
13104                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13105                StringBuilder sb = new StringBuilder(128);
13106                for (Map.Entry<String, ArrayList<Intent>> ent
13107                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13108                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13109                    if (dumpAll) {
13110                        pw.println(":");
13111                        ArrayList<Intent> intents = ent.getValue();
13112                        final int N = intents.size();
13113                        for (int i=0; i<N; i++) {
13114                            sb.setLength(0);
13115                            sb.append("    Intent: ");
13116                            intents.get(i).toShortString(sb, false, true, false, false);
13117                            pw.println(sb.toString());
13118                            Bundle bundle = intents.get(i).getExtras();
13119                            if (bundle != null) {
13120                                pw.print("      ");
13121                                pw.println(bundle.toString());
13122                            }
13123                        }
13124                    } else {
13125                        pw.println("");
13126                    }
13127                }
13128            }
13129        }
13130
13131        if (!onlyHistory && dumpAll) {
13132            pw.println();
13133            for (BroadcastQueue queue : mBroadcastQueues) {
13134                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13135                        + queue.mBroadcastsScheduled);
13136            }
13137            pw.println("  mHandler:");
13138            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13139            needSep = true;
13140            printedAnything = true;
13141        }
13142
13143        if (!printedAnything) {
13144            pw.println("  (nothing)");
13145        }
13146    }
13147
13148    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13149            int opti, boolean dumpAll, String dumpPackage) {
13150        boolean needSep;
13151        boolean printedAnything = false;
13152
13153        ItemMatcher matcher = new ItemMatcher();
13154        matcher.build(args, opti);
13155
13156        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13157
13158        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13159        printedAnything |= needSep;
13160
13161        if (mLaunchingProviders.size() > 0) {
13162            boolean printed = false;
13163            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13164                ContentProviderRecord r = mLaunchingProviders.get(i);
13165                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13166                    continue;
13167                }
13168                if (!printed) {
13169                    if (needSep) pw.println();
13170                    needSep = true;
13171                    pw.println("  Launching content providers:");
13172                    printed = true;
13173                    printedAnything = true;
13174                }
13175                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13176                        pw.println(r);
13177            }
13178        }
13179
13180        if (mGrantedUriPermissions.size() > 0) {
13181            boolean printed = false;
13182            int dumpUid = -2;
13183            if (dumpPackage != null) {
13184                try {
13185                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13186                } catch (NameNotFoundException e) {
13187                    dumpUid = -1;
13188                }
13189            }
13190            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13191                int uid = mGrantedUriPermissions.keyAt(i);
13192                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13193                    continue;
13194                }
13195                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13196                if (!printed) {
13197                    if (needSep) pw.println();
13198                    needSep = true;
13199                    pw.println("  Granted Uri Permissions:");
13200                    printed = true;
13201                    printedAnything = true;
13202                }
13203                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13204                for (UriPermission perm : perms.values()) {
13205                    pw.print("    "); pw.println(perm);
13206                    if (dumpAll) {
13207                        perm.dump(pw, "      ");
13208                    }
13209                }
13210            }
13211        }
13212
13213        if (!printedAnything) {
13214            pw.println("  (nothing)");
13215        }
13216    }
13217
13218    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13219            int opti, boolean dumpAll, String dumpPackage) {
13220        boolean printed = false;
13221
13222        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13223
13224        if (mIntentSenderRecords.size() > 0) {
13225            Iterator<WeakReference<PendingIntentRecord>> it
13226                    = mIntentSenderRecords.values().iterator();
13227            while (it.hasNext()) {
13228                WeakReference<PendingIntentRecord> ref = it.next();
13229                PendingIntentRecord rec = ref != null ? ref.get(): null;
13230                if (dumpPackage != null && (rec == null
13231                        || !dumpPackage.equals(rec.key.packageName))) {
13232                    continue;
13233                }
13234                printed = true;
13235                if (rec != null) {
13236                    pw.print("  * "); pw.println(rec);
13237                    if (dumpAll) {
13238                        rec.dump(pw, "    ");
13239                    }
13240                } else {
13241                    pw.print("  * "); pw.println(ref);
13242                }
13243            }
13244        }
13245
13246        if (!printed) {
13247            pw.println("  (nothing)");
13248        }
13249    }
13250
13251    private static final int dumpProcessList(PrintWriter pw,
13252            ActivityManagerService service, List list,
13253            String prefix, String normalLabel, String persistentLabel,
13254            String dumpPackage) {
13255        int numPers = 0;
13256        final int N = list.size()-1;
13257        for (int i=N; i>=0; i--) {
13258            ProcessRecord r = (ProcessRecord)list.get(i);
13259            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13260                continue;
13261            }
13262            pw.println(String.format("%s%s #%2d: %s",
13263                    prefix, (r.persistent ? persistentLabel : normalLabel),
13264                    i, r.toString()));
13265            if (r.persistent) {
13266                numPers++;
13267            }
13268        }
13269        return numPers;
13270    }
13271
13272    private static final boolean dumpProcessOomList(PrintWriter pw,
13273            ActivityManagerService service, List<ProcessRecord> origList,
13274            String prefix, String normalLabel, String persistentLabel,
13275            boolean inclDetails, String dumpPackage) {
13276
13277        ArrayList<Pair<ProcessRecord, Integer>> list
13278                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13279        for (int i=0; i<origList.size(); i++) {
13280            ProcessRecord r = origList.get(i);
13281            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13282                continue;
13283            }
13284            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13285        }
13286
13287        if (list.size() <= 0) {
13288            return false;
13289        }
13290
13291        Comparator<Pair<ProcessRecord, Integer>> comparator
13292                = new Comparator<Pair<ProcessRecord, Integer>>() {
13293            @Override
13294            public int compare(Pair<ProcessRecord, Integer> object1,
13295                    Pair<ProcessRecord, Integer> object2) {
13296                if (object1.first.setAdj != object2.first.setAdj) {
13297                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13298                }
13299                if (object1.second.intValue() != object2.second.intValue()) {
13300                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13301                }
13302                return 0;
13303            }
13304        };
13305
13306        Collections.sort(list, comparator);
13307
13308        final long curRealtime = SystemClock.elapsedRealtime();
13309        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13310        final long curUptime = SystemClock.uptimeMillis();
13311        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13312
13313        for (int i=list.size()-1; i>=0; i--) {
13314            ProcessRecord r = list.get(i).first;
13315            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13316            char schedGroup;
13317            switch (r.setSchedGroup) {
13318                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13319                    schedGroup = 'B';
13320                    break;
13321                case Process.THREAD_GROUP_DEFAULT:
13322                    schedGroup = 'F';
13323                    break;
13324                default:
13325                    schedGroup = '?';
13326                    break;
13327            }
13328            char foreground;
13329            if (r.foregroundActivities) {
13330                foreground = 'A';
13331            } else if (r.foregroundServices) {
13332                foreground = 'S';
13333            } else {
13334                foreground = ' ';
13335            }
13336            String procState = ProcessList.makeProcStateString(r.curProcState);
13337            pw.print(prefix);
13338            pw.print(r.persistent ? persistentLabel : normalLabel);
13339            pw.print(" #");
13340            int num = (origList.size()-1)-list.get(i).second;
13341            if (num < 10) pw.print(' ');
13342            pw.print(num);
13343            pw.print(": ");
13344            pw.print(oomAdj);
13345            pw.print(' ');
13346            pw.print(schedGroup);
13347            pw.print('/');
13348            pw.print(foreground);
13349            pw.print('/');
13350            pw.print(procState);
13351            pw.print(" trm:");
13352            if (r.trimMemoryLevel < 10) pw.print(' ');
13353            pw.print(r.trimMemoryLevel);
13354            pw.print(' ');
13355            pw.print(r.toShortString());
13356            pw.print(" (");
13357            pw.print(r.adjType);
13358            pw.println(')');
13359            if (r.adjSource != null || r.adjTarget != null) {
13360                pw.print(prefix);
13361                pw.print("    ");
13362                if (r.adjTarget instanceof ComponentName) {
13363                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13364                } else if (r.adjTarget != null) {
13365                    pw.print(r.adjTarget.toString());
13366                } else {
13367                    pw.print("{null}");
13368                }
13369                pw.print("<=");
13370                if (r.adjSource instanceof ProcessRecord) {
13371                    pw.print("Proc{");
13372                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13373                    pw.println("}");
13374                } else if (r.adjSource != null) {
13375                    pw.println(r.adjSource.toString());
13376                } else {
13377                    pw.println("{null}");
13378                }
13379            }
13380            if (inclDetails) {
13381                pw.print(prefix);
13382                pw.print("    ");
13383                pw.print("oom: max="); pw.print(r.maxAdj);
13384                pw.print(" curRaw="); pw.print(r.curRawAdj);
13385                pw.print(" setRaw="); pw.print(r.setRawAdj);
13386                pw.print(" cur="); pw.print(r.curAdj);
13387                pw.print(" set="); pw.println(r.setAdj);
13388                pw.print(prefix);
13389                pw.print("    ");
13390                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13391                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13392                pw.print(" lastPss="); pw.print(r.lastPss);
13393                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13394                pw.print(prefix);
13395                pw.print("    ");
13396                pw.print("cached="); pw.print(r.cached);
13397                pw.print(" empty="); pw.print(r.empty);
13398                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13399
13400                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13401                    if (r.lastWakeTime != 0) {
13402                        long wtime;
13403                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13404                        synchronized (stats) {
13405                            wtime = stats.getProcessWakeTime(r.info.uid,
13406                                    r.pid, curRealtime);
13407                        }
13408                        long timeUsed = wtime - r.lastWakeTime;
13409                        pw.print(prefix);
13410                        pw.print("    ");
13411                        pw.print("keep awake over ");
13412                        TimeUtils.formatDuration(realtimeSince, pw);
13413                        pw.print(" used ");
13414                        TimeUtils.formatDuration(timeUsed, pw);
13415                        pw.print(" (");
13416                        pw.print((timeUsed*100)/realtimeSince);
13417                        pw.println("%)");
13418                    }
13419                    if (r.lastCpuTime != 0) {
13420                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13421                        pw.print(prefix);
13422                        pw.print("    ");
13423                        pw.print("run cpu over ");
13424                        TimeUtils.formatDuration(uptimeSince, pw);
13425                        pw.print(" used ");
13426                        TimeUtils.formatDuration(timeUsed, pw);
13427                        pw.print(" (");
13428                        pw.print((timeUsed*100)/uptimeSince);
13429                        pw.println("%)");
13430                    }
13431                }
13432            }
13433        }
13434        return true;
13435    }
13436
13437    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13438        ArrayList<ProcessRecord> procs;
13439        synchronized (this) {
13440            if (args != null && args.length > start
13441                    && args[start].charAt(0) != '-') {
13442                procs = new ArrayList<ProcessRecord>();
13443                int pid = -1;
13444                try {
13445                    pid = Integer.parseInt(args[start]);
13446                } catch (NumberFormatException e) {
13447                }
13448                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13449                    ProcessRecord proc = mLruProcesses.get(i);
13450                    if (proc.pid == pid) {
13451                        procs.add(proc);
13452                    } else if (proc.processName.equals(args[start])) {
13453                        procs.add(proc);
13454                    }
13455                }
13456                if (procs.size() <= 0) {
13457                    return null;
13458                }
13459            } else {
13460                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13461            }
13462        }
13463        return procs;
13464    }
13465
13466    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13467            PrintWriter pw, String[] args) {
13468        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13469        if (procs == null) {
13470            pw.println("No process found for: " + args[0]);
13471            return;
13472        }
13473
13474        long uptime = SystemClock.uptimeMillis();
13475        long realtime = SystemClock.elapsedRealtime();
13476        pw.println("Applications Graphics Acceleration Info:");
13477        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13478
13479        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13480            ProcessRecord r = procs.get(i);
13481            if (r.thread != null) {
13482                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13483                pw.flush();
13484                try {
13485                    TransferPipe tp = new TransferPipe();
13486                    try {
13487                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13488                        tp.go(fd);
13489                    } finally {
13490                        tp.kill();
13491                    }
13492                } catch (IOException e) {
13493                    pw.println("Failure while dumping the app: " + r);
13494                    pw.flush();
13495                } catch (RemoteException e) {
13496                    pw.println("Got a RemoteException while dumping the app " + r);
13497                    pw.flush();
13498                }
13499            }
13500        }
13501    }
13502
13503    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13504        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13505        if (procs == null) {
13506            pw.println("No process found for: " + args[0]);
13507            return;
13508        }
13509
13510        pw.println("Applications Database Info:");
13511
13512        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13513            ProcessRecord r = procs.get(i);
13514            if (r.thread != null) {
13515                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13516                pw.flush();
13517                try {
13518                    TransferPipe tp = new TransferPipe();
13519                    try {
13520                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13521                        tp.go(fd);
13522                    } finally {
13523                        tp.kill();
13524                    }
13525                } catch (IOException e) {
13526                    pw.println("Failure while dumping the app: " + r);
13527                    pw.flush();
13528                } catch (RemoteException e) {
13529                    pw.println("Got a RemoteException while dumping the app " + r);
13530                    pw.flush();
13531                }
13532            }
13533        }
13534    }
13535
13536    final static class MemItem {
13537        final boolean isProc;
13538        final String label;
13539        final String shortLabel;
13540        final long pss;
13541        final int id;
13542        final boolean hasActivities;
13543        ArrayList<MemItem> subitems;
13544
13545        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13546                boolean _hasActivities) {
13547            isProc = true;
13548            label = _label;
13549            shortLabel = _shortLabel;
13550            pss = _pss;
13551            id = _id;
13552            hasActivities = _hasActivities;
13553        }
13554
13555        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13556            isProc = false;
13557            label = _label;
13558            shortLabel = _shortLabel;
13559            pss = _pss;
13560            id = _id;
13561            hasActivities = false;
13562        }
13563    }
13564
13565    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13566            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13567        if (sort && !isCompact) {
13568            Collections.sort(items, new Comparator<MemItem>() {
13569                @Override
13570                public int compare(MemItem lhs, MemItem rhs) {
13571                    if (lhs.pss < rhs.pss) {
13572                        return 1;
13573                    } else if (lhs.pss > rhs.pss) {
13574                        return -1;
13575                    }
13576                    return 0;
13577                }
13578            });
13579        }
13580
13581        for (int i=0; i<items.size(); i++) {
13582            MemItem mi = items.get(i);
13583            if (!isCompact) {
13584                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13585            } else if (mi.isProc) {
13586                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13587                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13588                pw.println(mi.hasActivities ? ",a" : ",e");
13589            } else {
13590                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13591                pw.println(mi.pss);
13592            }
13593            if (mi.subitems != null) {
13594                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13595                        true, isCompact);
13596            }
13597        }
13598    }
13599
13600    // These are in KB.
13601    static final long[] DUMP_MEM_BUCKETS = new long[] {
13602        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13603        120*1024, 160*1024, 200*1024,
13604        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13605        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13606    };
13607
13608    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13609            boolean stackLike) {
13610        int start = label.lastIndexOf('.');
13611        if (start >= 0) start++;
13612        else start = 0;
13613        int end = label.length();
13614        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13615            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13616                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13617                out.append(bucket);
13618                out.append(stackLike ? "MB." : "MB ");
13619                out.append(label, start, end);
13620                return;
13621            }
13622        }
13623        out.append(memKB/1024);
13624        out.append(stackLike ? "MB." : "MB ");
13625        out.append(label, start, end);
13626    }
13627
13628    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13629            ProcessList.NATIVE_ADJ,
13630            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13631            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13632            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13633            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13634            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13635    };
13636    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13637            "Native",
13638            "System", "Persistent", "Foreground",
13639            "Visible", "Perceptible",
13640            "Heavy Weight", "Backup",
13641            "A Services", "Home",
13642            "Previous", "B Services", "Cached"
13643    };
13644    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13645            "native",
13646            "sys", "pers", "fore",
13647            "vis", "percept",
13648            "heavy", "backup",
13649            "servicea", "home",
13650            "prev", "serviceb", "cached"
13651    };
13652
13653    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13654            long realtime, boolean isCheckinRequest, boolean isCompact) {
13655        if (isCheckinRequest || isCompact) {
13656            // short checkin version
13657            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13658        } else {
13659            pw.println("Applications Memory Usage (kB):");
13660            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13661        }
13662    }
13663
13664    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13665            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13666        boolean dumpDetails = false;
13667        boolean dumpFullDetails = false;
13668        boolean dumpDalvik = false;
13669        boolean oomOnly = false;
13670        boolean isCompact = false;
13671        boolean localOnly = false;
13672
13673        int opti = 0;
13674        while (opti < args.length) {
13675            String opt = args[opti];
13676            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13677                break;
13678            }
13679            opti++;
13680            if ("-a".equals(opt)) {
13681                dumpDetails = true;
13682                dumpFullDetails = true;
13683                dumpDalvik = true;
13684            } else if ("-d".equals(opt)) {
13685                dumpDalvik = true;
13686            } else if ("-c".equals(opt)) {
13687                isCompact = true;
13688            } else if ("--oom".equals(opt)) {
13689                oomOnly = true;
13690            } else if ("--local".equals(opt)) {
13691                localOnly = true;
13692            } else if ("-h".equals(opt)) {
13693                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13694                pw.println("  -a: include all available information for each process.");
13695                pw.println("  -d: include dalvik details when dumping process details.");
13696                pw.println("  -c: dump in a compact machine-parseable representation.");
13697                pw.println("  --oom: only show processes organized by oom adj.");
13698                pw.println("  --local: only collect details locally, don't call process.");
13699                pw.println("If [process] is specified it can be the name or ");
13700                pw.println("pid of a specific process to dump.");
13701                return;
13702            } else {
13703                pw.println("Unknown argument: " + opt + "; use -h for help");
13704            }
13705        }
13706
13707        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13708        long uptime = SystemClock.uptimeMillis();
13709        long realtime = SystemClock.elapsedRealtime();
13710        final long[] tmpLong = new long[1];
13711
13712        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13713        if (procs == null) {
13714            // No Java processes.  Maybe they want to print a native process.
13715            if (args != null && args.length > opti
13716                    && args[opti].charAt(0) != '-') {
13717                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13718                        = new ArrayList<ProcessCpuTracker.Stats>();
13719                updateCpuStatsNow();
13720                int findPid = -1;
13721                try {
13722                    findPid = Integer.parseInt(args[opti]);
13723                } catch (NumberFormatException e) {
13724                }
13725                synchronized (mProcessCpuThread) {
13726                    final int N = mProcessCpuTracker.countStats();
13727                    for (int i=0; i<N; i++) {
13728                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13729                        if (st.pid == findPid || (st.baseName != null
13730                                && st.baseName.equals(args[opti]))) {
13731                            nativeProcs.add(st);
13732                        }
13733                    }
13734                }
13735                if (nativeProcs.size() > 0) {
13736                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13737                            isCompact);
13738                    Debug.MemoryInfo mi = null;
13739                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13740                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13741                        final int pid = r.pid;
13742                        if (!isCheckinRequest && dumpDetails) {
13743                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13744                        }
13745                        if (mi == null) {
13746                            mi = new Debug.MemoryInfo();
13747                        }
13748                        if (dumpDetails || (!brief && !oomOnly)) {
13749                            Debug.getMemoryInfo(pid, mi);
13750                        } else {
13751                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13752                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13753                        }
13754                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13755                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13756                        if (isCheckinRequest) {
13757                            pw.println();
13758                        }
13759                    }
13760                    return;
13761                }
13762            }
13763            pw.println("No process found for: " + args[opti]);
13764            return;
13765        }
13766
13767        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13768            dumpDetails = true;
13769        }
13770
13771        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13772
13773        String[] innerArgs = new String[args.length-opti];
13774        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13775
13776        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13777        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13778        long nativePss=0, dalvikPss=0, otherPss=0;
13779        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13780
13781        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13782        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13783                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13784
13785        long totalPss = 0;
13786        long cachedPss = 0;
13787
13788        Debug.MemoryInfo mi = null;
13789        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13790            final ProcessRecord r = procs.get(i);
13791            final IApplicationThread thread;
13792            final int pid;
13793            final int oomAdj;
13794            final boolean hasActivities;
13795            synchronized (this) {
13796                thread = r.thread;
13797                pid = r.pid;
13798                oomAdj = r.getSetAdjWithServices();
13799                hasActivities = r.activities.size() > 0;
13800            }
13801            if (thread != null) {
13802                if (!isCheckinRequest && dumpDetails) {
13803                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13804                }
13805                if (mi == null) {
13806                    mi = new Debug.MemoryInfo();
13807                }
13808                if (dumpDetails || (!brief && !oomOnly)) {
13809                    Debug.getMemoryInfo(pid, mi);
13810                } else {
13811                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13812                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13813                }
13814                if (dumpDetails) {
13815                    if (localOnly) {
13816                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13817                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13818                        if (isCheckinRequest) {
13819                            pw.println();
13820                        }
13821                    } else {
13822                        try {
13823                            pw.flush();
13824                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13825                                    dumpDalvik, innerArgs);
13826                        } catch (RemoteException e) {
13827                            if (!isCheckinRequest) {
13828                                pw.println("Got RemoteException!");
13829                                pw.flush();
13830                            }
13831                        }
13832                    }
13833                }
13834
13835                final long myTotalPss = mi.getTotalPss();
13836                final long myTotalUss = mi.getTotalUss();
13837
13838                synchronized (this) {
13839                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13840                        // Record this for posterity if the process has been stable.
13841                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13842                    }
13843                }
13844
13845                if (!isCheckinRequest && mi != null) {
13846                    totalPss += myTotalPss;
13847                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13848                            (hasActivities ? " / activities)" : ")"),
13849                            r.processName, myTotalPss, pid, hasActivities);
13850                    procMems.add(pssItem);
13851                    procMemsMap.put(pid, pssItem);
13852
13853                    nativePss += mi.nativePss;
13854                    dalvikPss += mi.dalvikPss;
13855                    otherPss += mi.otherPss;
13856                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13857                        long mem = mi.getOtherPss(j);
13858                        miscPss[j] += mem;
13859                        otherPss -= mem;
13860                    }
13861
13862                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13863                        cachedPss += myTotalPss;
13864                    }
13865
13866                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13867                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13868                                || oomIndex == (oomPss.length-1)) {
13869                            oomPss[oomIndex] += myTotalPss;
13870                            if (oomProcs[oomIndex] == null) {
13871                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13872                            }
13873                            oomProcs[oomIndex].add(pssItem);
13874                            break;
13875                        }
13876                    }
13877                }
13878            }
13879        }
13880
13881        long nativeProcTotalPss = 0;
13882
13883        if (!isCheckinRequest && procs.size() > 1) {
13884            // If we are showing aggregations, also look for native processes to
13885            // include so that our aggregations are more accurate.
13886            updateCpuStatsNow();
13887            synchronized (mProcessCpuThread) {
13888                final int N = mProcessCpuTracker.countStats();
13889                for (int i=0; i<N; i++) {
13890                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13891                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13892                        if (mi == null) {
13893                            mi = new Debug.MemoryInfo();
13894                        }
13895                        if (!brief && !oomOnly) {
13896                            Debug.getMemoryInfo(st.pid, mi);
13897                        } else {
13898                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13899                            mi.nativePrivateDirty = (int)tmpLong[0];
13900                        }
13901
13902                        final long myTotalPss = mi.getTotalPss();
13903                        totalPss += myTotalPss;
13904                        nativeProcTotalPss += myTotalPss;
13905
13906                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13907                                st.name, myTotalPss, st.pid, false);
13908                        procMems.add(pssItem);
13909
13910                        nativePss += mi.nativePss;
13911                        dalvikPss += mi.dalvikPss;
13912                        otherPss += mi.otherPss;
13913                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13914                            long mem = mi.getOtherPss(j);
13915                            miscPss[j] += mem;
13916                            otherPss -= mem;
13917                        }
13918                        oomPss[0] += myTotalPss;
13919                        if (oomProcs[0] == null) {
13920                            oomProcs[0] = new ArrayList<MemItem>();
13921                        }
13922                        oomProcs[0].add(pssItem);
13923                    }
13924                }
13925            }
13926
13927            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13928
13929            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13930            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13931            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13932            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13933                String label = Debug.MemoryInfo.getOtherLabel(j);
13934                catMems.add(new MemItem(label, label, miscPss[j], j));
13935            }
13936
13937            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13938            for (int j=0; j<oomPss.length; j++) {
13939                if (oomPss[j] != 0) {
13940                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13941                            : DUMP_MEM_OOM_LABEL[j];
13942                    MemItem item = new MemItem(label, label, oomPss[j],
13943                            DUMP_MEM_OOM_ADJ[j]);
13944                    item.subitems = oomProcs[j];
13945                    oomMems.add(item);
13946                }
13947            }
13948
13949            if (!brief && !oomOnly && !isCompact) {
13950                pw.println();
13951                pw.println("Total PSS by process:");
13952                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13953                pw.println();
13954            }
13955            if (!isCompact) {
13956                pw.println("Total PSS by OOM adjustment:");
13957            }
13958            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13959            if (!brief && !oomOnly) {
13960                PrintWriter out = categoryPw != null ? categoryPw : pw;
13961                if (!isCompact) {
13962                    out.println();
13963                    out.println("Total PSS by category:");
13964                }
13965                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13966            }
13967            if (!isCompact) {
13968                pw.println();
13969            }
13970            MemInfoReader memInfo = new MemInfoReader();
13971            memInfo.readMemInfo();
13972            if (nativeProcTotalPss > 0) {
13973                synchronized (this) {
13974                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13975                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13976                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13977                            nativeProcTotalPss);
13978                }
13979            }
13980            if (!brief) {
13981                if (!isCompact) {
13982                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13983                    pw.print(" kB (status ");
13984                    switch (mLastMemoryLevel) {
13985                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13986                            pw.println("normal)");
13987                            break;
13988                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13989                            pw.println("moderate)");
13990                            break;
13991                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13992                            pw.println("low)");
13993                            break;
13994                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13995                            pw.println("critical)");
13996                            break;
13997                        default:
13998                            pw.print(mLastMemoryLevel);
13999                            pw.println(")");
14000                            break;
14001                    }
14002                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14003                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14004                            pw.print(cachedPss); pw.print(" cached pss + ");
14005                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14006                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14007                } else {
14008                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14009                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14010                            + memInfo.getFreeSizeKb()); pw.print(",");
14011                    pw.println(totalPss - cachedPss);
14012                }
14013            }
14014            if (!isCompact) {
14015                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14016                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14017                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14018                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14019                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14020                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14021                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14022                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14023                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14024                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14025                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14026            }
14027            if (!brief) {
14028                if (memInfo.getZramTotalSizeKb() != 0) {
14029                    if (!isCompact) {
14030                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14031                                pw.print(" kB physical used for ");
14032                                pw.print(memInfo.getSwapTotalSizeKb()
14033                                        - memInfo.getSwapFreeSizeKb());
14034                                pw.print(" kB in swap (");
14035                                pw.print(memInfo.getSwapTotalSizeKb());
14036                                pw.println(" kB total swap)");
14037                    } else {
14038                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14039                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14040                                pw.println(memInfo.getSwapFreeSizeKb());
14041                    }
14042                }
14043                final int[] SINGLE_LONG_FORMAT = new int[] {
14044                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14045                };
14046                long[] longOut = new long[1];
14047                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14048                        SINGLE_LONG_FORMAT, null, longOut, null);
14049                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14050                longOut[0] = 0;
14051                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14052                        SINGLE_LONG_FORMAT, null, longOut, null);
14053                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14054                longOut[0] = 0;
14055                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14056                        SINGLE_LONG_FORMAT, null, longOut, null);
14057                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14058                longOut[0] = 0;
14059                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14060                        SINGLE_LONG_FORMAT, null, longOut, null);
14061                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14062                if (!isCompact) {
14063                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14064                        pw.print("      KSM: "); pw.print(sharing);
14065                                pw.print(" kB saved from shared ");
14066                                pw.print(shared); pw.println(" kB");
14067                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14068                                pw.print(voltile); pw.println(" kB volatile");
14069                    }
14070                    pw.print("   Tuning: ");
14071                    pw.print(ActivityManager.staticGetMemoryClass());
14072                    pw.print(" (large ");
14073                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14074                    pw.print("), oom ");
14075                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14076                    pw.print(" kB");
14077                    pw.print(", restore limit ");
14078                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14079                    pw.print(" kB");
14080                    if (ActivityManager.isLowRamDeviceStatic()) {
14081                        pw.print(" (low-ram)");
14082                    }
14083                    if (ActivityManager.isHighEndGfx()) {
14084                        pw.print(" (high-end-gfx)");
14085                    }
14086                    pw.println();
14087                } else {
14088                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14089                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14090                    pw.println(voltile);
14091                    pw.print("tuning,");
14092                    pw.print(ActivityManager.staticGetMemoryClass());
14093                    pw.print(',');
14094                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14095                    pw.print(',');
14096                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14097                    if (ActivityManager.isLowRamDeviceStatic()) {
14098                        pw.print(",low-ram");
14099                    }
14100                    if (ActivityManager.isHighEndGfx()) {
14101                        pw.print(",high-end-gfx");
14102                    }
14103                    pw.println();
14104                }
14105            }
14106        }
14107    }
14108
14109    /**
14110     * Searches array of arguments for the specified string
14111     * @param args array of argument strings
14112     * @param value value to search for
14113     * @return true if the value is contained in the array
14114     */
14115    private static boolean scanArgs(String[] args, String value) {
14116        if (args != null) {
14117            for (String arg : args) {
14118                if (value.equals(arg)) {
14119                    return true;
14120                }
14121            }
14122        }
14123        return false;
14124    }
14125
14126    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14127            ContentProviderRecord cpr, boolean always) {
14128        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14129
14130        if (!inLaunching || always) {
14131            synchronized (cpr) {
14132                cpr.launchingApp = null;
14133                cpr.notifyAll();
14134            }
14135            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14136            String names[] = cpr.info.authority.split(";");
14137            for (int j = 0; j < names.length; j++) {
14138                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14139            }
14140        }
14141
14142        for (int i=0; i<cpr.connections.size(); i++) {
14143            ContentProviderConnection conn = cpr.connections.get(i);
14144            if (conn.waiting) {
14145                // If this connection is waiting for the provider, then we don't
14146                // need to mess with its process unless we are always removing
14147                // or for some reason the provider is not currently launching.
14148                if (inLaunching && !always) {
14149                    continue;
14150                }
14151            }
14152            ProcessRecord capp = conn.client;
14153            conn.dead = true;
14154            if (conn.stableCount > 0) {
14155                if (!capp.persistent && capp.thread != null
14156                        && capp.pid != 0
14157                        && capp.pid != MY_PID) {
14158                    capp.kill("depends on provider "
14159                            + cpr.name.flattenToShortString()
14160                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14161                }
14162            } else if (capp.thread != null && conn.provider.provider != null) {
14163                try {
14164                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14165                } catch (RemoteException e) {
14166                }
14167                // In the protocol here, we don't expect the client to correctly
14168                // clean up this connection, we'll just remove it.
14169                cpr.connections.remove(i);
14170                conn.client.conProviders.remove(conn);
14171            }
14172        }
14173
14174        if (inLaunching && always) {
14175            mLaunchingProviders.remove(cpr);
14176        }
14177        return inLaunching;
14178    }
14179
14180    /**
14181     * Main code for cleaning up a process when it has gone away.  This is
14182     * called both as a result of the process dying, or directly when stopping
14183     * a process when running in single process mode.
14184     */
14185    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14186            boolean restarting, boolean allowRestart, int index) {
14187        if (index >= 0) {
14188            removeLruProcessLocked(app);
14189            ProcessList.remove(app.pid);
14190        }
14191
14192        mProcessesToGc.remove(app);
14193        mPendingPssProcesses.remove(app);
14194
14195        // Dismiss any open dialogs.
14196        if (app.crashDialog != null && !app.forceCrashReport) {
14197            app.crashDialog.dismiss();
14198            app.crashDialog = null;
14199        }
14200        if (app.anrDialog != null) {
14201            app.anrDialog.dismiss();
14202            app.anrDialog = null;
14203        }
14204        if (app.waitDialog != null) {
14205            app.waitDialog.dismiss();
14206            app.waitDialog = null;
14207        }
14208
14209        app.crashing = false;
14210        app.notResponding = false;
14211
14212        app.resetPackageList(mProcessStats);
14213        app.unlinkDeathRecipient();
14214        app.makeInactive(mProcessStats);
14215        app.waitingToKill = null;
14216        app.forcingToForeground = null;
14217        updateProcessForegroundLocked(app, false, false);
14218        app.foregroundActivities = false;
14219        app.hasShownUi = false;
14220        app.treatLikeActivity = false;
14221        app.hasAboveClient = false;
14222        app.hasClientActivities = false;
14223
14224        mServices.killServicesLocked(app, allowRestart);
14225
14226        boolean restart = false;
14227
14228        // Remove published content providers.
14229        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14230            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14231            final boolean always = app.bad || !allowRestart;
14232            if (removeDyingProviderLocked(app, cpr, always) || always) {
14233                // We left the provider in the launching list, need to
14234                // restart it.
14235                restart = true;
14236            }
14237
14238            cpr.provider = null;
14239            cpr.proc = null;
14240        }
14241        app.pubProviders.clear();
14242
14243        // Take care of any launching providers waiting for this process.
14244        if (checkAppInLaunchingProvidersLocked(app, false)) {
14245            restart = true;
14246        }
14247
14248        // Unregister from connected content providers.
14249        if (!app.conProviders.isEmpty()) {
14250            for (int i=0; i<app.conProviders.size(); i++) {
14251                ContentProviderConnection conn = app.conProviders.get(i);
14252                conn.provider.connections.remove(conn);
14253            }
14254            app.conProviders.clear();
14255        }
14256
14257        // At this point there may be remaining entries in mLaunchingProviders
14258        // where we were the only one waiting, so they are no longer of use.
14259        // Look for these and clean up if found.
14260        // XXX Commented out for now.  Trying to figure out a way to reproduce
14261        // the actual situation to identify what is actually going on.
14262        if (false) {
14263            for (int i=0; i<mLaunchingProviders.size(); i++) {
14264                ContentProviderRecord cpr = (ContentProviderRecord)
14265                        mLaunchingProviders.get(i);
14266                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14267                    synchronized (cpr) {
14268                        cpr.launchingApp = null;
14269                        cpr.notifyAll();
14270                    }
14271                }
14272            }
14273        }
14274
14275        skipCurrentReceiverLocked(app);
14276
14277        // Unregister any receivers.
14278        for (int i=app.receivers.size()-1; i>=0; i--) {
14279            removeReceiverLocked(app.receivers.valueAt(i));
14280        }
14281        app.receivers.clear();
14282
14283        // If the app is undergoing backup, tell the backup manager about it
14284        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14285            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14286                    + mBackupTarget.appInfo + " died during backup");
14287            try {
14288                IBackupManager bm = IBackupManager.Stub.asInterface(
14289                        ServiceManager.getService(Context.BACKUP_SERVICE));
14290                bm.agentDisconnected(app.info.packageName);
14291            } catch (RemoteException e) {
14292                // can't happen; backup manager is local
14293            }
14294        }
14295
14296        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14297            ProcessChangeItem item = mPendingProcessChanges.get(i);
14298            if (item.pid == app.pid) {
14299                mPendingProcessChanges.remove(i);
14300                mAvailProcessChanges.add(item);
14301            }
14302        }
14303        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14304
14305        // If the caller is restarting this app, then leave it in its
14306        // current lists and let the caller take care of it.
14307        if (restarting) {
14308            return;
14309        }
14310
14311        if (!app.persistent || app.isolated) {
14312            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14313                    "Removing non-persistent process during cleanup: " + app);
14314            mProcessNames.remove(app.processName, app.uid);
14315            mIsolatedProcesses.remove(app.uid);
14316            if (mHeavyWeightProcess == app) {
14317                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14318                        mHeavyWeightProcess.userId, 0));
14319                mHeavyWeightProcess = null;
14320            }
14321        } else if (!app.removed) {
14322            // This app is persistent, so we need to keep its record around.
14323            // If it is not already on the pending app list, add it there
14324            // and start a new process for it.
14325            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14326                mPersistentStartingProcesses.add(app);
14327                restart = true;
14328            }
14329        }
14330        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14331                "Clean-up removing on hold: " + app);
14332        mProcessesOnHold.remove(app);
14333
14334        if (app == mHomeProcess) {
14335            mHomeProcess = null;
14336        }
14337        if (app == mPreviousProcess) {
14338            mPreviousProcess = null;
14339        }
14340
14341        if (restart && !app.isolated) {
14342            // We have components that still need to be running in the
14343            // process, so re-launch it.
14344            mProcessNames.put(app.processName, app.uid, app);
14345            startProcessLocked(app, "restart", app.processName);
14346        } else if (app.pid > 0 && app.pid != MY_PID) {
14347            // Goodbye!
14348            boolean removed;
14349            synchronized (mPidsSelfLocked) {
14350                mPidsSelfLocked.remove(app.pid);
14351                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14352            }
14353            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14354            if (app.isolated) {
14355                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14356            }
14357            app.setPid(0);
14358        }
14359    }
14360
14361    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14362        // Look through the content providers we are waiting to have launched,
14363        // and if any run in this process then either schedule a restart of
14364        // the process or kill the client waiting for it if this process has
14365        // gone bad.
14366        int NL = mLaunchingProviders.size();
14367        boolean restart = false;
14368        for (int i=0; i<NL; i++) {
14369            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14370            if (cpr.launchingApp == app) {
14371                if (!alwaysBad && !app.bad) {
14372                    restart = true;
14373                } else {
14374                    removeDyingProviderLocked(app, cpr, true);
14375                    // cpr should have been removed from mLaunchingProviders
14376                    NL = mLaunchingProviders.size();
14377                    i--;
14378                }
14379            }
14380        }
14381        return restart;
14382    }
14383
14384    // =========================================================
14385    // SERVICES
14386    // =========================================================
14387
14388    @Override
14389    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14390            int flags) {
14391        enforceNotIsolatedCaller("getServices");
14392        synchronized (this) {
14393            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14394        }
14395    }
14396
14397    @Override
14398    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14399        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14400        synchronized (this) {
14401            return mServices.getRunningServiceControlPanelLocked(name);
14402        }
14403    }
14404
14405    @Override
14406    public ComponentName startService(IApplicationThread caller, Intent service,
14407            String resolvedType, int userId) {
14408        enforceNotIsolatedCaller("startService");
14409        // Refuse possible leaked file descriptors
14410        if (service != null && service.hasFileDescriptors() == true) {
14411            throw new IllegalArgumentException("File descriptors passed in Intent");
14412        }
14413
14414        if (DEBUG_SERVICE)
14415            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14416        synchronized(this) {
14417            final int callingPid = Binder.getCallingPid();
14418            final int callingUid = Binder.getCallingUid();
14419            final long origId = Binder.clearCallingIdentity();
14420            ComponentName res = mServices.startServiceLocked(caller, service,
14421                    resolvedType, callingPid, callingUid, userId);
14422            Binder.restoreCallingIdentity(origId);
14423            return res;
14424        }
14425    }
14426
14427    ComponentName startServiceInPackage(int uid,
14428            Intent service, String resolvedType, int userId) {
14429        synchronized(this) {
14430            if (DEBUG_SERVICE)
14431                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14432            final long origId = Binder.clearCallingIdentity();
14433            ComponentName res = mServices.startServiceLocked(null, service,
14434                    resolvedType, -1, uid, userId);
14435            Binder.restoreCallingIdentity(origId);
14436            return res;
14437        }
14438    }
14439
14440    @Override
14441    public int stopService(IApplicationThread caller, Intent service,
14442            String resolvedType, int userId) {
14443        enforceNotIsolatedCaller("stopService");
14444        // Refuse possible leaked file descriptors
14445        if (service != null && service.hasFileDescriptors() == true) {
14446            throw new IllegalArgumentException("File descriptors passed in Intent");
14447        }
14448
14449        synchronized(this) {
14450            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14451        }
14452    }
14453
14454    @Override
14455    public IBinder peekService(Intent service, String resolvedType) {
14456        enforceNotIsolatedCaller("peekService");
14457        // Refuse possible leaked file descriptors
14458        if (service != null && service.hasFileDescriptors() == true) {
14459            throw new IllegalArgumentException("File descriptors passed in Intent");
14460        }
14461        synchronized(this) {
14462            return mServices.peekServiceLocked(service, resolvedType);
14463        }
14464    }
14465
14466    @Override
14467    public boolean stopServiceToken(ComponentName className, IBinder token,
14468            int startId) {
14469        synchronized(this) {
14470            return mServices.stopServiceTokenLocked(className, token, startId);
14471        }
14472    }
14473
14474    @Override
14475    public void setServiceForeground(ComponentName className, IBinder token,
14476            int id, Notification notification, boolean removeNotification) {
14477        synchronized(this) {
14478            mServices.setServiceForegroundLocked(className, token, id, notification,
14479                    removeNotification);
14480        }
14481    }
14482
14483    @Override
14484    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14485            boolean requireFull, String name, String callerPackage) {
14486        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14487                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14488    }
14489
14490    int unsafeConvertIncomingUser(int userId) {
14491        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14492                ? mCurrentUserId : userId;
14493    }
14494
14495    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14496            int allowMode, String name, String callerPackage) {
14497        final int callingUserId = UserHandle.getUserId(callingUid);
14498        if (callingUserId == userId) {
14499            return userId;
14500        }
14501
14502        // Note that we may be accessing mCurrentUserId outside of a lock...
14503        // shouldn't be a big deal, if this is being called outside
14504        // of a locked context there is intrinsically a race with
14505        // the value the caller will receive and someone else changing it.
14506        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14507        // we will switch to the calling user if access to the current user fails.
14508        int targetUserId = unsafeConvertIncomingUser(userId);
14509
14510        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14511            final boolean allow;
14512            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14513                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14514                // If the caller has this permission, they always pass go.  And collect $200.
14515                allow = true;
14516            } else if (allowMode == ALLOW_FULL_ONLY) {
14517                // We require full access, sucks to be you.
14518                allow = false;
14519            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14520                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14521                // If the caller does not have either permission, they are always doomed.
14522                allow = false;
14523            } else if (allowMode == ALLOW_NON_FULL) {
14524                // We are blanket allowing non-full access, you lucky caller!
14525                allow = true;
14526            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14527                // We may or may not allow this depending on whether the two users are
14528                // in the same profile.
14529                synchronized (mUserProfileGroupIdsSelfLocked) {
14530                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14531                            UserInfo.NO_PROFILE_GROUP_ID);
14532                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14533                            UserInfo.NO_PROFILE_GROUP_ID);
14534                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14535                            && callingProfile == targetProfile;
14536                }
14537            } else {
14538                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14539            }
14540            if (!allow) {
14541                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14542                    // In this case, they would like to just execute as their
14543                    // owner user instead of failing.
14544                    targetUserId = callingUserId;
14545                } else {
14546                    StringBuilder builder = new StringBuilder(128);
14547                    builder.append("Permission Denial: ");
14548                    builder.append(name);
14549                    if (callerPackage != null) {
14550                        builder.append(" from ");
14551                        builder.append(callerPackage);
14552                    }
14553                    builder.append(" asks to run as user ");
14554                    builder.append(userId);
14555                    builder.append(" but is calling from user ");
14556                    builder.append(UserHandle.getUserId(callingUid));
14557                    builder.append("; this requires ");
14558                    builder.append(INTERACT_ACROSS_USERS_FULL);
14559                    if (allowMode != ALLOW_FULL_ONLY) {
14560                        builder.append(" or ");
14561                        builder.append(INTERACT_ACROSS_USERS);
14562                    }
14563                    String msg = builder.toString();
14564                    Slog.w(TAG, msg);
14565                    throw new SecurityException(msg);
14566                }
14567            }
14568        }
14569        if (!allowAll && targetUserId < 0) {
14570            throw new IllegalArgumentException(
14571                    "Call does not support special user #" + targetUserId);
14572        }
14573        return targetUserId;
14574    }
14575
14576    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14577            String className, int flags) {
14578        boolean result = false;
14579        // For apps that don't have pre-defined UIDs, check for permission
14580        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14581            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14582                if (ActivityManager.checkUidPermission(
14583                        INTERACT_ACROSS_USERS,
14584                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14585                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14586                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14587                            + " requests FLAG_SINGLE_USER, but app does not hold "
14588                            + INTERACT_ACROSS_USERS;
14589                    Slog.w(TAG, msg);
14590                    throw new SecurityException(msg);
14591                }
14592                // Permission passed
14593                result = true;
14594            }
14595        } else if ("system".equals(componentProcessName)) {
14596            result = true;
14597        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14598                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14599            // Phone app is allowed to export singleuser providers.
14600            result = true;
14601        } else {
14602            // App with pre-defined UID, check if it's a persistent app
14603            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14604        }
14605        if (DEBUG_MU) {
14606            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14607                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14608        }
14609        return result;
14610    }
14611
14612    /**
14613     * Checks to see if the caller is in the same app as the singleton
14614     * component, or the component is in a special app. It allows special apps
14615     * to export singleton components but prevents exporting singleton
14616     * components for regular apps.
14617     */
14618    boolean isValidSingletonCall(int callingUid, int componentUid) {
14619        int componentAppId = UserHandle.getAppId(componentUid);
14620        return UserHandle.isSameApp(callingUid, componentUid)
14621                || componentAppId == Process.SYSTEM_UID
14622                || componentAppId == Process.PHONE_UID
14623                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14624                        == PackageManager.PERMISSION_GRANTED;
14625    }
14626
14627    public int bindService(IApplicationThread caller, IBinder token,
14628            Intent service, String resolvedType,
14629            IServiceConnection connection, int flags, int userId) {
14630        enforceNotIsolatedCaller("bindService");
14631        // Refuse possible leaked file descriptors
14632        if (service != null && service.hasFileDescriptors() == true) {
14633            throw new IllegalArgumentException("File descriptors passed in Intent");
14634        }
14635
14636        synchronized(this) {
14637            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14638                    connection, flags, userId);
14639        }
14640    }
14641
14642    public boolean unbindService(IServiceConnection connection) {
14643        synchronized (this) {
14644            return mServices.unbindServiceLocked(connection);
14645        }
14646    }
14647
14648    public void publishService(IBinder token, Intent intent, IBinder service) {
14649        // Refuse possible leaked file descriptors
14650        if (intent != null && intent.hasFileDescriptors() == true) {
14651            throw new IllegalArgumentException("File descriptors passed in Intent");
14652        }
14653
14654        synchronized(this) {
14655            if (!(token instanceof ServiceRecord)) {
14656                throw new IllegalArgumentException("Invalid service token");
14657            }
14658            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14659        }
14660    }
14661
14662    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14663        // Refuse possible leaked file descriptors
14664        if (intent != null && intent.hasFileDescriptors() == true) {
14665            throw new IllegalArgumentException("File descriptors passed in Intent");
14666        }
14667
14668        synchronized(this) {
14669            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14670        }
14671    }
14672
14673    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14674        synchronized(this) {
14675            if (!(token instanceof ServiceRecord)) {
14676                throw new IllegalArgumentException("Invalid service token");
14677            }
14678            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14679        }
14680    }
14681
14682    // =========================================================
14683    // BACKUP AND RESTORE
14684    // =========================================================
14685
14686    // Cause the target app to be launched if necessary and its backup agent
14687    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14688    // activity manager to announce its creation.
14689    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14690        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14691        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14692
14693        synchronized(this) {
14694            // !!! TODO: currently no check here that we're already bound
14695            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14696            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14697            synchronized (stats) {
14698                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14699            }
14700
14701            // Backup agent is now in use, its package can't be stopped.
14702            try {
14703                AppGlobals.getPackageManager().setPackageStoppedState(
14704                        app.packageName, false, UserHandle.getUserId(app.uid));
14705            } catch (RemoteException e) {
14706            } catch (IllegalArgumentException e) {
14707                Slog.w(TAG, "Failed trying to unstop package "
14708                        + app.packageName + ": " + e);
14709            }
14710
14711            BackupRecord r = new BackupRecord(ss, app, backupMode);
14712            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14713                    ? new ComponentName(app.packageName, app.backupAgentName)
14714                    : new ComponentName("android", "FullBackupAgent");
14715            // startProcessLocked() returns existing proc's record if it's already running
14716            ProcessRecord proc = startProcessLocked(app.processName, app,
14717                    false, 0, "backup", hostingName, false, false, false);
14718            if (proc == null) {
14719                Slog.e(TAG, "Unable to start backup agent process " + r);
14720                return false;
14721            }
14722
14723            r.app = proc;
14724            mBackupTarget = r;
14725            mBackupAppName = app.packageName;
14726
14727            // Try not to kill the process during backup
14728            updateOomAdjLocked(proc);
14729
14730            // If the process is already attached, schedule the creation of the backup agent now.
14731            // If it is not yet live, this will be done when it attaches to the framework.
14732            if (proc.thread != null) {
14733                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14734                try {
14735                    proc.thread.scheduleCreateBackupAgent(app,
14736                            compatibilityInfoForPackageLocked(app), backupMode);
14737                } catch (RemoteException e) {
14738                    // Will time out on the backup manager side
14739                }
14740            } else {
14741                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14742            }
14743            // Invariants: at this point, the target app process exists and the application
14744            // is either already running or in the process of coming up.  mBackupTarget and
14745            // mBackupAppName describe the app, so that when it binds back to the AM we
14746            // know that it's scheduled for a backup-agent operation.
14747        }
14748
14749        return true;
14750    }
14751
14752    @Override
14753    public void clearPendingBackup() {
14754        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14755        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14756
14757        synchronized (this) {
14758            mBackupTarget = null;
14759            mBackupAppName = null;
14760        }
14761    }
14762
14763    // A backup agent has just come up
14764    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14765        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14766                + " = " + agent);
14767
14768        synchronized(this) {
14769            if (!agentPackageName.equals(mBackupAppName)) {
14770                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14771                return;
14772            }
14773        }
14774
14775        long oldIdent = Binder.clearCallingIdentity();
14776        try {
14777            IBackupManager bm = IBackupManager.Stub.asInterface(
14778                    ServiceManager.getService(Context.BACKUP_SERVICE));
14779            bm.agentConnected(agentPackageName, agent);
14780        } catch (RemoteException e) {
14781            // can't happen; the backup manager service is local
14782        } catch (Exception e) {
14783            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14784            e.printStackTrace();
14785        } finally {
14786            Binder.restoreCallingIdentity(oldIdent);
14787        }
14788    }
14789
14790    // done with this agent
14791    public void unbindBackupAgent(ApplicationInfo appInfo) {
14792        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14793        if (appInfo == null) {
14794            Slog.w(TAG, "unbind backup agent for null app");
14795            return;
14796        }
14797
14798        synchronized(this) {
14799            try {
14800                if (mBackupAppName == null) {
14801                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14802                    return;
14803                }
14804
14805                if (!mBackupAppName.equals(appInfo.packageName)) {
14806                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14807                    return;
14808                }
14809
14810                // Not backing this app up any more; reset its OOM adjustment
14811                final ProcessRecord proc = mBackupTarget.app;
14812                updateOomAdjLocked(proc);
14813
14814                // If the app crashed during backup, 'thread' will be null here
14815                if (proc.thread != null) {
14816                    try {
14817                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14818                                compatibilityInfoForPackageLocked(appInfo));
14819                    } catch (Exception e) {
14820                        Slog.e(TAG, "Exception when unbinding backup agent:");
14821                        e.printStackTrace();
14822                    }
14823                }
14824            } finally {
14825                mBackupTarget = null;
14826                mBackupAppName = null;
14827            }
14828        }
14829    }
14830    // =========================================================
14831    // BROADCASTS
14832    // =========================================================
14833
14834    private final List getStickiesLocked(String action, IntentFilter filter,
14835            List cur, int userId) {
14836        final ContentResolver resolver = mContext.getContentResolver();
14837        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14838        if (stickies == null) {
14839            return cur;
14840        }
14841        final ArrayList<Intent> list = stickies.get(action);
14842        if (list == null) {
14843            return cur;
14844        }
14845        int N = list.size();
14846        for (int i=0; i<N; i++) {
14847            Intent intent = list.get(i);
14848            if (filter.match(resolver, intent, true, TAG) >= 0) {
14849                if (cur == null) {
14850                    cur = new ArrayList<Intent>();
14851                }
14852                cur.add(intent);
14853            }
14854        }
14855        return cur;
14856    }
14857
14858    boolean isPendingBroadcastProcessLocked(int pid) {
14859        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14860                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14861    }
14862
14863    void skipPendingBroadcastLocked(int pid) {
14864            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14865            for (BroadcastQueue queue : mBroadcastQueues) {
14866                queue.skipPendingBroadcastLocked(pid);
14867            }
14868    }
14869
14870    // The app just attached; send any pending broadcasts that it should receive
14871    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14872        boolean didSomething = false;
14873        for (BroadcastQueue queue : mBroadcastQueues) {
14874            didSomething |= queue.sendPendingBroadcastsLocked(app);
14875        }
14876        return didSomething;
14877    }
14878
14879    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14880            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14881        enforceNotIsolatedCaller("registerReceiver");
14882        int callingUid;
14883        int callingPid;
14884        synchronized(this) {
14885            ProcessRecord callerApp = null;
14886            if (caller != null) {
14887                callerApp = getRecordForAppLocked(caller);
14888                if (callerApp == null) {
14889                    throw new SecurityException(
14890                            "Unable to find app for caller " + caller
14891                            + " (pid=" + Binder.getCallingPid()
14892                            + ") when registering receiver " + receiver);
14893                }
14894                if (callerApp.info.uid != Process.SYSTEM_UID &&
14895                        !callerApp.pkgList.containsKey(callerPackage) &&
14896                        !"android".equals(callerPackage)) {
14897                    throw new SecurityException("Given caller package " + callerPackage
14898                            + " is not running in process " + callerApp);
14899                }
14900                callingUid = callerApp.info.uid;
14901                callingPid = callerApp.pid;
14902            } else {
14903                callerPackage = null;
14904                callingUid = Binder.getCallingUid();
14905                callingPid = Binder.getCallingPid();
14906            }
14907
14908            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14909                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14910
14911            List allSticky = null;
14912
14913            // Look for any matching sticky broadcasts...
14914            Iterator actions = filter.actionsIterator();
14915            if (actions != null) {
14916                while (actions.hasNext()) {
14917                    String action = (String)actions.next();
14918                    allSticky = getStickiesLocked(action, filter, allSticky,
14919                            UserHandle.USER_ALL);
14920                    allSticky = getStickiesLocked(action, filter, allSticky,
14921                            UserHandle.getUserId(callingUid));
14922                }
14923            } else {
14924                allSticky = getStickiesLocked(null, filter, allSticky,
14925                        UserHandle.USER_ALL);
14926                allSticky = getStickiesLocked(null, filter, allSticky,
14927                        UserHandle.getUserId(callingUid));
14928            }
14929
14930            // The first sticky in the list is returned directly back to
14931            // the client.
14932            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14933
14934            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14935                    + ": " + sticky);
14936
14937            if (receiver == null) {
14938                return sticky;
14939            }
14940
14941            ReceiverList rl
14942                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14943            if (rl == null) {
14944                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14945                        userId, receiver);
14946                if (rl.app != null) {
14947                    rl.app.receivers.add(rl);
14948                } else {
14949                    try {
14950                        receiver.asBinder().linkToDeath(rl, 0);
14951                    } catch (RemoteException e) {
14952                        return sticky;
14953                    }
14954                    rl.linkedToDeath = true;
14955                }
14956                mRegisteredReceivers.put(receiver.asBinder(), rl);
14957            } else if (rl.uid != callingUid) {
14958                throw new IllegalArgumentException(
14959                        "Receiver requested to register for uid " + callingUid
14960                        + " was previously registered for uid " + rl.uid);
14961            } else if (rl.pid != callingPid) {
14962                throw new IllegalArgumentException(
14963                        "Receiver requested to register for pid " + callingPid
14964                        + " was previously registered for pid " + rl.pid);
14965            } else if (rl.userId != userId) {
14966                throw new IllegalArgumentException(
14967                        "Receiver requested to register for user " + userId
14968                        + " was previously registered for user " + rl.userId);
14969            }
14970            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14971                    permission, callingUid, userId);
14972            rl.add(bf);
14973            if (!bf.debugCheck()) {
14974                Slog.w(TAG, "==> For Dynamic broadast");
14975            }
14976            mReceiverResolver.addFilter(bf);
14977
14978            // Enqueue broadcasts for all existing stickies that match
14979            // this filter.
14980            if (allSticky != null) {
14981                ArrayList receivers = new ArrayList();
14982                receivers.add(bf);
14983
14984                int N = allSticky.size();
14985                for (int i=0; i<N; i++) {
14986                    Intent intent = (Intent)allSticky.get(i);
14987                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14988                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14989                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14990                            null, null, false, true, true, -1);
14991                    queue.enqueueParallelBroadcastLocked(r);
14992                    queue.scheduleBroadcastsLocked();
14993                }
14994            }
14995
14996            return sticky;
14997        }
14998    }
14999
15000    public void unregisterReceiver(IIntentReceiver receiver) {
15001        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15002
15003        final long origId = Binder.clearCallingIdentity();
15004        try {
15005            boolean doTrim = false;
15006
15007            synchronized(this) {
15008                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15009                if (rl != null) {
15010                    if (rl.curBroadcast != null) {
15011                        BroadcastRecord r = rl.curBroadcast;
15012                        final boolean doNext = finishReceiverLocked(
15013                                receiver.asBinder(), r.resultCode, r.resultData,
15014                                r.resultExtras, r.resultAbort);
15015                        if (doNext) {
15016                            doTrim = true;
15017                            r.queue.processNextBroadcast(false);
15018                        }
15019                    }
15020
15021                    if (rl.app != null) {
15022                        rl.app.receivers.remove(rl);
15023                    }
15024                    removeReceiverLocked(rl);
15025                    if (rl.linkedToDeath) {
15026                        rl.linkedToDeath = false;
15027                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15028                    }
15029                }
15030            }
15031
15032            // If we actually concluded any broadcasts, we might now be able
15033            // to trim the recipients' apps from our working set
15034            if (doTrim) {
15035                trimApplications();
15036                return;
15037            }
15038
15039        } finally {
15040            Binder.restoreCallingIdentity(origId);
15041        }
15042    }
15043
15044    void removeReceiverLocked(ReceiverList rl) {
15045        mRegisteredReceivers.remove(rl.receiver.asBinder());
15046        int N = rl.size();
15047        for (int i=0; i<N; i++) {
15048            mReceiverResolver.removeFilter(rl.get(i));
15049        }
15050    }
15051
15052    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15053        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15054            ProcessRecord r = mLruProcesses.get(i);
15055            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15056                try {
15057                    r.thread.dispatchPackageBroadcast(cmd, packages);
15058                } catch (RemoteException ex) {
15059                }
15060            }
15061        }
15062    }
15063
15064    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15065            int[] users) {
15066        List<ResolveInfo> receivers = null;
15067        try {
15068            HashSet<ComponentName> singleUserReceivers = null;
15069            boolean scannedFirstReceivers = false;
15070            for (int user : users) {
15071                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15072                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15073                if (user != 0 && newReceivers != null) {
15074                    // If this is not the primary user, we need to check for
15075                    // any receivers that should be filtered out.
15076                    for (int i=0; i<newReceivers.size(); i++) {
15077                        ResolveInfo ri = newReceivers.get(i);
15078                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15079                            newReceivers.remove(i);
15080                            i--;
15081                        }
15082                    }
15083                }
15084                if (newReceivers != null && newReceivers.size() == 0) {
15085                    newReceivers = null;
15086                }
15087                if (receivers == null) {
15088                    receivers = newReceivers;
15089                } else if (newReceivers != null) {
15090                    // We need to concatenate the additional receivers
15091                    // found with what we have do far.  This would be easy,
15092                    // but we also need to de-dup any receivers that are
15093                    // singleUser.
15094                    if (!scannedFirstReceivers) {
15095                        // Collect any single user receivers we had already retrieved.
15096                        scannedFirstReceivers = true;
15097                        for (int i=0; i<receivers.size(); i++) {
15098                            ResolveInfo ri = receivers.get(i);
15099                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15100                                ComponentName cn = new ComponentName(
15101                                        ri.activityInfo.packageName, ri.activityInfo.name);
15102                                if (singleUserReceivers == null) {
15103                                    singleUserReceivers = new HashSet<ComponentName>();
15104                                }
15105                                singleUserReceivers.add(cn);
15106                            }
15107                        }
15108                    }
15109                    // Add the new results to the existing results, tracking
15110                    // and de-dupping single user receivers.
15111                    for (int i=0; i<newReceivers.size(); i++) {
15112                        ResolveInfo ri = newReceivers.get(i);
15113                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15114                            ComponentName cn = new ComponentName(
15115                                    ri.activityInfo.packageName, ri.activityInfo.name);
15116                            if (singleUserReceivers == null) {
15117                                singleUserReceivers = new HashSet<ComponentName>();
15118                            }
15119                            if (!singleUserReceivers.contains(cn)) {
15120                                singleUserReceivers.add(cn);
15121                                receivers.add(ri);
15122                            }
15123                        } else {
15124                            receivers.add(ri);
15125                        }
15126                    }
15127                }
15128            }
15129        } catch (RemoteException ex) {
15130            // pm is in same process, this will never happen.
15131        }
15132        return receivers;
15133    }
15134
15135    private final int broadcastIntentLocked(ProcessRecord callerApp,
15136            String callerPackage, Intent intent, String resolvedType,
15137            IIntentReceiver resultTo, int resultCode, String resultData,
15138            Bundle map, String requiredPermission, int appOp,
15139            boolean ordered, boolean sticky, int callingPid, int callingUid,
15140            int userId) {
15141        intent = new Intent(intent);
15142
15143        // By default broadcasts do not go to stopped apps.
15144        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15145
15146        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15147            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15148            + " ordered=" + ordered + " userid=" + userId);
15149        if ((resultTo != null) && !ordered) {
15150            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15151        }
15152
15153        userId = handleIncomingUser(callingPid, callingUid, userId,
15154                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15155
15156        // Make sure that the user who is receiving this broadcast is started.
15157        // If not, we will just skip it.
15158
15159
15160        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15161            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15162                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15163                Slog.w(TAG, "Skipping broadcast of " + intent
15164                        + ": user " + userId + " is stopped");
15165                return ActivityManager.BROADCAST_SUCCESS;
15166            }
15167        }
15168
15169        /*
15170         * Prevent non-system code (defined here to be non-persistent
15171         * processes) from sending protected broadcasts.
15172         */
15173        int callingAppId = UserHandle.getAppId(callingUid);
15174        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15175            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15176            || callingAppId == Process.NFC_UID || callingUid == 0) {
15177            // Always okay.
15178        } else if (callerApp == null || !callerApp.persistent) {
15179            try {
15180                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15181                        intent.getAction())) {
15182                    String msg = "Permission Denial: not allowed to send broadcast "
15183                            + intent.getAction() + " from pid="
15184                            + callingPid + ", uid=" + callingUid;
15185                    Slog.w(TAG, msg);
15186                    throw new SecurityException(msg);
15187                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15188                    // Special case for compatibility: we don't want apps to send this,
15189                    // but historically it has not been protected and apps may be using it
15190                    // to poke their own app widget.  So, instead of making it protected,
15191                    // just limit it to the caller.
15192                    if (callerApp == null) {
15193                        String msg = "Permission Denial: not allowed to send broadcast "
15194                                + intent.getAction() + " from unknown caller.";
15195                        Slog.w(TAG, msg);
15196                        throw new SecurityException(msg);
15197                    } else if (intent.getComponent() != null) {
15198                        // They are good enough to send to an explicit component...  verify
15199                        // it is being sent to the calling app.
15200                        if (!intent.getComponent().getPackageName().equals(
15201                                callerApp.info.packageName)) {
15202                            String msg = "Permission Denial: not allowed to send broadcast "
15203                                    + intent.getAction() + " to "
15204                                    + intent.getComponent().getPackageName() + " from "
15205                                    + callerApp.info.packageName;
15206                            Slog.w(TAG, msg);
15207                            throw new SecurityException(msg);
15208                        }
15209                    } else {
15210                        // Limit broadcast to their own package.
15211                        intent.setPackage(callerApp.info.packageName);
15212                    }
15213                }
15214            } catch (RemoteException e) {
15215                Slog.w(TAG, "Remote exception", e);
15216                return ActivityManager.BROADCAST_SUCCESS;
15217            }
15218        }
15219
15220        // Handle special intents: if this broadcast is from the package
15221        // manager about a package being removed, we need to remove all of
15222        // its activities from the history stack.
15223        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15224                intent.getAction());
15225        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15226                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15227                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15228                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15229                || uidRemoved) {
15230            if (checkComponentPermission(
15231                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15232                    callingPid, callingUid, -1, true)
15233                    == PackageManager.PERMISSION_GRANTED) {
15234                if (uidRemoved) {
15235                    final Bundle intentExtras = intent.getExtras();
15236                    final int uid = intentExtras != null
15237                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15238                    if (uid >= 0) {
15239                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15240                        synchronized (bs) {
15241                            bs.removeUidStatsLocked(uid);
15242                        }
15243                        mAppOpsService.uidRemoved(uid);
15244                    }
15245                } else {
15246                    // If resources are unavailable just force stop all
15247                    // those packages and flush the attribute cache as well.
15248                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15249                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15250                        if (list != null && (list.length > 0)) {
15251                            for (String pkg : list) {
15252                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15253                                        "storage unmount");
15254                            }
15255                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15256                            sendPackageBroadcastLocked(
15257                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15258                        }
15259                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15260                            intent.getAction())) {
15261                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15262                    } else {
15263                        Uri data = intent.getData();
15264                        String ssp;
15265                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15266                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15267                                    intent.getAction());
15268                            boolean fullUninstall = removed &&
15269                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15270                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15271                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15272                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15273                                        false, fullUninstall, userId,
15274                                        removed ? "pkg removed" : "pkg changed");
15275                            }
15276                            if (removed) {
15277                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15278                                        new String[] {ssp}, userId);
15279                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15280                                    mAppOpsService.packageRemoved(
15281                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15282
15283                                    // Remove all permissions granted from/to this package
15284                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15285                                }
15286                            }
15287                        }
15288                    }
15289                }
15290            } else {
15291                String msg = "Permission Denial: " + intent.getAction()
15292                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15293                        + ", uid=" + callingUid + ")"
15294                        + " requires "
15295                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15296                Slog.w(TAG, msg);
15297                throw new SecurityException(msg);
15298            }
15299
15300        // Special case for adding a package: by default turn on compatibility
15301        // mode.
15302        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15303            Uri data = intent.getData();
15304            String ssp;
15305            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15306                mCompatModePackages.handlePackageAddedLocked(ssp,
15307                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15308            }
15309        }
15310
15311        /*
15312         * If this is the time zone changed action, queue up a message that will reset the timezone
15313         * of all currently running processes. This message will get queued up before the broadcast
15314         * happens.
15315         */
15316        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15317            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15318        }
15319
15320        /*
15321         * If the user set the time, let all running processes know.
15322         */
15323        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15324            final int is24Hour = intent.getBooleanExtra(
15325                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15326            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15327            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15328            synchronized (stats) {
15329                stats.noteCurrentTimeChangedLocked();
15330            }
15331        }
15332
15333        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15334            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15335        }
15336
15337        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15338            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15339            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15340        }
15341
15342        // Add to the sticky list if requested.
15343        if (sticky) {
15344            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15345                    callingPid, callingUid)
15346                    != PackageManager.PERMISSION_GRANTED) {
15347                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15348                        + callingPid + ", uid=" + callingUid
15349                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15350                Slog.w(TAG, msg);
15351                throw new SecurityException(msg);
15352            }
15353            if (requiredPermission != null) {
15354                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15355                        + " and enforce permission " + requiredPermission);
15356                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15357            }
15358            if (intent.getComponent() != null) {
15359                throw new SecurityException(
15360                        "Sticky broadcasts can't target a specific component");
15361            }
15362            // We use userId directly here, since the "all" target is maintained
15363            // as a separate set of sticky broadcasts.
15364            if (userId != UserHandle.USER_ALL) {
15365                // But first, if this is not a broadcast to all users, then
15366                // make sure it doesn't conflict with an existing broadcast to
15367                // all users.
15368                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15369                        UserHandle.USER_ALL);
15370                if (stickies != null) {
15371                    ArrayList<Intent> list = stickies.get(intent.getAction());
15372                    if (list != null) {
15373                        int N = list.size();
15374                        int i;
15375                        for (i=0; i<N; i++) {
15376                            if (intent.filterEquals(list.get(i))) {
15377                                throw new IllegalArgumentException(
15378                                        "Sticky broadcast " + intent + " for user "
15379                                        + userId + " conflicts with existing global broadcast");
15380                            }
15381                        }
15382                    }
15383                }
15384            }
15385            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15386            if (stickies == null) {
15387                stickies = new ArrayMap<String, ArrayList<Intent>>();
15388                mStickyBroadcasts.put(userId, stickies);
15389            }
15390            ArrayList<Intent> list = stickies.get(intent.getAction());
15391            if (list == null) {
15392                list = new ArrayList<Intent>();
15393                stickies.put(intent.getAction(), list);
15394            }
15395            int N = list.size();
15396            int i;
15397            for (i=0; i<N; i++) {
15398                if (intent.filterEquals(list.get(i))) {
15399                    // This sticky already exists, replace it.
15400                    list.set(i, new Intent(intent));
15401                    break;
15402                }
15403            }
15404            if (i >= N) {
15405                list.add(new Intent(intent));
15406            }
15407        }
15408
15409        int[] users;
15410        if (userId == UserHandle.USER_ALL) {
15411            // Caller wants broadcast to go to all started users.
15412            users = mStartedUserArray;
15413        } else {
15414            // Caller wants broadcast to go to one specific user.
15415            users = new int[] {userId};
15416        }
15417
15418        // Figure out who all will receive this broadcast.
15419        List receivers = null;
15420        List<BroadcastFilter> registeredReceivers = null;
15421        // Need to resolve the intent to interested receivers...
15422        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15423                 == 0) {
15424            receivers = collectReceiverComponents(intent, resolvedType, users);
15425        }
15426        if (intent.getComponent() == null) {
15427            registeredReceivers = mReceiverResolver.queryIntent(intent,
15428                    resolvedType, false, userId);
15429        }
15430
15431        final boolean replacePending =
15432                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15433
15434        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15435                + " replacePending=" + replacePending);
15436
15437        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15438        if (!ordered && NR > 0) {
15439            // If we are not serializing this broadcast, then send the
15440            // registered receivers separately so they don't wait for the
15441            // components to be launched.
15442            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15443            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15444                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15445                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15446                    ordered, sticky, false, userId);
15447            if (DEBUG_BROADCAST) Slog.v(
15448                    TAG, "Enqueueing parallel broadcast " + r);
15449            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15450            if (!replaced) {
15451                queue.enqueueParallelBroadcastLocked(r);
15452                queue.scheduleBroadcastsLocked();
15453            }
15454            registeredReceivers = null;
15455            NR = 0;
15456        }
15457
15458        // Merge into one list.
15459        int ir = 0;
15460        if (receivers != null) {
15461            // A special case for PACKAGE_ADDED: do not allow the package
15462            // being added to see this broadcast.  This prevents them from
15463            // using this as a back door to get run as soon as they are
15464            // installed.  Maybe in the future we want to have a special install
15465            // broadcast or such for apps, but we'd like to deliberately make
15466            // this decision.
15467            String skipPackages[] = null;
15468            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15469                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15470                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15471                Uri data = intent.getData();
15472                if (data != null) {
15473                    String pkgName = data.getSchemeSpecificPart();
15474                    if (pkgName != null) {
15475                        skipPackages = new String[] { pkgName };
15476                    }
15477                }
15478            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15479                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15480            }
15481            if (skipPackages != null && (skipPackages.length > 0)) {
15482                for (String skipPackage : skipPackages) {
15483                    if (skipPackage != null) {
15484                        int NT = receivers.size();
15485                        for (int it=0; it<NT; it++) {
15486                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15487                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15488                                receivers.remove(it);
15489                                it--;
15490                                NT--;
15491                            }
15492                        }
15493                    }
15494                }
15495            }
15496
15497            int NT = receivers != null ? receivers.size() : 0;
15498            int it = 0;
15499            ResolveInfo curt = null;
15500            BroadcastFilter curr = null;
15501            while (it < NT && ir < NR) {
15502                if (curt == null) {
15503                    curt = (ResolveInfo)receivers.get(it);
15504                }
15505                if (curr == null) {
15506                    curr = registeredReceivers.get(ir);
15507                }
15508                if (curr.getPriority() >= curt.priority) {
15509                    // Insert this broadcast record into the final list.
15510                    receivers.add(it, curr);
15511                    ir++;
15512                    curr = null;
15513                    it++;
15514                    NT++;
15515                } else {
15516                    // Skip to the next ResolveInfo in the final list.
15517                    it++;
15518                    curt = null;
15519                }
15520            }
15521        }
15522        while (ir < NR) {
15523            if (receivers == null) {
15524                receivers = new ArrayList();
15525            }
15526            receivers.add(registeredReceivers.get(ir));
15527            ir++;
15528        }
15529
15530        if ((receivers != null && receivers.size() > 0)
15531                || resultTo != null) {
15532            BroadcastQueue queue = broadcastQueueForIntent(intent);
15533            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15534                    callerPackage, callingPid, callingUid, resolvedType,
15535                    requiredPermission, appOp, receivers, resultTo, resultCode,
15536                    resultData, map, ordered, sticky, false, userId);
15537            if (DEBUG_BROADCAST) Slog.v(
15538                    TAG, "Enqueueing ordered broadcast " + r
15539                    + ": prev had " + queue.mOrderedBroadcasts.size());
15540            if (DEBUG_BROADCAST) {
15541                int seq = r.intent.getIntExtra("seq", -1);
15542                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15543            }
15544            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15545            if (!replaced) {
15546                queue.enqueueOrderedBroadcastLocked(r);
15547                queue.scheduleBroadcastsLocked();
15548            }
15549        }
15550
15551        return ActivityManager.BROADCAST_SUCCESS;
15552    }
15553
15554    final Intent verifyBroadcastLocked(Intent intent) {
15555        // Refuse possible leaked file descriptors
15556        if (intent != null && intent.hasFileDescriptors() == true) {
15557            throw new IllegalArgumentException("File descriptors passed in Intent");
15558        }
15559
15560        int flags = intent.getFlags();
15561
15562        if (!mProcessesReady) {
15563            // if the caller really truly claims to know what they're doing, go
15564            // ahead and allow the broadcast without launching any receivers
15565            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15566                intent = new Intent(intent);
15567                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15568            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15569                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15570                        + " before boot completion");
15571                throw new IllegalStateException("Cannot broadcast before boot completed");
15572            }
15573        }
15574
15575        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15576            throw new IllegalArgumentException(
15577                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15578        }
15579
15580        return intent;
15581    }
15582
15583    public final int broadcastIntent(IApplicationThread caller,
15584            Intent intent, String resolvedType, IIntentReceiver resultTo,
15585            int resultCode, String resultData, Bundle map,
15586            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15587        enforceNotIsolatedCaller("broadcastIntent");
15588        synchronized(this) {
15589            intent = verifyBroadcastLocked(intent);
15590
15591            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15592            final int callingPid = Binder.getCallingPid();
15593            final int callingUid = Binder.getCallingUid();
15594            final long origId = Binder.clearCallingIdentity();
15595            int res = broadcastIntentLocked(callerApp,
15596                    callerApp != null ? callerApp.info.packageName : null,
15597                    intent, resolvedType, resultTo,
15598                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15599                    callingPid, callingUid, userId);
15600            Binder.restoreCallingIdentity(origId);
15601            return res;
15602        }
15603    }
15604
15605    int broadcastIntentInPackage(String packageName, int uid,
15606            Intent intent, String resolvedType, IIntentReceiver resultTo,
15607            int resultCode, String resultData, Bundle map,
15608            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15609        synchronized(this) {
15610            intent = verifyBroadcastLocked(intent);
15611
15612            final long origId = Binder.clearCallingIdentity();
15613            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15614                    resultTo, resultCode, resultData, map, requiredPermission,
15615                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15616            Binder.restoreCallingIdentity(origId);
15617            return res;
15618        }
15619    }
15620
15621    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15622        // Refuse possible leaked file descriptors
15623        if (intent != null && intent.hasFileDescriptors() == true) {
15624            throw new IllegalArgumentException("File descriptors passed in Intent");
15625        }
15626
15627        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15628                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15629
15630        synchronized(this) {
15631            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15632                    != PackageManager.PERMISSION_GRANTED) {
15633                String msg = "Permission Denial: unbroadcastIntent() from pid="
15634                        + Binder.getCallingPid()
15635                        + ", uid=" + Binder.getCallingUid()
15636                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15637                Slog.w(TAG, msg);
15638                throw new SecurityException(msg);
15639            }
15640            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15641            if (stickies != null) {
15642                ArrayList<Intent> list = stickies.get(intent.getAction());
15643                if (list != null) {
15644                    int N = list.size();
15645                    int i;
15646                    for (i=0; i<N; i++) {
15647                        if (intent.filterEquals(list.get(i))) {
15648                            list.remove(i);
15649                            break;
15650                        }
15651                    }
15652                    if (list.size() <= 0) {
15653                        stickies.remove(intent.getAction());
15654                    }
15655                }
15656                if (stickies.size() <= 0) {
15657                    mStickyBroadcasts.remove(userId);
15658                }
15659            }
15660        }
15661    }
15662
15663    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15664            String resultData, Bundle resultExtras, boolean resultAbort) {
15665        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15666        if (r == null) {
15667            Slog.w(TAG, "finishReceiver called but not found on queue");
15668            return false;
15669        }
15670
15671        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15672    }
15673
15674    void backgroundServicesFinishedLocked(int userId) {
15675        for (BroadcastQueue queue : mBroadcastQueues) {
15676            queue.backgroundServicesFinishedLocked(userId);
15677        }
15678    }
15679
15680    public void finishReceiver(IBinder who, int resultCode, String resultData,
15681            Bundle resultExtras, boolean resultAbort) {
15682        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15683
15684        // Refuse possible leaked file descriptors
15685        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15686            throw new IllegalArgumentException("File descriptors passed in Bundle");
15687        }
15688
15689        final long origId = Binder.clearCallingIdentity();
15690        try {
15691            boolean doNext = false;
15692            BroadcastRecord r;
15693
15694            synchronized(this) {
15695                r = broadcastRecordForReceiverLocked(who);
15696                if (r != null) {
15697                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15698                        resultData, resultExtras, resultAbort, true);
15699                }
15700            }
15701
15702            if (doNext) {
15703                r.queue.processNextBroadcast(false);
15704            }
15705            trimApplications();
15706        } finally {
15707            Binder.restoreCallingIdentity(origId);
15708        }
15709    }
15710
15711    // =========================================================
15712    // INSTRUMENTATION
15713    // =========================================================
15714
15715    public boolean startInstrumentation(ComponentName className,
15716            String profileFile, int flags, Bundle arguments,
15717            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15718            int userId, String abiOverride) {
15719        enforceNotIsolatedCaller("startInstrumentation");
15720        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15721                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15722        // Refuse possible leaked file descriptors
15723        if (arguments != null && arguments.hasFileDescriptors()) {
15724            throw new IllegalArgumentException("File descriptors passed in Bundle");
15725        }
15726
15727        synchronized(this) {
15728            InstrumentationInfo ii = null;
15729            ApplicationInfo ai = null;
15730            try {
15731                ii = mContext.getPackageManager().getInstrumentationInfo(
15732                    className, STOCK_PM_FLAGS);
15733                ai = AppGlobals.getPackageManager().getApplicationInfo(
15734                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15735            } catch (PackageManager.NameNotFoundException e) {
15736            } catch (RemoteException e) {
15737            }
15738            if (ii == null) {
15739                reportStartInstrumentationFailure(watcher, className,
15740                        "Unable to find instrumentation info for: " + className);
15741                return false;
15742            }
15743            if (ai == null) {
15744                reportStartInstrumentationFailure(watcher, className,
15745                        "Unable to find instrumentation target package: " + ii.targetPackage);
15746                return false;
15747            }
15748
15749            int match = mContext.getPackageManager().checkSignatures(
15750                    ii.targetPackage, ii.packageName);
15751            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15752                String msg = "Permission Denial: starting instrumentation "
15753                        + className + " from pid="
15754                        + Binder.getCallingPid()
15755                        + ", uid=" + Binder.getCallingPid()
15756                        + " not allowed because package " + ii.packageName
15757                        + " does not have a signature matching the target "
15758                        + ii.targetPackage;
15759                reportStartInstrumentationFailure(watcher, className, msg);
15760                throw new SecurityException(msg);
15761            }
15762
15763            final long origId = Binder.clearCallingIdentity();
15764            // Instrumentation can kill and relaunch even persistent processes
15765            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15766                    "start instr");
15767            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15768            app.instrumentationClass = className;
15769            app.instrumentationInfo = ai;
15770            app.instrumentationProfileFile = profileFile;
15771            app.instrumentationArguments = arguments;
15772            app.instrumentationWatcher = watcher;
15773            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15774            app.instrumentationResultClass = className;
15775            Binder.restoreCallingIdentity(origId);
15776        }
15777
15778        return true;
15779    }
15780
15781    /**
15782     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15783     * error to the logs, but if somebody is watching, send the report there too.  This enables
15784     * the "am" command to report errors with more information.
15785     *
15786     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15787     * @param cn The component name of the instrumentation.
15788     * @param report The error report.
15789     */
15790    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15791            ComponentName cn, String report) {
15792        Slog.w(TAG, report);
15793        try {
15794            if (watcher != null) {
15795                Bundle results = new Bundle();
15796                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15797                results.putString("Error", report);
15798                watcher.instrumentationStatus(cn, -1, results);
15799            }
15800        } catch (RemoteException e) {
15801            Slog.w(TAG, e);
15802        }
15803    }
15804
15805    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15806        if (app.instrumentationWatcher != null) {
15807            try {
15808                // NOTE:  IInstrumentationWatcher *must* be oneway here
15809                app.instrumentationWatcher.instrumentationFinished(
15810                    app.instrumentationClass,
15811                    resultCode,
15812                    results);
15813            } catch (RemoteException e) {
15814            }
15815        }
15816        if (app.instrumentationUiAutomationConnection != null) {
15817            try {
15818                app.instrumentationUiAutomationConnection.shutdown();
15819            } catch (RemoteException re) {
15820                /* ignore */
15821            }
15822            // Only a UiAutomation can set this flag and now that
15823            // it is finished we make sure it is reset to its default.
15824            mUserIsMonkey = false;
15825        }
15826        app.instrumentationWatcher = null;
15827        app.instrumentationUiAutomationConnection = null;
15828        app.instrumentationClass = null;
15829        app.instrumentationInfo = null;
15830        app.instrumentationProfileFile = null;
15831        app.instrumentationArguments = null;
15832
15833        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15834                "finished inst");
15835    }
15836
15837    public void finishInstrumentation(IApplicationThread target,
15838            int resultCode, Bundle results) {
15839        int userId = UserHandle.getCallingUserId();
15840        // Refuse possible leaked file descriptors
15841        if (results != null && results.hasFileDescriptors()) {
15842            throw new IllegalArgumentException("File descriptors passed in Intent");
15843        }
15844
15845        synchronized(this) {
15846            ProcessRecord app = getRecordForAppLocked(target);
15847            if (app == null) {
15848                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15849                return;
15850            }
15851            final long origId = Binder.clearCallingIdentity();
15852            finishInstrumentationLocked(app, resultCode, results);
15853            Binder.restoreCallingIdentity(origId);
15854        }
15855    }
15856
15857    // =========================================================
15858    // CONFIGURATION
15859    // =========================================================
15860
15861    public ConfigurationInfo getDeviceConfigurationInfo() {
15862        ConfigurationInfo config = new ConfigurationInfo();
15863        synchronized (this) {
15864            config.reqTouchScreen = mConfiguration.touchscreen;
15865            config.reqKeyboardType = mConfiguration.keyboard;
15866            config.reqNavigation = mConfiguration.navigation;
15867            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15868                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15869                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15870            }
15871            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15872                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15873                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15874            }
15875            config.reqGlEsVersion = GL_ES_VERSION;
15876        }
15877        return config;
15878    }
15879
15880    ActivityStack getFocusedStack() {
15881        return mStackSupervisor.getFocusedStack();
15882    }
15883
15884    public Configuration getConfiguration() {
15885        Configuration ci;
15886        synchronized(this) {
15887            ci = new Configuration(mConfiguration);
15888        }
15889        return ci;
15890    }
15891
15892    public void updatePersistentConfiguration(Configuration values) {
15893        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15894                "updateConfiguration()");
15895        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15896                "updateConfiguration()");
15897        if (values == null) {
15898            throw new NullPointerException("Configuration must not be null");
15899        }
15900
15901        synchronized(this) {
15902            final long origId = Binder.clearCallingIdentity();
15903            updateConfigurationLocked(values, null, true, false);
15904            Binder.restoreCallingIdentity(origId);
15905        }
15906    }
15907
15908    public void updateConfiguration(Configuration values) {
15909        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15910                "updateConfiguration()");
15911
15912        synchronized(this) {
15913            if (values == null && mWindowManager != null) {
15914                // sentinel: fetch the current configuration from the window manager
15915                values = mWindowManager.computeNewConfiguration();
15916            }
15917
15918            if (mWindowManager != null) {
15919                mProcessList.applyDisplaySize(mWindowManager);
15920            }
15921
15922            final long origId = Binder.clearCallingIdentity();
15923            if (values != null) {
15924                Settings.System.clearConfiguration(values);
15925            }
15926            updateConfigurationLocked(values, null, false, false);
15927            Binder.restoreCallingIdentity(origId);
15928        }
15929    }
15930
15931    /**
15932     * Do either or both things: (1) change the current configuration, and (2)
15933     * make sure the given activity is running with the (now) current
15934     * configuration.  Returns true if the activity has been left running, or
15935     * false if <var>starting</var> is being destroyed to match the new
15936     * configuration.
15937     * @param persistent TODO
15938     */
15939    boolean updateConfigurationLocked(Configuration values,
15940            ActivityRecord starting, boolean persistent, boolean initLocale) {
15941        int changes = 0;
15942
15943        if (values != null) {
15944            Configuration newConfig = new Configuration(mConfiguration);
15945            changes = newConfig.updateFrom(values);
15946            if (changes != 0) {
15947                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15948                    Slog.i(TAG, "Updating configuration to: " + values);
15949                }
15950
15951                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15952
15953                if (values.locale != null && !initLocale) {
15954                    saveLocaleLocked(values.locale,
15955                                     !values.locale.equals(mConfiguration.locale),
15956                                     values.userSetLocale);
15957                }
15958
15959                mConfigurationSeq++;
15960                if (mConfigurationSeq <= 0) {
15961                    mConfigurationSeq = 1;
15962                }
15963                newConfig.seq = mConfigurationSeq;
15964                mConfiguration = newConfig;
15965                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15966                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15967                //mUsageStatsService.noteStartConfig(newConfig);
15968
15969                final Configuration configCopy = new Configuration(mConfiguration);
15970
15971                // TODO: If our config changes, should we auto dismiss any currently
15972                // showing dialogs?
15973                mShowDialogs = shouldShowDialogs(newConfig);
15974
15975                AttributeCache ac = AttributeCache.instance();
15976                if (ac != null) {
15977                    ac.updateConfiguration(configCopy);
15978                }
15979
15980                // Make sure all resources in our process are updated
15981                // right now, so that anyone who is going to retrieve
15982                // resource values after we return will be sure to get
15983                // the new ones.  This is especially important during
15984                // boot, where the first config change needs to guarantee
15985                // all resources have that config before following boot
15986                // code is executed.
15987                mSystemThread.applyConfigurationToResources(configCopy);
15988
15989                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15990                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15991                    msg.obj = new Configuration(configCopy);
15992                    mHandler.sendMessage(msg);
15993                }
15994
15995                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15996                    ProcessRecord app = mLruProcesses.get(i);
15997                    try {
15998                        if (app.thread != null) {
15999                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16000                                    + app.processName + " new config " + mConfiguration);
16001                            app.thread.scheduleConfigurationChanged(configCopy);
16002                        }
16003                    } catch (Exception e) {
16004                    }
16005                }
16006                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16007                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16008                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16009                        | Intent.FLAG_RECEIVER_FOREGROUND);
16010                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16011                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16012                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16013                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16014                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16015                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16016                    broadcastIntentLocked(null, null, intent,
16017                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16018                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16019                }
16020            }
16021        }
16022
16023        boolean kept = true;
16024        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16025        // mainStack is null during startup.
16026        if (mainStack != null) {
16027            if (changes != 0 && starting == null) {
16028                // If the configuration changed, and the caller is not already
16029                // in the process of starting an activity, then find the top
16030                // activity to check if its configuration needs to change.
16031                starting = mainStack.topRunningActivityLocked(null);
16032            }
16033
16034            if (starting != null) {
16035                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16036                // And we need to make sure at this point that all other activities
16037                // are made visible with the correct configuration.
16038                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16039            }
16040        }
16041
16042        if (values != null && mWindowManager != null) {
16043            mWindowManager.setNewConfiguration(mConfiguration);
16044        }
16045
16046        return kept;
16047    }
16048
16049    /**
16050     * Decide based on the configuration whether we should shouw the ANR,
16051     * crash, etc dialogs.  The idea is that if there is no affordnace to
16052     * press the on-screen buttons, we shouldn't show the dialog.
16053     *
16054     * A thought: SystemUI might also want to get told about this, the Power
16055     * dialog / global actions also might want different behaviors.
16056     */
16057    private static final boolean shouldShowDialogs(Configuration config) {
16058        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16059                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16060    }
16061
16062    /**
16063     * Save the locale.  You must be inside a synchronized (this) block.
16064     */
16065    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16066        if(isDiff) {
16067            SystemProperties.set("user.language", l.getLanguage());
16068            SystemProperties.set("user.region", l.getCountry());
16069        }
16070
16071        if(isPersist) {
16072            SystemProperties.set("persist.sys.language", l.getLanguage());
16073            SystemProperties.set("persist.sys.country", l.getCountry());
16074            SystemProperties.set("persist.sys.localevar", l.getVariant());
16075        }
16076    }
16077
16078    @Override
16079    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16080        synchronized (this) {
16081            ActivityRecord srec = ActivityRecord.forToken(token);
16082            if (srec.task != null && srec.task.stack != null) {
16083                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16084            }
16085        }
16086        return false;
16087    }
16088
16089    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16090            Intent resultData) {
16091
16092        synchronized (this) {
16093            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16094            if (stack != null) {
16095                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16096            }
16097            return false;
16098        }
16099    }
16100
16101    public int getLaunchedFromUid(IBinder activityToken) {
16102        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16103        if (srec == null) {
16104            return -1;
16105        }
16106        return srec.launchedFromUid;
16107    }
16108
16109    public String getLaunchedFromPackage(IBinder activityToken) {
16110        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16111        if (srec == null) {
16112            return null;
16113        }
16114        return srec.launchedFromPackage;
16115    }
16116
16117    // =========================================================
16118    // LIFETIME MANAGEMENT
16119    // =========================================================
16120
16121    // Returns which broadcast queue the app is the current [or imminent] receiver
16122    // on, or 'null' if the app is not an active broadcast recipient.
16123    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16124        BroadcastRecord r = app.curReceiver;
16125        if (r != null) {
16126            return r.queue;
16127        }
16128
16129        // It's not the current receiver, but it might be starting up to become one
16130        synchronized (this) {
16131            for (BroadcastQueue queue : mBroadcastQueues) {
16132                r = queue.mPendingBroadcast;
16133                if (r != null && r.curApp == app) {
16134                    // found it; report which queue it's in
16135                    return queue;
16136                }
16137            }
16138        }
16139
16140        return null;
16141    }
16142
16143    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16144            boolean doingAll, long now) {
16145        if (mAdjSeq == app.adjSeq) {
16146            // This adjustment has already been computed.
16147            return app.curRawAdj;
16148        }
16149
16150        if (app.thread == null) {
16151            app.adjSeq = mAdjSeq;
16152            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16153            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16154            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16155        }
16156
16157        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16158        app.adjSource = null;
16159        app.adjTarget = null;
16160        app.empty = false;
16161        app.cached = false;
16162
16163        final int activitiesSize = app.activities.size();
16164
16165        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16166            // The max adjustment doesn't allow this app to be anything
16167            // below foreground, so it is not worth doing work for it.
16168            app.adjType = "fixed";
16169            app.adjSeq = mAdjSeq;
16170            app.curRawAdj = app.maxAdj;
16171            app.foregroundActivities = false;
16172            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16173            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16174            // System processes can do UI, and when they do we want to have
16175            // them trim their memory after the user leaves the UI.  To
16176            // facilitate this, here we need to determine whether or not it
16177            // is currently showing UI.
16178            app.systemNoUi = true;
16179            if (app == TOP_APP) {
16180                app.systemNoUi = false;
16181            } else if (activitiesSize > 0) {
16182                for (int j = 0; j < activitiesSize; j++) {
16183                    final ActivityRecord r = app.activities.get(j);
16184                    if (r.visible) {
16185                        app.systemNoUi = false;
16186                    }
16187                }
16188            }
16189            if (!app.systemNoUi) {
16190                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16191            }
16192            return (app.curAdj=app.maxAdj);
16193        }
16194
16195        app.systemNoUi = false;
16196
16197        // Determine the importance of the process, starting with most
16198        // important to least, and assign an appropriate OOM adjustment.
16199        int adj;
16200        int schedGroup;
16201        int procState;
16202        boolean foregroundActivities = false;
16203        BroadcastQueue queue;
16204        if (app == TOP_APP) {
16205            // The last app on the list is the foreground app.
16206            adj = ProcessList.FOREGROUND_APP_ADJ;
16207            schedGroup = Process.THREAD_GROUP_DEFAULT;
16208            app.adjType = "top-activity";
16209            foregroundActivities = true;
16210            procState = ActivityManager.PROCESS_STATE_TOP;
16211        } else if (app.instrumentationClass != null) {
16212            // Don't want to kill running instrumentation.
16213            adj = ProcessList.FOREGROUND_APP_ADJ;
16214            schedGroup = Process.THREAD_GROUP_DEFAULT;
16215            app.adjType = "instrumentation";
16216            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16217        } else if ((queue = isReceivingBroadcast(app)) != null) {
16218            // An app that is currently receiving a broadcast also
16219            // counts as being in the foreground for OOM killer purposes.
16220            // It's placed in a sched group based on the nature of the
16221            // broadcast as reflected by which queue it's active in.
16222            adj = ProcessList.FOREGROUND_APP_ADJ;
16223            schedGroup = (queue == mFgBroadcastQueue)
16224                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16225            app.adjType = "broadcast";
16226            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16227        } else if (app.executingServices.size() > 0) {
16228            // An app that is currently executing a service callback also
16229            // counts as being in the foreground.
16230            adj = ProcessList.FOREGROUND_APP_ADJ;
16231            schedGroup = app.execServicesFg ?
16232                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16233            app.adjType = "exec-service";
16234            procState = ActivityManager.PROCESS_STATE_SERVICE;
16235            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16236        } else {
16237            // As far as we know the process is empty.  We may change our mind later.
16238            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16239            // At this point we don't actually know the adjustment.  Use the cached adj
16240            // value that the caller wants us to.
16241            adj = cachedAdj;
16242            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16243            app.cached = true;
16244            app.empty = true;
16245            app.adjType = "cch-empty";
16246        }
16247
16248        // Examine all activities if not already foreground.
16249        if (!foregroundActivities && activitiesSize > 0) {
16250            for (int j = 0; j < activitiesSize; j++) {
16251                final ActivityRecord r = app.activities.get(j);
16252                if (r.app != app) {
16253                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16254                            + app + "?!?");
16255                    continue;
16256                }
16257                if (r.visible) {
16258                    // App has a visible activity; only upgrade adjustment.
16259                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16260                        adj = ProcessList.VISIBLE_APP_ADJ;
16261                        app.adjType = "visible";
16262                    }
16263                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16264                        procState = ActivityManager.PROCESS_STATE_TOP;
16265                    }
16266                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16267                    app.cached = false;
16268                    app.empty = false;
16269                    foregroundActivities = true;
16270                    break;
16271                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16272                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16273                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16274                        app.adjType = "pausing";
16275                    }
16276                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16277                        procState = ActivityManager.PROCESS_STATE_TOP;
16278                    }
16279                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16280                    app.cached = false;
16281                    app.empty = false;
16282                    foregroundActivities = true;
16283                } else if (r.state == ActivityState.STOPPING) {
16284                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16285                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16286                        app.adjType = "stopping";
16287                    }
16288                    // For the process state, we will at this point consider the
16289                    // process to be cached.  It will be cached either as an activity
16290                    // or empty depending on whether the activity is finishing.  We do
16291                    // this so that we can treat the process as cached for purposes of
16292                    // memory trimming (determing current memory level, trim command to
16293                    // send to process) since there can be an arbitrary number of stopping
16294                    // processes and they should soon all go into the cached state.
16295                    if (!r.finishing) {
16296                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16297                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16298                        }
16299                    }
16300                    app.cached = false;
16301                    app.empty = false;
16302                    foregroundActivities = true;
16303                } else {
16304                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16305                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16306                        app.adjType = "cch-act";
16307                    }
16308                }
16309            }
16310        }
16311
16312        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16313            if (app.foregroundServices) {
16314                // The user is aware of this app, so make it visible.
16315                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16316                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16317                app.cached = false;
16318                app.adjType = "fg-service";
16319                schedGroup = Process.THREAD_GROUP_DEFAULT;
16320            } else if (app.forcingToForeground != null) {
16321                // The user is aware of this app, so make it visible.
16322                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16323                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16324                app.cached = false;
16325                app.adjType = "force-fg";
16326                app.adjSource = app.forcingToForeground;
16327                schedGroup = Process.THREAD_GROUP_DEFAULT;
16328            }
16329        }
16330
16331        if (app == mHeavyWeightProcess) {
16332            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16333                // We don't want to kill the current heavy-weight process.
16334                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16335                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16336                app.cached = false;
16337                app.adjType = "heavy";
16338            }
16339            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16340                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16341            }
16342        }
16343
16344        if (app == mHomeProcess) {
16345            if (adj > ProcessList.HOME_APP_ADJ) {
16346                // This process is hosting what we currently consider to be the
16347                // home app, so we don't want to let it go into the background.
16348                adj = ProcessList.HOME_APP_ADJ;
16349                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16350                app.cached = false;
16351                app.adjType = "home";
16352            }
16353            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16354                procState = ActivityManager.PROCESS_STATE_HOME;
16355            }
16356        }
16357
16358        if (app == mPreviousProcess && app.activities.size() > 0) {
16359            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16360                // This was the previous process that showed UI to the user.
16361                // We want to try to keep it around more aggressively, to give
16362                // a good experience around switching between two apps.
16363                adj = ProcessList.PREVIOUS_APP_ADJ;
16364                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16365                app.cached = false;
16366                app.adjType = "previous";
16367            }
16368            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16369                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16370            }
16371        }
16372
16373        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16374                + " reason=" + app.adjType);
16375
16376        // By default, we use the computed adjustment.  It may be changed if
16377        // there are applications dependent on our services or providers, but
16378        // this gives us a baseline and makes sure we don't get into an
16379        // infinite recursion.
16380        app.adjSeq = mAdjSeq;
16381        app.curRawAdj = adj;
16382        app.hasStartedServices = false;
16383
16384        if (mBackupTarget != null && app == mBackupTarget.app) {
16385            // If possible we want to avoid killing apps while they're being backed up
16386            if (adj > ProcessList.BACKUP_APP_ADJ) {
16387                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16388                adj = ProcessList.BACKUP_APP_ADJ;
16389                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16390                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16391                }
16392                app.adjType = "backup";
16393                app.cached = false;
16394            }
16395            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16396                procState = ActivityManager.PROCESS_STATE_BACKUP;
16397            }
16398        }
16399
16400        boolean mayBeTop = false;
16401
16402        for (int is = app.services.size()-1;
16403                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16404                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16405                        || procState > ActivityManager.PROCESS_STATE_TOP);
16406                is--) {
16407            ServiceRecord s = app.services.valueAt(is);
16408            if (s.startRequested) {
16409                app.hasStartedServices = true;
16410                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16411                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16412                }
16413                if (app.hasShownUi && app != mHomeProcess) {
16414                    // If this process has shown some UI, let it immediately
16415                    // go to the LRU list because it may be pretty heavy with
16416                    // UI stuff.  We'll tag it with a label just to help
16417                    // debug and understand what is going on.
16418                    if (adj > ProcessList.SERVICE_ADJ) {
16419                        app.adjType = "cch-started-ui-services";
16420                    }
16421                } else {
16422                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16423                        // This service has seen some activity within
16424                        // recent memory, so we will keep its process ahead
16425                        // of the background processes.
16426                        if (adj > ProcessList.SERVICE_ADJ) {
16427                            adj = ProcessList.SERVICE_ADJ;
16428                            app.adjType = "started-services";
16429                            app.cached = false;
16430                        }
16431                    }
16432                    // If we have let the service slide into the background
16433                    // state, still have some text describing what it is doing
16434                    // even though the service no longer has an impact.
16435                    if (adj > ProcessList.SERVICE_ADJ) {
16436                        app.adjType = "cch-started-services";
16437                    }
16438                }
16439            }
16440            for (int conni = s.connections.size()-1;
16441                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16442                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16443                            || procState > ActivityManager.PROCESS_STATE_TOP);
16444                    conni--) {
16445                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16446                for (int i = 0;
16447                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16448                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16449                                || procState > ActivityManager.PROCESS_STATE_TOP);
16450                        i++) {
16451                    // XXX should compute this based on the max of
16452                    // all connected clients.
16453                    ConnectionRecord cr = clist.get(i);
16454                    if (cr.binding.client == app) {
16455                        // Binding to ourself is not interesting.
16456                        continue;
16457                    }
16458                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16459                        ProcessRecord client = cr.binding.client;
16460                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16461                                TOP_APP, doingAll, now);
16462                        int clientProcState = client.curProcState;
16463                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16464                            // If the other app is cached for any reason, for purposes here
16465                            // we are going to consider it empty.  The specific cached state
16466                            // doesn't propagate except under certain conditions.
16467                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16468                        }
16469                        String adjType = null;
16470                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16471                            // Not doing bind OOM management, so treat
16472                            // this guy more like a started service.
16473                            if (app.hasShownUi && app != mHomeProcess) {
16474                                // If this process has shown some UI, let it immediately
16475                                // go to the LRU list because it may be pretty heavy with
16476                                // UI stuff.  We'll tag it with a label just to help
16477                                // debug and understand what is going on.
16478                                if (adj > clientAdj) {
16479                                    adjType = "cch-bound-ui-services";
16480                                }
16481                                app.cached = false;
16482                                clientAdj = adj;
16483                                clientProcState = procState;
16484                            } else {
16485                                if (now >= (s.lastActivity
16486                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16487                                    // This service has not seen activity within
16488                                    // recent memory, so allow it to drop to the
16489                                    // LRU list if there is no other reason to keep
16490                                    // it around.  We'll also tag it with a label just
16491                                    // to help debug and undertand what is going on.
16492                                    if (adj > clientAdj) {
16493                                        adjType = "cch-bound-services";
16494                                    }
16495                                    clientAdj = adj;
16496                                }
16497                            }
16498                        }
16499                        if (adj > clientAdj) {
16500                            // If this process has recently shown UI, and
16501                            // the process that is binding to it is less
16502                            // important than being visible, then we don't
16503                            // care about the binding as much as we care
16504                            // about letting this process get into the LRU
16505                            // list to be killed and restarted if needed for
16506                            // memory.
16507                            if (app.hasShownUi && app != mHomeProcess
16508                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16509                                adjType = "cch-bound-ui-services";
16510                            } else {
16511                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16512                                        |Context.BIND_IMPORTANT)) != 0) {
16513                                    adj = clientAdj;
16514                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16515                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16516                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16517                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16518                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16519                                    adj = clientAdj;
16520                                } else {
16521                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16522                                        adj = ProcessList.VISIBLE_APP_ADJ;
16523                                    }
16524                                }
16525                                if (!client.cached) {
16526                                    app.cached = false;
16527                                }
16528                                adjType = "service";
16529                            }
16530                        }
16531                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16532                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16533                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16534                            }
16535                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16536                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16537                                    // Special handling of clients who are in the top state.
16538                                    // We *may* want to consider this process to be in the
16539                                    // top state as well, but only if there is not another
16540                                    // reason for it to be running.  Being on the top is a
16541                                    // special state, meaning you are specifically running
16542                                    // for the current top app.  If the process is already
16543                                    // running in the background for some other reason, it
16544                                    // is more important to continue considering it to be
16545                                    // in the background state.
16546                                    mayBeTop = true;
16547                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16548                                } else {
16549                                    // Special handling for above-top states (persistent
16550                                    // processes).  These should not bring the current process
16551                                    // into the top state, since they are not on top.  Instead
16552                                    // give them the best state after that.
16553                                    clientProcState =
16554                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16555                                }
16556                            }
16557                        } else {
16558                            if (clientProcState <
16559                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16560                                clientProcState =
16561                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16562                            }
16563                        }
16564                        if (procState > clientProcState) {
16565                            procState = clientProcState;
16566                        }
16567                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16568                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16569                            app.pendingUiClean = true;
16570                        }
16571                        if (adjType != null) {
16572                            app.adjType = adjType;
16573                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16574                                    .REASON_SERVICE_IN_USE;
16575                            app.adjSource = cr.binding.client;
16576                            app.adjSourceProcState = clientProcState;
16577                            app.adjTarget = s.name;
16578                        }
16579                    }
16580                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16581                        app.treatLikeActivity = true;
16582                    }
16583                    final ActivityRecord a = cr.activity;
16584                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16585                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16586                                (a.visible || a.state == ActivityState.RESUMED
16587                                 || a.state == ActivityState.PAUSING)) {
16588                            adj = ProcessList.FOREGROUND_APP_ADJ;
16589                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16590                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16591                            }
16592                            app.cached = false;
16593                            app.adjType = "service";
16594                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16595                                    .REASON_SERVICE_IN_USE;
16596                            app.adjSource = a;
16597                            app.adjSourceProcState = procState;
16598                            app.adjTarget = s.name;
16599                        }
16600                    }
16601                }
16602            }
16603        }
16604
16605        for (int provi = app.pubProviders.size()-1;
16606                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16607                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16608                        || procState > ActivityManager.PROCESS_STATE_TOP);
16609                provi--) {
16610            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16611            for (int i = cpr.connections.size()-1;
16612                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16613                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16614                            || procState > ActivityManager.PROCESS_STATE_TOP);
16615                    i--) {
16616                ContentProviderConnection conn = cpr.connections.get(i);
16617                ProcessRecord client = conn.client;
16618                if (client == app) {
16619                    // Being our own client is not interesting.
16620                    continue;
16621                }
16622                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16623                int clientProcState = client.curProcState;
16624                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16625                    // If the other app is cached for any reason, for purposes here
16626                    // we are going to consider it empty.
16627                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16628                }
16629                if (adj > clientAdj) {
16630                    if (app.hasShownUi && app != mHomeProcess
16631                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16632                        app.adjType = "cch-ui-provider";
16633                    } else {
16634                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16635                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16636                        app.adjType = "provider";
16637                    }
16638                    app.cached &= client.cached;
16639                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16640                            .REASON_PROVIDER_IN_USE;
16641                    app.adjSource = client;
16642                    app.adjSourceProcState = clientProcState;
16643                    app.adjTarget = cpr.name;
16644                }
16645                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16646                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16647                        // Special handling of clients who are in the top state.
16648                        // We *may* want to consider this process to be in the
16649                        // top state as well, but only if there is not another
16650                        // reason for it to be running.  Being on the top is a
16651                        // special state, meaning you are specifically running
16652                        // for the current top app.  If the process is already
16653                        // running in the background for some other reason, it
16654                        // is more important to continue considering it to be
16655                        // in the background state.
16656                        mayBeTop = true;
16657                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16658                    } else {
16659                        // Special handling for above-top states (persistent
16660                        // processes).  These should not bring the current process
16661                        // into the top state, since they are not on top.  Instead
16662                        // give them the best state after that.
16663                        clientProcState =
16664                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16665                    }
16666                }
16667                if (procState > clientProcState) {
16668                    procState = clientProcState;
16669                }
16670                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16671                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16672                }
16673            }
16674            // If the provider has external (non-framework) process
16675            // dependencies, ensure that its adjustment is at least
16676            // FOREGROUND_APP_ADJ.
16677            if (cpr.hasExternalProcessHandles()) {
16678                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16679                    adj = ProcessList.FOREGROUND_APP_ADJ;
16680                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16681                    app.cached = false;
16682                    app.adjType = "provider";
16683                    app.adjTarget = cpr.name;
16684                }
16685                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16686                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16687                }
16688            }
16689        }
16690
16691        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16692            // A client of one of our services or providers is in the top state.  We
16693            // *may* want to be in the top state, but not if we are already running in
16694            // the background for some other reason.  For the decision here, we are going
16695            // to pick out a few specific states that we want to remain in when a client
16696            // is top (states that tend to be longer-term) and otherwise allow it to go
16697            // to the top state.
16698            switch (procState) {
16699                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16700                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16701                case ActivityManager.PROCESS_STATE_SERVICE:
16702                    // These all are longer-term states, so pull them up to the top
16703                    // of the background states, but not all the way to the top state.
16704                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16705                    break;
16706                default:
16707                    // Otherwise, top is a better choice, so take it.
16708                    procState = ActivityManager.PROCESS_STATE_TOP;
16709                    break;
16710            }
16711        }
16712
16713        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16714            if (app.hasClientActivities) {
16715                // This is a cached process, but with client activities.  Mark it so.
16716                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16717                app.adjType = "cch-client-act";
16718            } else if (app.treatLikeActivity) {
16719                // This is a cached process, but somebody wants us to treat it like it has
16720                // an activity, okay!
16721                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16722                app.adjType = "cch-as-act";
16723            }
16724        }
16725
16726        if (adj == ProcessList.SERVICE_ADJ) {
16727            if (doingAll) {
16728                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16729                mNewNumServiceProcs++;
16730                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16731                if (!app.serviceb) {
16732                    // This service isn't far enough down on the LRU list to
16733                    // normally be a B service, but if we are low on RAM and it
16734                    // is large we want to force it down since we would prefer to
16735                    // keep launcher over it.
16736                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16737                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16738                        app.serviceHighRam = true;
16739                        app.serviceb = true;
16740                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16741                    } else {
16742                        mNewNumAServiceProcs++;
16743                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16744                    }
16745                } else {
16746                    app.serviceHighRam = false;
16747                }
16748            }
16749            if (app.serviceb) {
16750                adj = ProcessList.SERVICE_B_ADJ;
16751            }
16752        }
16753
16754        app.curRawAdj = adj;
16755
16756        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16757        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16758        if (adj > app.maxAdj) {
16759            adj = app.maxAdj;
16760            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16761                schedGroup = Process.THREAD_GROUP_DEFAULT;
16762            }
16763        }
16764
16765        // Do final modification to adj.  Everything we do between here and applying
16766        // the final setAdj must be done in this function, because we will also use
16767        // it when computing the final cached adj later.  Note that we don't need to
16768        // worry about this for max adj above, since max adj will always be used to
16769        // keep it out of the cached vaues.
16770        app.curAdj = app.modifyRawOomAdj(adj);
16771        app.curSchedGroup = schedGroup;
16772        app.curProcState = procState;
16773        app.foregroundActivities = foregroundActivities;
16774
16775        return app.curRawAdj;
16776    }
16777
16778    /**
16779     * Schedule PSS collection of a process.
16780     */
16781    void requestPssLocked(ProcessRecord proc, int procState) {
16782        if (mPendingPssProcesses.contains(proc)) {
16783            return;
16784        }
16785        if (mPendingPssProcesses.size() == 0) {
16786            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16787        }
16788        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16789        proc.pssProcState = procState;
16790        mPendingPssProcesses.add(proc);
16791    }
16792
16793    /**
16794     * Schedule PSS collection of all processes.
16795     */
16796    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16797        if (!always) {
16798            if (now < (mLastFullPssTime +
16799                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16800                return;
16801            }
16802        }
16803        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16804        mLastFullPssTime = now;
16805        mFullPssPending = true;
16806        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16807        mPendingPssProcesses.clear();
16808        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16809            ProcessRecord app = mLruProcesses.get(i);
16810            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16811                app.pssProcState = app.setProcState;
16812                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16813                        isSleeping(), now);
16814                mPendingPssProcesses.add(app);
16815            }
16816        }
16817        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16818    }
16819
16820    /**
16821     * Ask a given process to GC right now.
16822     */
16823    final void performAppGcLocked(ProcessRecord app) {
16824        try {
16825            app.lastRequestedGc = SystemClock.uptimeMillis();
16826            if (app.thread != null) {
16827                if (app.reportLowMemory) {
16828                    app.reportLowMemory = false;
16829                    app.thread.scheduleLowMemory();
16830                } else {
16831                    app.thread.processInBackground();
16832                }
16833            }
16834        } catch (Exception e) {
16835            // whatever.
16836        }
16837    }
16838
16839    /**
16840     * Returns true if things are idle enough to perform GCs.
16841     */
16842    private final boolean canGcNowLocked() {
16843        boolean processingBroadcasts = false;
16844        for (BroadcastQueue q : mBroadcastQueues) {
16845            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16846                processingBroadcasts = true;
16847            }
16848        }
16849        return !processingBroadcasts
16850                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16851    }
16852
16853    /**
16854     * Perform GCs on all processes that are waiting for it, but only
16855     * if things are idle.
16856     */
16857    final void performAppGcsLocked() {
16858        final int N = mProcessesToGc.size();
16859        if (N <= 0) {
16860            return;
16861        }
16862        if (canGcNowLocked()) {
16863            while (mProcessesToGc.size() > 0) {
16864                ProcessRecord proc = mProcessesToGc.remove(0);
16865                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16866                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16867                            <= SystemClock.uptimeMillis()) {
16868                        // To avoid spamming the system, we will GC processes one
16869                        // at a time, waiting a few seconds between each.
16870                        performAppGcLocked(proc);
16871                        scheduleAppGcsLocked();
16872                        return;
16873                    } else {
16874                        // It hasn't been long enough since we last GCed this
16875                        // process...  put it in the list to wait for its time.
16876                        addProcessToGcListLocked(proc);
16877                        break;
16878                    }
16879                }
16880            }
16881
16882            scheduleAppGcsLocked();
16883        }
16884    }
16885
16886    /**
16887     * If all looks good, perform GCs on all processes waiting for them.
16888     */
16889    final void performAppGcsIfAppropriateLocked() {
16890        if (canGcNowLocked()) {
16891            performAppGcsLocked();
16892            return;
16893        }
16894        // Still not idle, wait some more.
16895        scheduleAppGcsLocked();
16896    }
16897
16898    /**
16899     * Schedule the execution of all pending app GCs.
16900     */
16901    final void scheduleAppGcsLocked() {
16902        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16903
16904        if (mProcessesToGc.size() > 0) {
16905            // Schedule a GC for the time to the next process.
16906            ProcessRecord proc = mProcessesToGc.get(0);
16907            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16908
16909            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16910            long now = SystemClock.uptimeMillis();
16911            if (when < (now+GC_TIMEOUT)) {
16912                when = now + GC_TIMEOUT;
16913            }
16914            mHandler.sendMessageAtTime(msg, when);
16915        }
16916    }
16917
16918    /**
16919     * Add a process to the array of processes waiting to be GCed.  Keeps the
16920     * list in sorted order by the last GC time.  The process can't already be
16921     * on the list.
16922     */
16923    final void addProcessToGcListLocked(ProcessRecord proc) {
16924        boolean added = false;
16925        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16926            if (mProcessesToGc.get(i).lastRequestedGc <
16927                    proc.lastRequestedGc) {
16928                added = true;
16929                mProcessesToGc.add(i+1, proc);
16930                break;
16931            }
16932        }
16933        if (!added) {
16934            mProcessesToGc.add(0, proc);
16935        }
16936    }
16937
16938    /**
16939     * Set up to ask a process to GC itself.  This will either do it
16940     * immediately, or put it on the list of processes to gc the next
16941     * time things are idle.
16942     */
16943    final void scheduleAppGcLocked(ProcessRecord app) {
16944        long now = SystemClock.uptimeMillis();
16945        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16946            return;
16947        }
16948        if (!mProcessesToGc.contains(app)) {
16949            addProcessToGcListLocked(app);
16950            scheduleAppGcsLocked();
16951        }
16952    }
16953
16954    final void checkExcessivePowerUsageLocked(boolean doKills) {
16955        updateCpuStatsNow();
16956
16957        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16958        boolean doWakeKills = doKills;
16959        boolean doCpuKills = doKills;
16960        if (mLastPowerCheckRealtime == 0) {
16961            doWakeKills = false;
16962        }
16963        if (mLastPowerCheckUptime == 0) {
16964            doCpuKills = false;
16965        }
16966        if (stats.isScreenOn()) {
16967            doWakeKills = false;
16968        }
16969        final long curRealtime = SystemClock.elapsedRealtime();
16970        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16971        final long curUptime = SystemClock.uptimeMillis();
16972        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16973        mLastPowerCheckRealtime = curRealtime;
16974        mLastPowerCheckUptime = curUptime;
16975        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16976            doWakeKills = false;
16977        }
16978        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16979            doCpuKills = false;
16980        }
16981        int i = mLruProcesses.size();
16982        while (i > 0) {
16983            i--;
16984            ProcessRecord app = mLruProcesses.get(i);
16985            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16986                long wtime;
16987                synchronized (stats) {
16988                    wtime = stats.getProcessWakeTime(app.info.uid,
16989                            app.pid, curRealtime);
16990                }
16991                long wtimeUsed = wtime - app.lastWakeTime;
16992                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16993                if (DEBUG_POWER) {
16994                    StringBuilder sb = new StringBuilder(128);
16995                    sb.append("Wake for ");
16996                    app.toShortString(sb);
16997                    sb.append(": over ");
16998                    TimeUtils.formatDuration(realtimeSince, sb);
16999                    sb.append(" used ");
17000                    TimeUtils.formatDuration(wtimeUsed, sb);
17001                    sb.append(" (");
17002                    sb.append((wtimeUsed*100)/realtimeSince);
17003                    sb.append("%)");
17004                    Slog.i(TAG, sb.toString());
17005                    sb.setLength(0);
17006                    sb.append("CPU for ");
17007                    app.toShortString(sb);
17008                    sb.append(": over ");
17009                    TimeUtils.formatDuration(uptimeSince, sb);
17010                    sb.append(" used ");
17011                    TimeUtils.formatDuration(cputimeUsed, sb);
17012                    sb.append(" (");
17013                    sb.append((cputimeUsed*100)/uptimeSince);
17014                    sb.append("%)");
17015                    Slog.i(TAG, sb.toString());
17016                }
17017                // If a process has held a wake lock for more
17018                // than 50% of the time during this period,
17019                // that sounds bad.  Kill!
17020                if (doWakeKills && realtimeSince > 0
17021                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17022                    synchronized (stats) {
17023                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17024                                realtimeSince, wtimeUsed);
17025                    }
17026                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17027                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17028                } else if (doCpuKills && uptimeSince > 0
17029                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17030                    synchronized (stats) {
17031                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17032                                uptimeSince, cputimeUsed);
17033                    }
17034                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17035                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17036                } else {
17037                    app.lastWakeTime = wtime;
17038                    app.lastCpuTime = app.curCpuTime;
17039                }
17040            }
17041        }
17042    }
17043
17044    private final boolean applyOomAdjLocked(ProcessRecord app,
17045            ProcessRecord TOP_APP, boolean doingAll, long now) {
17046        boolean success = true;
17047
17048        if (app.curRawAdj != app.setRawAdj) {
17049            app.setRawAdj = app.curRawAdj;
17050        }
17051
17052        int changes = 0;
17053
17054        if (app.curAdj != app.setAdj) {
17055            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17056            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17057                TAG, "Set " + app.pid + " " + app.processName +
17058                " adj " + app.curAdj + ": " + app.adjType);
17059            app.setAdj = app.curAdj;
17060        }
17061
17062        if (app.setSchedGroup != app.curSchedGroup) {
17063            app.setSchedGroup = app.curSchedGroup;
17064            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17065                    "Setting process group of " + app.processName
17066                    + " to " + app.curSchedGroup);
17067            if (app.waitingToKill != null &&
17068                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17069                app.kill(app.waitingToKill, true);
17070                success = false;
17071            } else {
17072                if (true) {
17073                    long oldId = Binder.clearCallingIdentity();
17074                    try {
17075                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17076                    } catch (Exception e) {
17077                        Slog.w(TAG, "Failed setting process group of " + app.pid
17078                                + " to " + app.curSchedGroup);
17079                        e.printStackTrace();
17080                    } finally {
17081                        Binder.restoreCallingIdentity(oldId);
17082                    }
17083                } else {
17084                    if (app.thread != null) {
17085                        try {
17086                            app.thread.setSchedulingGroup(app.curSchedGroup);
17087                        } catch (RemoteException e) {
17088                        }
17089                    }
17090                }
17091                Process.setSwappiness(app.pid,
17092                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17093            }
17094        }
17095        if (app.repForegroundActivities != app.foregroundActivities) {
17096            app.repForegroundActivities = app.foregroundActivities;
17097            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17098        }
17099        if (app.repProcState != app.curProcState) {
17100            app.repProcState = app.curProcState;
17101            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17102            if (app.thread != null) {
17103                try {
17104                    if (false) {
17105                        //RuntimeException h = new RuntimeException("here");
17106                        Slog.i(TAG, "Sending new process state " + app.repProcState
17107                                + " to " + app /*, h*/);
17108                    }
17109                    app.thread.setProcessState(app.repProcState);
17110                } catch (RemoteException e) {
17111                }
17112            }
17113        }
17114        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17115                app.setProcState)) {
17116            app.lastStateTime = now;
17117            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17118                    isSleeping(), now);
17119            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17120                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17121                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17122                    + (app.nextPssTime-now) + ": " + app);
17123        } else {
17124            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17125                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17126                requestPssLocked(app, app.setProcState);
17127                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17128                        isSleeping(), now);
17129            } else if (false && DEBUG_PSS) {
17130                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17131            }
17132        }
17133        if (app.setProcState != app.curProcState) {
17134            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17135                    "Proc state change of " + app.processName
17136                    + " to " + app.curProcState);
17137            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17138            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17139            if (setImportant && !curImportant) {
17140                // This app is no longer something we consider important enough to allow to
17141                // use arbitrary amounts of battery power.  Note
17142                // its current wake lock time to later know to kill it if
17143                // it is not behaving well.
17144                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17145                synchronized (stats) {
17146                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17147                            app.pid, SystemClock.elapsedRealtime());
17148                }
17149                app.lastCpuTime = app.curCpuTime;
17150
17151            }
17152            app.setProcState = app.curProcState;
17153            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17154                app.notCachedSinceIdle = false;
17155            }
17156            if (!doingAll) {
17157                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17158            } else {
17159                app.procStateChanged = true;
17160            }
17161        }
17162
17163        if (changes != 0) {
17164            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17165            int i = mPendingProcessChanges.size()-1;
17166            ProcessChangeItem item = null;
17167            while (i >= 0) {
17168                item = mPendingProcessChanges.get(i);
17169                if (item.pid == app.pid) {
17170                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17171                    break;
17172                }
17173                i--;
17174            }
17175            if (i < 0) {
17176                // No existing item in pending changes; need a new one.
17177                final int NA = mAvailProcessChanges.size();
17178                if (NA > 0) {
17179                    item = mAvailProcessChanges.remove(NA-1);
17180                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17181                } else {
17182                    item = new ProcessChangeItem();
17183                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17184                }
17185                item.changes = 0;
17186                item.pid = app.pid;
17187                item.uid = app.info.uid;
17188                if (mPendingProcessChanges.size() == 0) {
17189                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17190                            "*** Enqueueing dispatch processes changed!");
17191                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17192                }
17193                mPendingProcessChanges.add(item);
17194            }
17195            item.changes |= changes;
17196            item.processState = app.repProcState;
17197            item.foregroundActivities = app.repForegroundActivities;
17198            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17199                    + Integer.toHexString(System.identityHashCode(item))
17200                    + " " + app.toShortString() + ": changes=" + item.changes
17201                    + " procState=" + item.processState
17202                    + " foreground=" + item.foregroundActivities
17203                    + " type=" + app.adjType + " source=" + app.adjSource
17204                    + " target=" + app.adjTarget);
17205        }
17206
17207        return success;
17208    }
17209
17210    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17211        if (proc.thread != null) {
17212            if (proc.baseProcessTracker != null) {
17213                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17214            }
17215            if (proc.repProcState >= 0) {
17216                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17217                        proc.repProcState);
17218            }
17219        }
17220    }
17221
17222    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17223            ProcessRecord TOP_APP, boolean doingAll, long now) {
17224        if (app.thread == null) {
17225            return false;
17226        }
17227
17228        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17229
17230        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17231    }
17232
17233    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17234            boolean oomAdj) {
17235        if (isForeground != proc.foregroundServices) {
17236            proc.foregroundServices = isForeground;
17237            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17238                    proc.info.uid);
17239            if (isForeground) {
17240                if (curProcs == null) {
17241                    curProcs = new ArrayList<ProcessRecord>();
17242                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17243                }
17244                if (!curProcs.contains(proc)) {
17245                    curProcs.add(proc);
17246                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17247                            proc.info.packageName, proc.info.uid);
17248                }
17249            } else {
17250                if (curProcs != null) {
17251                    if (curProcs.remove(proc)) {
17252                        mBatteryStatsService.noteEvent(
17253                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17254                                proc.info.packageName, proc.info.uid);
17255                        if (curProcs.size() <= 0) {
17256                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17257                        }
17258                    }
17259                }
17260            }
17261            if (oomAdj) {
17262                updateOomAdjLocked();
17263            }
17264        }
17265    }
17266
17267    private final ActivityRecord resumedAppLocked() {
17268        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17269        String pkg;
17270        int uid;
17271        if (act != null) {
17272            pkg = act.packageName;
17273            uid = act.info.applicationInfo.uid;
17274        } else {
17275            pkg = null;
17276            uid = -1;
17277        }
17278        // Has the UID or resumed package name changed?
17279        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17280                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17281            if (mCurResumedPackage != null) {
17282                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17283                        mCurResumedPackage, mCurResumedUid);
17284            }
17285            mCurResumedPackage = pkg;
17286            mCurResumedUid = uid;
17287            if (mCurResumedPackage != null) {
17288                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17289                        mCurResumedPackage, mCurResumedUid);
17290            }
17291        }
17292        return act;
17293    }
17294
17295    final boolean updateOomAdjLocked(ProcessRecord app) {
17296        final ActivityRecord TOP_ACT = resumedAppLocked();
17297        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17298        final boolean wasCached = app.cached;
17299
17300        mAdjSeq++;
17301
17302        // This is the desired cached adjusment we want to tell it to use.
17303        // If our app is currently cached, we know it, and that is it.  Otherwise,
17304        // we don't know it yet, and it needs to now be cached we will then
17305        // need to do a complete oom adj.
17306        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17307                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17308        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17309                SystemClock.uptimeMillis());
17310        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17311            // Changed to/from cached state, so apps after it in the LRU
17312            // list may also be changed.
17313            updateOomAdjLocked();
17314        }
17315        return success;
17316    }
17317
17318    final void updateOomAdjLocked() {
17319        final ActivityRecord TOP_ACT = resumedAppLocked();
17320        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17321        final long now = SystemClock.uptimeMillis();
17322        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17323        final int N = mLruProcesses.size();
17324
17325        if (false) {
17326            RuntimeException e = new RuntimeException();
17327            e.fillInStackTrace();
17328            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17329        }
17330
17331        mAdjSeq++;
17332        mNewNumServiceProcs = 0;
17333        mNewNumAServiceProcs = 0;
17334
17335        final int emptyProcessLimit;
17336        final int cachedProcessLimit;
17337        if (mProcessLimit <= 0) {
17338            emptyProcessLimit = cachedProcessLimit = 0;
17339        } else if (mProcessLimit == 1) {
17340            emptyProcessLimit = 1;
17341            cachedProcessLimit = 0;
17342        } else {
17343            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17344            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17345        }
17346
17347        // Let's determine how many processes we have running vs.
17348        // how many slots we have for background processes; we may want
17349        // to put multiple processes in a slot of there are enough of
17350        // them.
17351        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17352                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17353        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17354        if (numEmptyProcs > cachedProcessLimit) {
17355            // If there are more empty processes than our limit on cached
17356            // processes, then use the cached process limit for the factor.
17357            // This ensures that the really old empty processes get pushed
17358            // down to the bottom, so if we are running low on memory we will
17359            // have a better chance at keeping around more cached processes
17360            // instead of a gazillion empty processes.
17361            numEmptyProcs = cachedProcessLimit;
17362        }
17363        int emptyFactor = numEmptyProcs/numSlots;
17364        if (emptyFactor < 1) emptyFactor = 1;
17365        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17366        if (cachedFactor < 1) cachedFactor = 1;
17367        int stepCached = 0;
17368        int stepEmpty = 0;
17369        int numCached = 0;
17370        int numEmpty = 0;
17371        int numTrimming = 0;
17372
17373        mNumNonCachedProcs = 0;
17374        mNumCachedHiddenProcs = 0;
17375
17376        // First update the OOM adjustment for each of the
17377        // application processes based on their current state.
17378        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17379        int nextCachedAdj = curCachedAdj+1;
17380        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17381        int nextEmptyAdj = curEmptyAdj+2;
17382        for (int i=N-1; i>=0; i--) {
17383            ProcessRecord app = mLruProcesses.get(i);
17384            if (!app.killedByAm && app.thread != null) {
17385                app.procStateChanged = false;
17386                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17387
17388                // If we haven't yet assigned the final cached adj
17389                // to the process, do that now.
17390                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17391                    switch (app.curProcState) {
17392                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17393                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17394                            // This process is a cached process holding activities...
17395                            // assign it the next cached value for that type, and then
17396                            // step that cached level.
17397                            app.curRawAdj = curCachedAdj;
17398                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17399                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17400                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17401                                    + ")");
17402                            if (curCachedAdj != nextCachedAdj) {
17403                                stepCached++;
17404                                if (stepCached >= cachedFactor) {
17405                                    stepCached = 0;
17406                                    curCachedAdj = nextCachedAdj;
17407                                    nextCachedAdj += 2;
17408                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17409                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17410                                    }
17411                                }
17412                            }
17413                            break;
17414                        default:
17415                            // For everything else, assign next empty cached process
17416                            // level and bump that up.  Note that this means that
17417                            // long-running services that have dropped down to the
17418                            // cached level will be treated as empty (since their process
17419                            // state is still as a service), which is what we want.
17420                            app.curRawAdj = curEmptyAdj;
17421                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17422                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17423                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17424                                    + ")");
17425                            if (curEmptyAdj != nextEmptyAdj) {
17426                                stepEmpty++;
17427                                if (stepEmpty >= emptyFactor) {
17428                                    stepEmpty = 0;
17429                                    curEmptyAdj = nextEmptyAdj;
17430                                    nextEmptyAdj += 2;
17431                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17432                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17433                                    }
17434                                }
17435                            }
17436                            break;
17437                    }
17438                }
17439
17440                applyOomAdjLocked(app, TOP_APP, true, now);
17441
17442                // Count the number of process types.
17443                switch (app.curProcState) {
17444                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17445                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17446                        mNumCachedHiddenProcs++;
17447                        numCached++;
17448                        if (numCached > cachedProcessLimit) {
17449                            app.kill("cached #" + numCached, true);
17450                        }
17451                        break;
17452                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17453                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17454                                && app.lastActivityTime < oldTime) {
17455                            app.kill("empty for "
17456                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17457                                    / 1000) + "s", true);
17458                        } else {
17459                            numEmpty++;
17460                            if (numEmpty > emptyProcessLimit) {
17461                                app.kill("empty #" + numEmpty, true);
17462                            }
17463                        }
17464                        break;
17465                    default:
17466                        mNumNonCachedProcs++;
17467                        break;
17468                }
17469
17470                if (app.isolated && app.services.size() <= 0) {
17471                    // If this is an isolated process, and there are no
17472                    // services running in it, then the process is no longer
17473                    // needed.  We agressively kill these because we can by
17474                    // definition not re-use the same process again, and it is
17475                    // good to avoid having whatever code was running in them
17476                    // left sitting around after no longer needed.
17477                    app.kill("isolated not needed", true);
17478                }
17479
17480                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17481                        && !app.killedByAm) {
17482                    numTrimming++;
17483                }
17484            }
17485        }
17486
17487        mNumServiceProcs = mNewNumServiceProcs;
17488
17489        // Now determine the memory trimming level of background processes.
17490        // Unfortunately we need to start at the back of the list to do this
17491        // properly.  We only do this if the number of background apps we
17492        // are managing to keep around is less than half the maximum we desire;
17493        // if we are keeping a good number around, we'll let them use whatever
17494        // memory they want.
17495        final int numCachedAndEmpty = numCached + numEmpty;
17496        int memFactor;
17497        if (numCached <= ProcessList.TRIM_CACHED_APPS
17498                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17499            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17500                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17501            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17502                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17503            } else {
17504                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17505            }
17506        } else {
17507            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17508        }
17509        // We always allow the memory level to go up (better).  We only allow it to go
17510        // down if we are in a state where that is allowed, *and* the total number of processes
17511        // has gone down since last time.
17512        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17513                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17514                + " last=" + mLastNumProcesses);
17515        if (memFactor > mLastMemoryLevel) {
17516            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17517                memFactor = mLastMemoryLevel;
17518                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17519            }
17520        }
17521        mLastMemoryLevel = memFactor;
17522        mLastNumProcesses = mLruProcesses.size();
17523        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17524        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17525        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17526            if (mLowRamStartTime == 0) {
17527                mLowRamStartTime = now;
17528            }
17529            int step = 0;
17530            int fgTrimLevel;
17531            switch (memFactor) {
17532                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17533                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17534                    break;
17535                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17536                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17537                    break;
17538                default:
17539                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17540                    break;
17541            }
17542            int factor = numTrimming/3;
17543            int minFactor = 2;
17544            if (mHomeProcess != null) minFactor++;
17545            if (mPreviousProcess != null) minFactor++;
17546            if (factor < minFactor) factor = minFactor;
17547            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17548            for (int i=N-1; i>=0; i--) {
17549                ProcessRecord app = mLruProcesses.get(i);
17550                if (allChanged || app.procStateChanged) {
17551                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17552                    app.procStateChanged = false;
17553                }
17554                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17555                        && !app.killedByAm) {
17556                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17557                        try {
17558                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17559                                    "Trimming memory of " + app.processName
17560                                    + " to " + curLevel);
17561                            app.thread.scheduleTrimMemory(curLevel);
17562                        } catch (RemoteException e) {
17563                        }
17564                        if (false) {
17565                            // For now we won't do this; our memory trimming seems
17566                            // to be good enough at this point that destroying
17567                            // activities causes more harm than good.
17568                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17569                                    && app != mHomeProcess && app != mPreviousProcess) {
17570                                // Need to do this on its own message because the stack may not
17571                                // be in a consistent state at this point.
17572                                // For these apps we will also finish their activities
17573                                // to help them free memory.
17574                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17575                            }
17576                        }
17577                    }
17578                    app.trimMemoryLevel = curLevel;
17579                    step++;
17580                    if (step >= factor) {
17581                        step = 0;
17582                        switch (curLevel) {
17583                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17584                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17585                                break;
17586                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17587                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17588                                break;
17589                        }
17590                    }
17591                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17592                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17593                            && app.thread != null) {
17594                        try {
17595                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17596                                    "Trimming memory of heavy-weight " + app.processName
17597                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17598                            app.thread.scheduleTrimMemory(
17599                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17600                        } catch (RemoteException e) {
17601                        }
17602                    }
17603                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17604                } else {
17605                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17606                            || app.systemNoUi) && app.pendingUiClean) {
17607                        // If this application is now in the background and it
17608                        // had done UI, then give it the special trim level to
17609                        // have it free UI resources.
17610                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17611                        if (app.trimMemoryLevel < level && app.thread != null) {
17612                            try {
17613                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17614                                        "Trimming memory of bg-ui " + app.processName
17615                                        + " to " + level);
17616                                app.thread.scheduleTrimMemory(level);
17617                            } catch (RemoteException e) {
17618                            }
17619                        }
17620                        app.pendingUiClean = false;
17621                    }
17622                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17623                        try {
17624                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17625                                    "Trimming memory of fg " + app.processName
17626                                    + " to " + fgTrimLevel);
17627                            app.thread.scheduleTrimMemory(fgTrimLevel);
17628                        } catch (RemoteException e) {
17629                        }
17630                    }
17631                    app.trimMemoryLevel = fgTrimLevel;
17632                }
17633            }
17634        } else {
17635            if (mLowRamStartTime != 0) {
17636                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17637                mLowRamStartTime = 0;
17638            }
17639            for (int i=N-1; i>=0; i--) {
17640                ProcessRecord app = mLruProcesses.get(i);
17641                if (allChanged || app.procStateChanged) {
17642                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17643                    app.procStateChanged = false;
17644                }
17645                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17646                        || app.systemNoUi) && app.pendingUiClean) {
17647                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17648                            && app.thread != null) {
17649                        try {
17650                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17651                                    "Trimming memory of ui hidden " + app.processName
17652                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17653                            app.thread.scheduleTrimMemory(
17654                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17655                        } catch (RemoteException e) {
17656                        }
17657                    }
17658                    app.pendingUiClean = false;
17659                }
17660                app.trimMemoryLevel = 0;
17661            }
17662        }
17663
17664        if (mAlwaysFinishActivities) {
17665            // Need to do this on its own message because the stack may not
17666            // be in a consistent state at this point.
17667            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17668        }
17669
17670        if (allChanged) {
17671            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17672        }
17673
17674        if (mProcessStats.shouldWriteNowLocked(now)) {
17675            mHandler.post(new Runnable() {
17676                @Override public void run() {
17677                    synchronized (ActivityManagerService.this) {
17678                        mProcessStats.writeStateAsyncLocked();
17679                    }
17680                }
17681            });
17682        }
17683
17684        if (DEBUG_OOM_ADJ) {
17685            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17686        }
17687    }
17688
17689    final void trimApplications() {
17690        synchronized (this) {
17691            int i;
17692
17693            // First remove any unused application processes whose package
17694            // has been removed.
17695            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17696                final ProcessRecord app = mRemovedProcesses.get(i);
17697                if (app.activities.size() == 0
17698                        && app.curReceiver == null && app.services.size() == 0) {
17699                    Slog.i(
17700                        TAG, "Exiting empty application process "
17701                        + app.processName + " ("
17702                        + (app.thread != null ? app.thread.asBinder() : null)
17703                        + ")\n");
17704                    if (app.pid > 0 && app.pid != MY_PID) {
17705                        app.kill("empty", false);
17706                    } else {
17707                        try {
17708                            app.thread.scheduleExit();
17709                        } catch (Exception e) {
17710                            // Ignore exceptions.
17711                        }
17712                    }
17713                    cleanUpApplicationRecordLocked(app, false, true, -1);
17714                    mRemovedProcesses.remove(i);
17715
17716                    if (app.persistent) {
17717                        addAppLocked(app.info, false, null /* ABI override */);
17718                    }
17719                }
17720            }
17721
17722            // Now update the oom adj for all processes.
17723            updateOomAdjLocked();
17724        }
17725    }
17726
17727    /** This method sends the specified signal to each of the persistent apps */
17728    public void signalPersistentProcesses(int sig) throws RemoteException {
17729        if (sig != Process.SIGNAL_USR1) {
17730            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17731        }
17732
17733        synchronized (this) {
17734            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17735                    != PackageManager.PERMISSION_GRANTED) {
17736                throw new SecurityException("Requires permission "
17737                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17738            }
17739
17740            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17741                ProcessRecord r = mLruProcesses.get(i);
17742                if (r.thread != null && r.persistent) {
17743                    Process.sendSignal(r.pid, sig);
17744                }
17745            }
17746        }
17747    }
17748
17749    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17750        if (proc == null || proc == mProfileProc) {
17751            proc = mProfileProc;
17752            profileType = mProfileType;
17753            clearProfilerLocked();
17754        }
17755        if (proc == null) {
17756            return;
17757        }
17758        try {
17759            proc.thread.profilerControl(false, null, profileType);
17760        } catch (RemoteException e) {
17761            throw new IllegalStateException("Process disappeared");
17762        }
17763    }
17764
17765    private void clearProfilerLocked() {
17766        if (mProfileFd != null) {
17767            try {
17768                mProfileFd.close();
17769            } catch (IOException e) {
17770            }
17771        }
17772        mProfileApp = null;
17773        mProfileProc = null;
17774        mProfileFile = null;
17775        mProfileType = 0;
17776        mAutoStopProfiler = false;
17777        mSamplingInterval = 0;
17778    }
17779
17780    public boolean profileControl(String process, int userId, boolean start,
17781            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17782
17783        try {
17784            synchronized (this) {
17785                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17786                // its own permission.
17787                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17788                        != PackageManager.PERMISSION_GRANTED) {
17789                    throw new SecurityException("Requires permission "
17790                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17791                }
17792
17793                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17794                    throw new IllegalArgumentException("null profile info or fd");
17795                }
17796
17797                ProcessRecord proc = null;
17798                if (process != null) {
17799                    proc = findProcessLocked(process, userId, "profileControl");
17800                }
17801
17802                if (start && (proc == null || proc.thread == null)) {
17803                    throw new IllegalArgumentException("Unknown process: " + process);
17804                }
17805
17806                if (start) {
17807                    stopProfilerLocked(null, 0);
17808                    setProfileApp(proc.info, proc.processName, profilerInfo);
17809                    mProfileProc = proc;
17810                    mProfileType = profileType;
17811                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17812                    try {
17813                        fd = fd.dup();
17814                    } catch (IOException e) {
17815                        fd = null;
17816                    }
17817                    profilerInfo.profileFd = fd;
17818                    proc.thread.profilerControl(start, profilerInfo, profileType);
17819                    fd = null;
17820                    mProfileFd = null;
17821                } else {
17822                    stopProfilerLocked(proc, profileType);
17823                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17824                        try {
17825                            profilerInfo.profileFd.close();
17826                        } catch (IOException e) {
17827                        }
17828                    }
17829                }
17830
17831                return true;
17832            }
17833        } catch (RemoteException e) {
17834            throw new IllegalStateException("Process disappeared");
17835        } finally {
17836            if (profilerInfo != null && profilerInfo.profileFd != null) {
17837                try {
17838                    profilerInfo.profileFd.close();
17839                } catch (IOException e) {
17840                }
17841            }
17842        }
17843    }
17844
17845    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17846        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17847                userId, true, ALLOW_FULL_ONLY, callName, null);
17848        ProcessRecord proc = null;
17849        try {
17850            int pid = Integer.parseInt(process);
17851            synchronized (mPidsSelfLocked) {
17852                proc = mPidsSelfLocked.get(pid);
17853            }
17854        } catch (NumberFormatException e) {
17855        }
17856
17857        if (proc == null) {
17858            ArrayMap<String, SparseArray<ProcessRecord>> all
17859                    = mProcessNames.getMap();
17860            SparseArray<ProcessRecord> procs = all.get(process);
17861            if (procs != null && procs.size() > 0) {
17862                proc = procs.valueAt(0);
17863                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17864                    for (int i=1; i<procs.size(); i++) {
17865                        ProcessRecord thisProc = procs.valueAt(i);
17866                        if (thisProc.userId == userId) {
17867                            proc = thisProc;
17868                            break;
17869                        }
17870                    }
17871                }
17872            }
17873        }
17874
17875        return proc;
17876    }
17877
17878    public boolean dumpHeap(String process, int userId, boolean managed,
17879            String path, ParcelFileDescriptor fd) throws RemoteException {
17880
17881        try {
17882            synchronized (this) {
17883                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17884                // its own permission (same as profileControl).
17885                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17886                        != PackageManager.PERMISSION_GRANTED) {
17887                    throw new SecurityException("Requires permission "
17888                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17889                }
17890
17891                if (fd == null) {
17892                    throw new IllegalArgumentException("null fd");
17893                }
17894
17895                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17896                if (proc == null || proc.thread == null) {
17897                    throw new IllegalArgumentException("Unknown process: " + process);
17898                }
17899
17900                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17901                if (!isDebuggable) {
17902                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17903                        throw new SecurityException("Process not debuggable: " + proc);
17904                    }
17905                }
17906
17907                proc.thread.dumpHeap(managed, path, fd);
17908                fd = null;
17909                return true;
17910            }
17911        } catch (RemoteException e) {
17912            throw new IllegalStateException("Process disappeared");
17913        } finally {
17914            if (fd != null) {
17915                try {
17916                    fd.close();
17917                } catch (IOException e) {
17918                }
17919            }
17920        }
17921    }
17922
17923    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17924    public void monitor() {
17925        synchronized (this) { }
17926    }
17927
17928    void onCoreSettingsChange(Bundle settings) {
17929        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17930            ProcessRecord processRecord = mLruProcesses.get(i);
17931            try {
17932                if (processRecord.thread != null) {
17933                    processRecord.thread.setCoreSettings(settings);
17934                }
17935            } catch (RemoteException re) {
17936                /* ignore */
17937            }
17938        }
17939    }
17940
17941    // Multi-user methods
17942
17943    /**
17944     * Start user, if its not already running, but don't bring it to foreground.
17945     */
17946    @Override
17947    public boolean startUserInBackground(final int userId) {
17948        return startUser(userId, /* foreground */ false);
17949    }
17950
17951    /**
17952     * Start user, if its not already running, and bring it to foreground.
17953     */
17954    boolean startUserInForeground(final int userId, Dialog dlg) {
17955        boolean result = startUser(userId, /* foreground */ true);
17956        dlg.dismiss();
17957        return result;
17958    }
17959
17960    /**
17961     * Refreshes the list of users related to the current user when either a
17962     * user switch happens or when a new related user is started in the
17963     * background.
17964     */
17965    private void updateCurrentProfileIdsLocked() {
17966        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17967                mCurrentUserId, false /* enabledOnly */);
17968        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17969        for (int i = 0; i < currentProfileIds.length; i++) {
17970            currentProfileIds[i] = profiles.get(i).id;
17971        }
17972        mCurrentProfileIds = currentProfileIds;
17973
17974        synchronized (mUserProfileGroupIdsSelfLocked) {
17975            mUserProfileGroupIdsSelfLocked.clear();
17976            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17977            for (int i = 0; i < users.size(); i++) {
17978                UserInfo user = users.get(i);
17979                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17980                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17981                }
17982            }
17983        }
17984    }
17985
17986    private Set getProfileIdsLocked(int userId) {
17987        Set userIds = new HashSet<Integer>();
17988        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17989                userId, false /* enabledOnly */);
17990        for (UserInfo user : profiles) {
17991            userIds.add(Integer.valueOf(user.id));
17992        }
17993        return userIds;
17994    }
17995
17996    @Override
17997    public boolean switchUser(final int userId) {
17998        String userName;
17999        synchronized (this) {
18000            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18001            if (userInfo == null) {
18002                Slog.w(TAG, "No user info for user #" + userId);
18003                return false;
18004            }
18005            if (userInfo.isManagedProfile()) {
18006                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18007                return false;
18008            }
18009            userName = userInfo.name;
18010            mTargetUserId = userId;
18011        }
18012        mHandler.removeMessages(START_USER_SWITCH_MSG);
18013        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18014        return true;
18015    }
18016
18017    private void showUserSwitchDialog(int userId, String userName) {
18018        // The dialog will show and then initiate the user switch by calling startUserInForeground
18019        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18020                true /* above system */);
18021        d.show();
18022    }
18023
18024    private boolean startUser(final int userId, final boolean foreground) {
18025        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18026                != PackageManager.PERMISSION_GRANTED) {
18027            String msg = "Permission Denial: switchUser() from pid="
18028                    + Binder.getCallingPid()
18029                    + ", uid=" + Binder.getCallingUid()
18030                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18031            Slog.w(TAG, msg);
18032            throw new SecurityException(msg);
18033        }
18034
18035        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18036
18037        final long ident = Binder.clearCallingIdentity();
18038        try {
18039            synchronized (this) {
18040                final int oldUserId = mCurrentUserId;
18041                if (oldUserId == userId) {
18042                    return true;
18043                }
18044
18045                mStackSupervisor.setLockTaskModeLocked(null, false);
18046
18047                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18048                if (userInfo == null) {
18049                    Slog.w(TAG, "No user info for user #" + userId);
18050                    return false;
18051                }
18052                if (foreground && userInfo.isManagedProfile()) {
18053                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18054                    return false;
18055                }
18056
18057                if (foreground) {
18058                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18059                            R.anim.screen_user_enter);
18060                }
18061
18062                boolean needStart = false;
18063
18064                // If the user we are switching to is not currently started, then
18065                // we need to start it now.
18066                if (mStartedUsers.get(userId) == null) {
18067                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18068                    updateStartedUserArrayLocked();
18069                    needStart = true;
18070                }
18071
18072                final Integer userIdInt = Integer.valueOf(userId);
18073                mUserLru.remove(userIdInt);
18074                mUserLru.add(userIdInt);
18075
18076                if (foreground) {
18077                    mCurrentUserId = userId;
18078                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18079                    updateCurrentProfileIdsLocked();
18080                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18081                    // Once the internal notion of the active user has switched, we lock the device
18082                    // with the option to show the user switcher on the keyguard.
18083                    mWindowManager.lockNow(null);
18084                } else {
18085                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18086                    updateCurrentProfileIdsLocked();
18087                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18088                    mUserLru.remove(currentUserIdInt);
18089                    mUserLru.add(currentUserIdInt);
18090                }
18091
18092                final UserStartedState uss = mStartedUsers.get(userId);
18093
18094                // Make sure user is in the started state.  If it is currently
18095                // stopping, we need to knock that off.
18096                if (uss.mState == UserStartedState.STATE_STOPPING) {
18097                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18098                    // so we can just fairly silently bring the user back from
18099                    // the almost-dead.
18100                    uss.mState = UserStartedState.STATE_RUNNING;
18101                    updateStartedUserArrayLocked();
18102                    needStart = true;
18103                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18104                    // This means ACTION_SHUTDOWN has been sent, so we will
18105                    // need to treat this as a new boot of the user.
18106                    uss.mState = UserStartedState.STATE_BOOTING;
18107                    updateStartedUserArrayLocked();
18108                    needStart = true;
18109                }
18110
18111                if (uss.mState == UserStartedState.STATE_BOOTING) {
18112                    // Booting up a new user, need to tell system services about it.
18113                    // Note that this is on the same handler as scheduling of broadcasts,
18114                    // which is important because it needs to go first.
18115                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18116                }
18117
18118                if (foreground) {
18119                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18120                            oldUserId));
18121                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18122                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18123                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18124                            oldUserId, userId, uss));
18125                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18126                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18127                }
18128
18129                if (needStart) {
18130                    // Send USER_STARTED broadcast
18131                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18132                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18133                            | Intent.FLAG_RECEIVER_FOREGROUND);
18134                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18135                    broadcastIntentLocked(null, null, intent,
18136                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18137                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18138                }
18139
18140                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18141                    if (userId != UserHandle.USER_OWNER) {
18142                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18143                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18144                        broadcastIntentLocked(null, null, intent, null,
18145                                new IIntentReceiver.Stub() {
18146                                    public void performReceive(Intent intent, int resultCode,
18147                                            String data, Bundle extras, boolean ordered,
18148                                            boolean sticky, int sendingUser) {
18149                                        onUserInitialized(uss, foreground, oldUserId, userId);
18150                                    }
18151                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18152                                true, false, MY_PID, Process.SYSTEM_UID,
18153                                userId);
18154                        uss.initializing = true;
18155                    } else {
18156                        getUserManagerLocked().makeInitialized(userInfo.id);
18157                    }
18158                }
18159
18160                if (foreground) {
18161                    if (!uss.initializing) {
18162                        moveUserToForeground(uss, oldUserId, userId);
18163                    }
18164                } else {
18165                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18166                }
18167
18168                if (needStart) {
18169                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18170                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18171                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18172                    broadcastIntentLocked(null, null, intent,
18173                            null, new IIntentReceiver.Stub() {
18174                                @Override
18175                                public void performReceive(Intent intent, int resultCode, String data,
18176                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18177                                        throws RemoteException {
18178                                }
18179                            }, 0, null, null,
18180                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18181                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18182                }
18183            }
18184        } finally {
18185            Binder.restoreCallingIdentity(ident);
18186        }
18187
18188        return true;
18189    }
18190
18191    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18192        long ident = Binder.clearCallingIdentity();
18193        try {
18194            Intent intent;
18195            if (oldUserId >= 0) {
18196                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18197                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18198                int count = profiles.size();
18199                for (int i = 0; i < count; i++) {
18200                    int profileUserId = profiles.get(i).id;
18201                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18202                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18203                            | Intent.FLAG_RECEIVER_FOREGROUND);
18204                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18205                    broadcastIntentLocked(null, null, intent,
18206                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18207                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18208                }
18209            }
18210            if (newUserId >= 0) {
18211                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18212                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18213                int count = profiles.size();
18214                for (int i = 0; i < count; i++) {
18215                    int profileUserId = profiles.get(i).id;
18216                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18217                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18218                            | Intent.FLAG_RECEIVER_FOREGROUND);
18219                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18220                    broadcastIntentLocked(null, null, intent,
18221                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18222                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18223                }
18224                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18225                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18226                        | Intent.FLAG_RECEIVER_FOREGROUND);
18227                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18228                broadcastIntentLocked(null, null, intent,
18229                        null, null, 0, null, null,
18230                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18231                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18232            }
18233        } finally {
18234            Binder.restoreCallingIdentity(ident);
18235        }
18236    }
18237
18238    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18239            final int newUserId) {
18240        final int N = mUserSwitchObservers.beginBroadcast();
18241        if (N > 0) {
18242            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18243                int mCount = 0;
18244                @Override
18245                public void sendResult(Bundle data) throws RemoteException {
18246                    synchronized (ActivityManagerService.this) {
18247                        if (mCurUserSwitchCallback == this) {
18248                            mCount++;
18249                            if (mCount == N) {
18250                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18251                            }
18252                        }
18253                    }
18254                }
18255            };
18256            synchronized (this) {
18257                uss.switching = true;
18258                mCurUserSwitchCallback = callback;
18259            }
18260            for (int i=0; i<N; i++) {
18261                try {
18262                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18263                            newUserId, callback);
18264                } catch (RemoteException e) {
18265                }
18266            }
18267        } else {
18268            synchronized (this) {
18269                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18270            }
18271        }
18272        mUserSwitchObservers.finishBroadcast();
18273    }
18274
18275    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18276        synchronized (this) {
18277            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18278            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18279        }
18280    }
18281
18282    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18283        mCurUserSwitchCallback = null;
18284        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18285        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18286                oldUserId, newUserId, uss));
18287    }
18288
18289    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18290        synchronized (this) {
18291            if (foreground) {
18292                moveUserToForeground(uss, oldUserId, newUserId);
18293            }
18294        }
18295
18296        completeSwitchAndInitalize(uss, newUserId, true, false);
18297    }
18298
18299    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18300        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18301        if (homeInFront) {
18302            startHomeActivityLocked(newUserId);
18303        } else {
18304            mStackSupervisor.resumeTopActivitiesLocked();
18305        }
18306        EventLogTags.writeAmSwitchUser(newUserId);
18307        getUserManagerLocked().userForeground(newUserId);
18308        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18309    }
18310
18311    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18312        completeSwitchAndInitalize(uss, newUserId, false, true);
18313    }
18314
18315    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18316            boolean clearInitializing, boolean clearSwitching) {
18317        boolean unfrozen = false;
18318        synchronized (this) {
18319            if (clearInitializing) {
18320                uss.initializing = false;
18321                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18322            }
18323            if (clearSwitching) {
18324                uss.switching = false;
18325            }
18326            if (!uss.switching && !uss.initializing) {
18327                mWindowManager.stopFreezingScreen();
18328                unfrozen = true;
18329            }
18330        }
18331        if (unfrozen) {
18332            final int N = mUserSwitchObservers.beginBroadcast();
18333            for (int i=0; i<N; i++) {
18334                try {
18335                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18336                } catch (RemoteException e) {
18337                }
18338            }
18339            mUserSwitchObservers.finishBroadcast();
18340        }
18341    }
18342
18343    void scheduleStartProfilesLocked() {
18344        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18345            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18346                    DateUtils.SECOND_IN_MILLIS);
18347        }
18348    }
18349
18350    void startProfilesLocked() {
18351        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18352        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18353                mCurrentUserId, false /* enabledOnly */);
18354        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18355        for (UserInfo user : profiles) {
18356            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18357                    && user.id != mCurrentUserId) {
18358                toStart.add(user);
18359            }
18360        }
18361        final int n = toStart.size();
18362        int i = 0;
18363        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18364            startUserInBackground(toStart.get(i).id);
18365        }
18366        if (i < n) {
18367            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18368        }
18369    }
18370
18371    void finishUserBoot(UserStartedState uss) {
18372        synchronized (this) {
18373            if (uss.mState == UserStartedState.STATE_BOOTING
18374                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18375                uss.mState = UserStartedState.STATE_RUNNING;
18376                final int userId = uss.mHandle.getIdentifier();
18377                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18378                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18379                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18380                broadcastIntentLocked(null, null, intent,
18381                        null, null, 0, null, null,
18382                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18383                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18384            }
18385        }
18386    }
18387
18388    void finishUserSwitch(UserStartedState uss) {
18389        synchronized (this) {
18390            finishUserBoot(uss);
18391
18392            startProfilesLocked();
18393
18394            int num = mUserLru.size();
18395            int i = 0;
18396            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18397                Integer oldUserId = mUserLru.get(i);
18398                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18399                if (oldUss == null) {
18400                    // Shouldn't happen, but be sane if it does.
18401                    mUserLru.remove(i);
18402                    num--;
18403                    continue;
18404                }
18405                if (oldUss.mState == UserStartedState.STATE_STOPPING
18406                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18407                    // This user is already stopping, doesn't count.
18408                    num--;
18409                    i++;
18410                    continue;
18411                }
18412                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18413                    // Owner and current can't be stopped, but count as running.
18414                    i++;
18415                    continue;
18416                }
18417                // This is a user to be stopped.
18418                stopUserLocked(oldUserId, null);
18419                num--;
18420                i++;
18421            }
18422        }
18423    }
18424
18425    @Override
18426    public int stopUser(final int userId, final IStopUserCallback callback) {
18427        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18428                != PackageManager.PERMISSION_GRANTED) {
18429            String msg = "Permission Denial: switchUser() from pid="
18430                    + Binder.getCallingPid()
18431                    + ", uid=" + Binder.getCallingUid()
18432                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18433            Slog.w(TAG, msg);
18434            throw new SecurityException(msg);
18435        }
18436        if (userId <= 0) {
18437            throw new IllegalArgumentException("Can't stop primary user " + userId);
18438        }
18439        synchronized (this) {
18440            return stopUserLocked(userId, callback);
18441        }
18442    }
18443
18444    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18445        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18446        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18447            return ActivityManager.USER_OP_IS_CURRENT;
18448        }
18449
18450        final UserStartedState uss = mStartedUsers.get(userId);
18451        if (uss == null) {
18452            // User is not started, nothing to do...  but we do need to
18453            // callback if requested.
18454            if (callback != null) {
18455                mHandler.post(new Runnable() {
18456                    @Override
18457                    public void run() {
18458                        try {
18459                            callback.userStopped(userId);
18460                        } catch (RemoteException e) {
18461                        }
18462                    }
18463                });
18464            }
18465            return ActivityManager.USER_OP_SUCCESS;
18466        }
18467
18468        if (callback != null) {
18469            uss.mStopCallbacks.add(callback);
18470        }
18471
18472        if (uss.mState != UserStartedState.STATE_STOPPING
18473                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18474            uss.mState = UserStartedState.STATE_STOPPING;
18475            updateStartedUserArrayLocked();
18476
18477            long ident = Binder.clearCallingIdentity();
18478            try {
18479                // We are going to broadcast ACTION_USER_STOPPING and then
18480                // once that is done send a final ACTION_SHUTDOWN and then
18481                // stop the user.
18482                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18483                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18484                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18485                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18486                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18487                // This is the result receiver for the final shutdown broadcast.
18488                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18489                    @Override
18490                    public void performReceive(Intent intent, int resultCode, String data,
18491                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18492                        finishUserStop(uss);
18493                    }
18494                };
18495                // This is the result receiver for the initial stopping broadcast.
18496                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18497                    @Override
18498                    public void performReceive(Intent intent, int resultCode, String data,
18499                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18500                        // On to the next.
18501                        synchronized (ActivityManagerService.this) {
18502                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18503                                // Whoops, we are being started back up.  Abort, abort!
18504                                return;
18505                            }
18506                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18507                        }
18508                        mBatteryStatsService.noteEvent(
18509                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18510                                Integer.toString(userId), userId);
18511                        mSystemServiceManager.stopUser(userId);
18512                        broadcastIntentLocked(null, null, shutdownIntent,
18513                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18514                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18515                    }
18516                };
18517                // Kick things off.
18518                broadcastIntentLocked(null, null, stoppingIntent,
18519                        null, stoppingReceiver, 0, null, null,
18520                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18521                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18522            } finally {
18523                Binder.restoreCallingIdentity(ident);
18524            }
18525        }
18526
18527        return ActivityManager.USER_OP_SUCCESS;
18528    }
18529
18530    void finishUserStop(UserStartedState uss) {
18531        final int userId = uss.mHandle.getIdentifier();
18532        boolean stopped;
18533        ArrayList<IStopUserCallback> callbacks;
18534        synchronized (this) {
18535            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18536            if (mStartedUsers.get(userId) != uss) {
18537                stopped = false;
18538            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18539                stopped = false;
18540            } else {
18541                stopped = true;
18542                // User can no longer run.
18543                mStartedUsers.remove(userId);
18544                mUserLru.remove(Integer.valueOf(userId));
18545                updateStartedUserArrayLocked();
18546
18547                // Clean up all state and processes associated with the user.
18548                // Kill all the processes for the user.
18549                forceStopUserLocked(userId, "finish user");
18550            }
18551
18552            // Explicitly remove the old information in mRecentTasks.
18553            removeRecentTasksForUserLocked(userId);
18554        }
18555
18556        for (int i=0; i<callbacks.size(); i++) {
18557            try {
18558                if (stopped) callbacks.get(i).userStopped(userId);
18559                else callbacks.get(i).userStopAborted(userId);
18560            } catch (RemoteException e) {
18561            }
18562        }
18563
18564        if (stopped) {
18565            mSystemServiceManager.cleanupUser(userId);
18566            synchronized (this) {
18567                mStackSupervisor.removeUserLocked(userId);
18568            }
18569        }
18570    }
18571
18572    @Override
18573    public UserInfo getCurrentUser() {
18574        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18575                != PackageManager.PERMISSION_GRANTED) && (
18576                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18577                != PackageManager.PERMISSION_GRANTED)) {
18578            String msg = "Permission Denial: getCurrentUser() from pid="
18579                    + Binder.getCallingPid()
18580                    + ", uid=" + Binder.getCallingUid()
18581                    + " requires " + INTERACT_ACROSS_USERS;
18582            Slog.w(TAG, msg);
18583            throw new SecurityException(msg);
18584        }
18585        synchronized (this) {
18586            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18587            return getUserManagerLocked().getUserInfo(userId);
18588        }
18589    }
18590
18591    int getCurrentUserIdLocked() {
18592        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18593    }
18594
18595    @Override
18596    public boolean isUserRunning(int userId, boolean orStopped) {
18597        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18598                != PackageManager.PERMISSION_GRANTED) {
18599            String msg = "Permission Denial: isUserRunning() from pid="
18600                    + Binder.getCallingPid()
18601                    + ", uid=" + Binder.getCallingUid()
18602                    + " requires " + INTERACT_ACROSS_USERS;
18603            Slog.w(TAG, msg);
18604            throw new SecurityException(msg);
18605        }
18606        synchronized (this) {
18607            return isUserRunningLocked(userId, orStopped);
18608        }
18609    }
18610
18611    boolean isUserRunningLocked(int userId, boolean orStopped) {
18612        UserStartedState state = mStartedUsers.get(userId);
18613        if (state == null) {
18614            return false;
18615        }
18616        if (orStopped) {
18617            return true;
18618        }
18619        return state.mState != UserStartedState.STATE_STOPPING
18620                && state.mState != UserStartedState.STATE_SHUTDOWN;
18621    }
18622
18623    @Override
18624    public int[] getRunningUserIds() {
18625        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18626                != PackageManager.PERMISSION_GRANTED) {
18627            String msg = "Permission Denial: isUserRunning() from pid="
18628                    + Binder.getCallingPid()
18629                    + ", uid=" + Binder.getCallingUid()
18630                    + " requires " + INTERACT_ACROSS_USERS;
18631            Slog.w(TAG, msg);
18632            throw new SecurityException(msg);
18633        }
18634        synchronized (this) {
18635            return mStartedUserArray;
18636        }
18637    }
18638
18639    private void updateStartedUserArrayLocked() {
18640        int num = 0;
18641        for (int i=0; i<mStartedUsers.size();  i++) {
18642            UserStartedState uss = mStartedUsers.valueAt(i);
18643            // This list does not include stopping users.
18644            if (uss.mState != UserStartedState.STATE_STOPPING
18645                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18646                num++;
18647            }
18648        }
18649        mStartedUserArray = new int[num];
18650        num = 0;
18651        for (int i=0; i<mStartedUsers.size();  i++) {
18652            UserStartedState uss = mStartedUsers.valueAt(i);
18653            if (uss.mState != UserStartedState.STATE_STOPPING
18654                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18655                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18656                num++;
18657            }
18658        }
18659    }
18660
18661    @Override
18662    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18663        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18664                != PackageManager.PERMISSION_GRANTED) {
18665            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18666                    + Binder.getCallingPid()
18667                    + ", uid=" + Binder.getCallingUid()
18668                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18669            Slog.w(TAG, msg);
18670            throw new SecurityException(msg);
18671        }
18672
18673        mUserSwitchObservers.register(observer);
18674    }
18675
18676    @Override
18677    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18678        mUserSwitchObservers.unregister(observer);
18679    }
18680
18681    private boolean userExists(int userId) {
18682        if (userId == 0) {
18683            return true;
18684        }
18685        UserManagerService ums = getUserManagerLocked();
18686        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18687    }
18688
18689    int[] getUsersLocked() {
18690        UserManagerService ums = getUserManagerLocked();
18691        return ums != null ? ums.getUserIds() : new int[] { 0 };
18692    }
18693
18694    UserManagerService getUserManagerLocked() {
18695        if (mUserManager == null) {
18696            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18697            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18698        }
18699        return mUserManager;
18700    }
18701
18702    private int applyUserId(int uid, int userId) {
18703        return UserHandle.getUid(userId, uid);
18704    }
18705
18706    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18707        if (info == null) return null;
18708        ApplicationInfo newInfo = new ApplicationInfo(info);
18709        newInfo.uid = applyUserId(info.uid, userId);
18710        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18711                + info.packageName;
18712        return newInfo;
18713    }
18714
18715    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18716        if (aInfo == null
18717                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18718            return aInfo;
18719        }
18720
18721        ActivityInfo info = new ActivityInfo(aInfo);
18722        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18723        return info;
18724    }
18725
18726    private final class LocalService extends ActivityManagerInternal {
18727        @Override
18728        public void goingToSleep() {
18729            ActivityManagerService.this.goingToSleep();
18730        }
18731
18732        @Override
18733        public void wakingUp() {
18734            ActivityManagerService.this.wakingUp();
18735        }
18736
18737        @Override
18738        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18739                String processName, String abiOverride, int uid, Runnable crashHandler) {
18740            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18741                    processName, abiOverride, uid, crashHandler);
18742        }
18743    }
18744
18745    /**
18746     * An implementation of IAppTask, that allows an app to manage its own tasks via
18747     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18748     * only the process that calls getAppTasks() can call the AppTask methods.
18749     */
18750    class AppTaskImpl extends IAppTask.Stub {
18751        private int mTaskId;
18752        private int mCallingUid;
18753
18754        public AppTaskImpl(int taskId, int callingUid) {
18755            mTaskId = taskId;
18756            mCallingUid = callingUid;
18757        }
18758
18759        private void checkCaller() {
18760            if (mCallingUid != Binder.getCallingUid()) {
18761                throw new SecurityException("Caller " + mCallingUid
18762                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18763            }
18764        }
18765
18766        @Override
18767        public void finishAndRemoveTask() {
18768            checkCaller();
18769
18770            synchronized (ActivityManagerService.this) {
18771                long origId = Binder.clearCallingIdentity();
18772                try {
18773                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18774                    if (tr == null) {
18775                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18776                    }
18777                    // Only kill the process if we are not a new document
18778                    int flags = tr.getBaseIntent().getFlags();
18779                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18780                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18781                    removeTaskByIdLocked(mTaskId,
18782                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18783                } finally {
18784                    Binder.restoreCallingIdentity(origId);
18785                }
18786            }
18787        }
18788
18789        @Override
18790        public ActivityManager.RecentTaskInfo getTaskInfo() {
18791            checkCaller();
18792
18793            synchronized (ActivityManagerService.this) {
18794                long origId = Binder.clearCallingIdentity();
18795                try {
18796                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18797                    if (tr == null) {
18798                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18799                    }
18800                    return createRecentTaskInfoFromTaskRecord(tr);
18801                } finally {
18802                    Binder.restoreCallingIdentity(origId);
18803                }
18804            }
18805        }
18806
18807        @Override
18808        public void moveToFront() {
18809            checkCaller();
18810
18811            final TaskRecord tr;
18812            synchronized (ActivityManagerService.this) {
18813                tr = recentTaskForIdLocked(mTaskId);
18814                if (tr == null) {
18815                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18816                }
18817                if (tr.getRootActivity() != null) {
18818                    long origId = Binder.clearCallingIdentity();
18819                    try {
18820                        moveTaskToFrontLocked(tr.taskId, 0, null);
18821                        return;
18822                    } finally {
18823                        Binder.restoreCallingIdentity(origId);
18824                    }
18825                }
18826            }
18827
18828            startActivityFromRecentsInner(tr.taskId, null);
18829        }
18830
18831        @Override
18832        public int startActivity(IBinder whoThread, String callingPackage,
18833                Intent intent, String resolvedType, Bundle options) {
18834            checkCaller();
18835
18836            int callingUser = UserHandle.getCallingUserId();
18837            TaskRecord tr;
18838            IApplicationThread appThread;
18839            synchronized (ActivityManagerService.this) {
18840                tr = recentTaskForIdLocked(mTaskId);
18841                if (tr == null) {
18842                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18843                }
18844                appThread = ApplicationThreadNative.asInterface(whoThread);
18845                if (appThread == null) {
18846                    throw new IllegalArgumentException("Bad app thread " + appThread);
18847                }
18848            }
18849            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18850                    resolvedType, null, null, null, null, 0, 0, null, null,
18851                    null, options, callingUser, null, tr);
18852        }
18853
18854        @Override
18855        public void setExcludeFromRecents(boolean exclude) {
18856            checkCaller();
18857
18858            synchronized (ActivityManagerService.this) {
18859                long origId = Binder.clearCallingIdentity();
18860                try {
18861                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18862                    if (tr == null) {
18863                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18864                    }
18865                    Intent intent = tr.getBaseIntent();
18866                    if (exclude) {
18867                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18868                    } else {
18869                        intent.setFlags(intent.getFlags()
18870                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18871                    }
18872                } finally {
18873                    Binder.restoreCallingIdentity(origId);
18874                }
18875            }
18876        }
18877    }
18878}
18879