ActivityManagerService.java revision 89ad456ea49cb62615ebdcac83a2515743bbe5fa
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.admin.DevicePolicyManager;
41import android.app.usage.UsageEvents;
42import android.app.usage.UsageStatsManagerInternal;
43import android.appwidget.AppWidgetManager;
44import android.content.res.Resources;
45import android.graphics.Bitmap;
46import android.graphics.Point;
47import android.graphics.Rect;
48import android.os.BatteryStats;
49import android.os.PersistableBundle;
50import android.service.voice.IVoiceInteractionSession;
51import android.util.ArrayMap;
52import android.util.ArraySet;
53import android.util.SparseIntArray;
54
55import com.android.internal.R;
56import com.android.internal.annotations.GuardedBy;
57import com.android.internal.app.IAppOpsService;
58import com.android.internal.app.IVoiceInteractor;
59import com.android.internal.app.ProcessMap;
60import com.android.internal.app.ProcessStats;
61import com.android.internal.content.PackageMonitor;
62import com.android.internal.os.BackgroundThread;
63import com.android.internal.os.BatteryStatsImpl;
64import com.android.internal.os.ProcessCpuTracker;
65import com.android.internal.os.TransferPipe;
66import com.android.internal.os.Zygote;
67import com.android.internal.util.FastPrintWriter;
68import com.android.internal.util.FastXmlSerializer;
69import com.android.internal.util.MemInfoReader;
70import com.android.internal.util.Preconditions;
71import com.android.server.AppOpsService;
72import com.android.server.AttributeCache;
73import com.android.server.IntentResolver;
74import com.android.server.LocalServices;
75import com.android.server.ServiceThread;
76import com.android.server.SystemService;
77import com.android.server.SystemServiceManager;
78import com.android.server.Watchdog;
79import com.android.server.am.ActivityStack.ActivityState;
80import com.android.server.firewall.IntentFirewall;
81import com.android.server.pm.UserManagerService;
82import com.android.server.wm.AppTransition;
83import com.android.server.wm.WindowManagerService;
84import com.google.android.collect.Lists;
85import com.google.android.collect.Maps;
86
87import libcore.io.IoUtils;
88
89import org.xmlpull.v1.XmlPullParser;
90import org.xmlpull.v1.XmlPullParserException;
91import org.xmlpull.v1.XmlSerializer;
92
93import android.app.Activity;
94import android.app.ActivityManager;
95import android.app.ActivityManager.RunningTaskInfo;
96import android.app.ActivityManager.StackInfo;
97import android.app.ActivityManagerInternal;
98import android.app.ActivityManagerNative;
99import android.app.ActivityOptions;
100import android.app.ActivityThread;
101import android.app.AlertDialog;
102import android.app.AppGlobals;
103import android.app.ApplicationErrorReport;
104import android.app.Dialog;
105import android.app.IActivityController;
106import android.app.IApplicationThread;
107import android.app.IInstrumentationWatcher;
108import android.app.INotificationManager;
109import android.app.IProcessObserver;
110import android.app.IServiceConnection;
111import android.app.IStopUserCallback;
112import android.app.IUiAutomationConnection;
113import android.app.IUserSwitchObserver;
114import android.app.Instrumentation;
115import android.app.Notification;
116import android.app.NotificationManager;
117import android.app.PendingIntent;
118import android.app.backup.IBackupManager;
119import android.content.ActivityNotFoundException;
120import android.content.BroadcastReceiver;
121import android.content.ClipData;
122import android.content.ComponentCallbacks2;
123import android.content.ComponentName;
124import android.content.ContentProvider;
125import android.content.ContentResolver;
126import android.content.Context;
127import android.content.DialogInterface;
128import android.content.IContentProvider;
129import android.content.IIntentReceiver;
130import android.content.IIntentSender;
131import android.content.Intent;
132import android.content.IntentFilter;
133import android.content.IntentSender;
134import android.content.pm.ActivityInfo;
135import android.content.pm.ApplicationInfo;
136import android.content.pm.ConfigurationInfo;
137import android.content.pm.IPackageDataObserver;
138import android.content.pm.IPackageManager;
139import android.content.pm.InstrumentationInfo;
140import android.content.pm.PackageInfo;
141import android.content.pm.PackageManager;
142import android.content.pm.ParceledListSlice;
143import android.content.pm.UserInfo;
144import android.content.pm.PackageManager.NameNotFoundException;
145import android.content.pm.PathPermission;
146import android.content.pm.ProviderInfo;
147import android.content.pm.ResolveInfo;
148import android.content.pm.ServiceInfo;
149import android.content.res.CompatibilityInfo;
150import android.content.res.Configuration;
151import android.net.Proxy;
152import android.net.ProxyInfo;
153import android.net.Uri;
154import android.os.Binder;
155import android.os.Build;
156import android.os.Bundle;
157import android.os.Debug;
158import android.os.DropBoxManager;
159import android.os.Environment;
160import android.os.FactoryTest;
161import android.os.FileObserver;
162import android.os.FileUtils;
163import android.os.Handler;
164import android.os.IBinder;
165import android.os.IPermissionController;
166import android.os.IRemoteCallback;
167import android.os.IUserManager;
168import android.os.Looper;
169import android.os.Message;
170import android.os.Parcel;
171import android.os.ParcelFileDescriptor;
172import android.os.Process;
173import android.os.RemoteCallbackList;
174import android.os.RemoteException;
175import android.os.SELinux;
176import android.os.ServiceManager;
177import android.os.StrictMode;
178import android.os.SystemClock;
179import android.os.SystemProperties;
180import android.os.UpdateLock;
181import android.os.UserHandle;
182import android.provider.Settings;
183import android.text.format.DateUtils;
184import android.text.format.Time;
185import android.util.AtomicFile;
186import android.util.EventLog;
187import android.util.Log;
188import android.util.Pair;
189import android.util.PrintWriterPrinter;
190import android.util.Slog;
191import android.util.SparseArray;
192import android.util.TimeUtils;
193import android.util.Xml;
194import android.view.Gravity;
195import android.view.LayoutInflater;
196import android.view.View;
197import android.view.WindowManager;
198
199import java.io.BufferedInputStream;
200import java.io.BufferedOutputStream;
201import java.io.DataInputStream;
202import java.io.DataOutputStream;
203import java.io.File;
204import java.io.FileDescriptor;
205import java.io.FileInputStream;
206import java.io.FileNotFoundException;
207import java.io.FileOutputStream;
208import java.io.IOException;
209import java.io.InputStreamReader;
210import java.io.PrintWriter;
211import java.io.StringWriter;
212import java.lang.ref.WeakReference;
213import java.util.ArrayList;
214import java.util.Arrays;
215import java.util.Collections;
216import java.util.Comparator;
217import java.util.HashMap;
218import java.util.HashSet;
219import java.util.Iterator;
220import java.util.List;
221import java.util.Locale;
222import java.util.Map;
223import java.util.Set;
224import java.util.concurrent.atomic.AtomicBoolean;
225import java.util.concurrent.atomic.AtomicLong;
226
227public final class ActivityManagerService extends ActivityManagerNative
228        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
229
230    private static final String USER_DATA_DIR = "/data/user/";
231    // File that stores last updated system version and called preboot receivers
232    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
233
234    static final String TAG = "ActivityManager";
235    static final String TAG_MU = "ActivityManagerServiceMU";
236    static final boolean DEBUG = false;
237    static final boolean localLOGV = DEBUG;
238    static final boolean DEBUG_BACKUP = localLOGV || false;
239    static final boolean DEBUG_BROADCAST = localLOGV || false;
240    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
241    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_CLEANUP = localLOGV || false;
243    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
244    static final boolean DEBUG_FOCUS = false;
245    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
246    static final boolean DEBUG_MU = localLOGV || false;
247    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
248    static final boolean DEBUG_LRU = localLOGV || false;
249    static final boolean DEBUG_PAUSE = localLOGV || false;
250    static final boolean DEBUG_POWER = localLOGV || false;
251    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
252    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
253    static final boolean DEBUG_PROCESSES = localLOGV || false;
254    static final boolean DEBUG_PROVIDER = localLOGV || false;
255    static final boolean DEBUG_RESULTS = localLOGV || false;
256    static final boolean DEBUG_SERVICE = localLOGV || false;
257    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
258    static final boolean DEBUG_STACK = localLOGV || false;
259    static final boolean DEBUG_SWITCH = localLOGV || false;
260    static final boolean DEBUG_TASKS = localLOGV || false;
261    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
262    static final boolean DEBUG_TRANSITION = localLOGV || false;
263    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
264    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
265    static final boolean DEBUG_VISBILITY = localLOGV || false;
266    static final boolean DEBUG_PSS = localLOGV || false;
267    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
268    static final boolean DEBUG_RECENTS = localLOGV || false;
269    static final boolean VALIDATE_TOKENS = false;
270    static final boolean SHOW_ACTIVITY_START_TIME = true;
271
272    // Control over CPU and battery monitoring.
273    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
274    static final boolean MONITOR_CPU_USAGE = true;
275    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
276    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
277    static final boolean MONITOR_THREAD_CPU_USAGE = false;
278
279    // The flags that are set for all calls we make to the package manager.
280    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
281
282    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
283
284    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
285
286    // Maximum number of recent tasks that we can remember.
287    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
288
289    // Maximum number recent bitmaps to keep in memory.
290    static final int MAX_RECENT_BITMAPS = 5;
291
292    // Amount of time after a call to stopAppSwitches() during which we will
293    // prevent further untrusted switches from happening.
294    static final long APP_SWITCH_DELAY_TIME = 5*1000;
295
296    // How long we wait for a launched process to attach to the activity manager
297    // before we decide it's never going to come up for real.
298    static final int PROC_START_TIMEOUT = 10*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real, when the process was
302    // started with a wrapper for instrumentation (such as Valgrind) because it
303    // could take much longer than usual.
304    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
305
306    // How long to wait after going idle before forcing apps to GC.
307    static final int GC_TIMEOUT = 5*1000;
308
309    // The minimum amount of time between successive GC requests for a process.
310    static final int GC_MIN_INTERVAL = 60*1000;
311
312    // The minimum amount of time between successive PSS requests for a process.
313    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process
316    // when the request is due to the memory state being lowered.
317    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
318
319    // The rate at which we check for apps using excessive power -- 15 mins.
320    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
321
322    // The minimum sample duration we will allow before deciding we have
323    // enough data on wake locks to start killing things.
324    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on CPU usage to start killing things.
328    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // How long we allow a receiver to run before giving up on it.
331    static final int BROADCAST_FG_TIMEOUT = 10*1000;
332    static final int BROADCAST_BG_TIMEOUT = 60*1000;
333
334    // How long we wait until we timeout on key dispatching.
335    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
336
337    // How long we wait until we timeout on key dispatching during instrumentation.
338    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
339
340    // Amount of time we wait for observers to handle a user switch before
341    // giving up on them and unfreezing the screen.
342    static final int USER_SWITCH_TIMEOUT = 2*1000;
343
344    // Maximum number of users we allow to be running at a time.
345    static final int MAX_RUNNING_USERS = 3;
346
347    // How long to wait in getAssistContextExtras for the activity and foreground services
348    // to respond with the result.
349    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
350
351    // Maximum number of persisted Uri grants a package is allowed
352    static final int MAX_PERSISTED_URI_GRANTS = 128;
353
354    static final int MY_PID = Process.myPid();
355
356    static final String[] EMPTY_STRING_ARRAY = new String[0];
357
358    // How many bytes to write into the dropbox log before truncating
359    static final int DROPBOX_MAX_SIZE = 256 * 1024;
360
361    // Access modes for handleIncomingUser.
362    static final int ALLOW_NON_FULL = 0;
363    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
364    static final int ALLOW_FULL_ONLY = 2;
365
366    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
367
368    /** All system services */
369    SystemServiceManager mSystemServiceManager;
370
371    /** Run all ActivityStacks through this */
372    ActivityStackSupervisor mStackSupervisor;
373
374    public IntentFirewall mIntentFirewall;
375
376    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
377    // default actuion automatically.  Important for devices without direct input
378    // devices.
379    private boolean mShowDialogs = true;
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
417
418    /**
419     * For addAppTask: cached of the last activity component that was added.
420     */
421    ComponentName mLastAddedTaskComponent;
422
423    /**
424     * For addAppTask: cached of the last activity uid that was added.
425     */
426    int mLastAddedTaskUid;
427
428    /**
429     * For addAppTask: cached of the last ActivityInfo that was added.
430     */
431    ActivityInfo mLastAddedTaskActivity;
432
433    public class PendingAssistExtras extends Binder implements Runnable {
434        public final ActivityRecord activity;
435        public boolean haveResult = false;
436        public Bundle result = null;
437        public PendingAssistExtras(ActivityRecord _activity) {
438            activity = _activity;
439        }
440        @Override
441        public void run() {
442            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
443            synchronized (this) {
444                haveResult = true;
445                notifyAll();
446            }
447        }
448    }
449
450    final ArrayList<PendingAssistExtras> mPendingAssistExtras
451            = new ArrayList<PendingAssistExtras>();
452
453    /**
454     * Process management.
455     */
456    final ProcessList mProcessList = new ProcessList();
457
458    /**
459     * All of the applications we currently have running organized by name.
460     * The keys are strings of the application package name (as
461     * returned by the package manager), and the keys are ApplicationRecord
462     * objects.
463     */
464    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
465
466    /**
467     * Tracking long-term execution of processes to look for abuse and other
468     * bad app behavior.
469     */
470    final ProcessStatsService mProcessStats;
471
472    /**
473     * The currently running isolated processes.
474     */
475    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
476
477    /**
478     * Counter for assigning isolated process uids, to avoid frequently reusing the
479     * same ones.
480     */
481    int mNextIsolatedProcessUid = 0;
482
483    /**
484     * The currently running heavy-weight process, if any.
485     */
486    ProcessRecord mHeavyWeightProcess = null;
487
488    /**
489     * The last time that various processes have crashed.
490     */
491    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
492
493    /**
494     * Information about a process that is currently marked as bad.
495     */
496    static final class BadProcessInfo {
497        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
498            this.time = time;
499            this.shortMsg = shortMsg;
500            this.longMsg = longMsg;
501            this.stack = stack;
502        }
503
504        final long time;
505        final String shortMsg;
506        final String longMsg;
507        final String stack;
508    }
509
510    /**
511     * Set of applications that we consider to be bad, and will reject
512     * incoming broadcasts from (which the user has no control over).
513     * Processes are added to this set when they have crashed twice within
514     * a minimum amount of time; they are removed from it when they are
515     * later restarted (hopefully due to some user action).  The value is the
516     * time it was added to the list.
517     */
518    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
519
520    /**
521     * All of the processes we currently have running organized by pid.
522     * The keys are the pid running the application.
523     *
524     * <p>NOTE: This object is protected by its own lock, NOT the global
525     * activity manager lock!
526     */
527    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
528
529    /**
530     * All of the processes that have been forced to be foreground.  The key
531     * is the pid of the caller who requested it (we hold a death
532     * link on it).
533     */
534    abstract class ForegroundToken implements IBinder.DeathRecipient {
535        int pid;
536        IBinder token;
537    }
538    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
539
540    /**
541     * List of records for processes that someone had tried to start before the
542     * system was ready.  We don't start them at that point, but ensure they
543     * are started by the time booting is complete.
544     */
545    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
546
547    /**
548     * List of persistent applications that are in the process
549     * of being started.
550     */
551    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes that are being forcibly torn down.
555     */
556    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of running applications, sorted by recent usage.
560     * The first entry in the list is the least recently used.
561     */
562    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Where in mLruProcesses that the processes hosting activities start.
566     */
567    int mLruProcessActivityStart = 0;
568
569    /**
570     * Where in mLruProcesses that the processes hosting services start.
571     * This is after (lower index) than mLruProcessesActivityStart.
572     */
573    int mLruProcessServiceStart = 0;
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
579
580    /**
581     * Processes we want to collect PSS data from.
582     */
583    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Last time we requested PSS data of all processes.
587     */
588    long mLastFullPssTime = SystemClock.uptimeMillis();
589
590    /**
591     * If set, the next time we collect PSS data we should do a full collection
592     * with data from native processes and the kernel.
593     */
594    boolean mFullPssPending = false;
595
596    /**
597     * This is the process holding what we currently consider to be
598     * the "home" activity.
599     */
600    ProcessRecord mHomeProcess;
601
602    /**
603     * This is the process holding the activity the user last visited that
604     * is in a different process from the one they are currently in.
605     */
606    ProcessRecord mPreviousProcess;
607
608    /**
609     * The time at which the previous process was last visible.
610     */
611    long mPreviousProcessVisibleTime;
612
613    /**
614     * Which uses have been started, so are allowed to run code.
615     */
616    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
617
618    /**
619     * LRU list of history of current users.  Most recently current is at the end.
620     */
621    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
622
623    /**
624     * Constant array of the users that are currently started.
625     */
626    int[] mStartedUserArray = new int[] { 0 };
627
628    /**
629     * Registered observers of the user switching mechanics.
630     */
631    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
632            = new RemoteCallbackList<IUserSwitchObserver>();
633
634    /**
635     * Currently active user switch.
636     */
637    Object mCurUserSwitchCallback;
638
639    /**
640     * Packages that the user has asked to have run in screen size
641     * compatibility mode instead of filling the screen.
642     */
643    final CompatModePackages mCompatModePackages;
644
645    /**
646     * Set of IntentSenderRecord objects that are currently active.
647     */
648    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
649            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
650
651    /**
652     * Fingerprints (hashCode()) of stack traces that we've
653     * already logged DropBox entries for.  Guarded by itself.  If
654     * something (rogue user app) forces this over
655     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
656     */
657    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
658    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
659
660    /**
661     * Strict Mode background batched logging state.
662     *
663     * The string buffer is guarded by itself, and its lock is also
664     * used to determine if another batched write is already
665     * in-flight.
666     */
667    private final StringBuilder mStrictModeBuffer = new StringBuilder();
668
669    /**
670     * Keeps track of all IIntentReceivers that have been registered for
671     * broadcasts.  Hash keys are the receiver IBinder, hash value is
672     * a ReceiverList.
673     */
674    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
675            new HashMap<IBinder, ReceiverList>();
676
677    /**
678     * Resolver for broadcast intents to registered receivers.
679     * Holds BroadcastFilter (subclass of IntentFilter).
680     */
681    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
682            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
683        @Override
684        protected boolean allowFilterResult(
685                BroadcastFilter filter, List<BroadcastFilter> dest) {
686            IBinder target = filter.receiverList.receiver.asBinder();
687            for (int i=dest.size()-1; i>=0; i--) {
688                if (dest.get(i).receiverList.receiver.asBinder() == target) {
689                    return false;
690                }
691            }
692            return true;
693        }
694
695        @Override
696        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
697            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
698                    || userId == filter.owningUserId) {
699                return super.newResult(filter, match, userId);
700            }
701            return null;
702        }
703
704        @Override
705        protected BroadcastFilter[] newArray(int size) {
706            return new BroadcastFilter[size];
707        }
708
709        @Override
710        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
711            return packageName.equals(filter.packageName);
712        }
713    };
714
715    /**
716     * State of all active sticky broadcasts per user.  Keys are the action of the
717     * sticky Intent, values are an ArrayList of all broadcasted intents with
718     * that action (which should usually be one).  The SparseArray is keyed
719     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
720     * for stickies that are sent to all users.
721     */
722    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
723            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
724
725    final ActiveServices mServices;
726
727    /**
728     * Backup/restore process management
729     */
730    String mBackupAppName = null;
731    BackupRecord mBackupTarget = null;
732
733    final ProviderMap mProviderMap;
734
735    /**
736     * List of content providers who have clients waiting for them.  The
737     * application is currently being launched and the provider will be
738     * removed from this list once it is published.
739     */
740    final ArrayList<ContentProviderRecord> mLaunchingProviders
741            = new ArrayList<ContentProviderRecord>();
742
743    /**
744     * File storing persisted {@link #mGrantedUriPermissions}.
745     */
746    private final AtomicFile mGrantFile;
747
748    /** XML constants used in {@link #mGrantFile} */
749    private static final String TAG_URI_GRANTS = "uri-grants";
750    private static final String TAG_URI_GRANT = "uri-grant";
751    private static final String ATTR_USER_HANDLE = "userHandle";
752    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
753    private static final String ATTR_TARGET_USER_ID = "targetUserId";
754    private static final String ATTR_SOURCE_PKG = "sourcePkg";
755    private static final String ATTR_TARGET_PKG = "targetPkg";
756    private static final String ATTR_URI = "uri";
757    private static final String ATTR_MODE_FLAGS = "modeFlags";
758    private static final String ATTR_CREATED_TIME = "createdTime";
759    private static final String ATTR_PREFIX = "prefix";
760
761    /**
762     * Global set of specific {@link Uri} permissions that have been granted.
763     * This optimized lookup structure maps from {@link UriPermission#targetUid}
764     * to {@link UriPermission#uri} to {@link UriPermission}.
765     */
766    @GuardedBy("this")
767    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
768            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
769
770    public static class GrantUri {
771        public final int sourceUserId;
772        public final Uri uri;
773        public boolean prefix;
774
775        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
776            this.sourceUserId = sourceUserId;
777            this.uri = uri;
778            this.prefix = prefix;
779        }
780
781        @Override
782        public int hashCode() {
783            return toString().hashCode();
784        }
785
786        @Override
787        public boolean equals(Object o) {
788            if (o instanceof GrantUri) {
789                GrantUri other = (GrantUri) o;
790                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
791                        && prefix == other.prefix;
792            }
793            return false;
794        }
795
796        @Override
797        public String toString() {
798            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
799            if (prefix) result += " [prefix]";
800            return result;
801        }
802
803        public String toSafeString() {
804            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
805            if (prefix) result += " [prefix]";
806            return result;
807        }
808
809        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
810            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
811                    ContentProvider.getUriWithoutUserId(uri), false);
812        }
813    }
814
815    CoreSettingsObserver mCoreSettingsObserver;
816
817    /**
818     * Thread-local storage used to carry caller permissions over through
819     * indirect content-provider access.
820     */
821    private class Identity {
822        public int pid;
823        public int uid;
824
825        Identity(int _pid, int _uid) {
826            pid = _pid;
827            uid = _uid;
828        }
829    }
830
831    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
832
833    /**
834     * All information we have collected about the runtime performance of
835     * any user id that can impact battery performance.
836     */
837    final BatteryStatsService mBatteryStatsService;
838
839    /**
840     * Information about component usage
841     */
842    UsageStatsManagerInternal mUsageStatsService;
843
844    /**
845     * Information about and control over application operations
846     */
847    final AppOpsService mAppOpsService;
848
849    /**
850     * Save recent tasks information across reboots.
851     */
852    final TaskPersister mTaskPersister;
853
854    /**
855     * Current configuration information.  HistoryRecord objects are given
856     * a reference to this object to indicate which configuration they are
857     * currently running in, so this object must be kept immutable.
858     */
859    Configuration mConfiguration = new Configuration();
860
861    /**
862     * Current sequencing integer of the configuration, for skipping old
863     * configurations.
864     */
865    int mConfigurationSeq = 0;
866
867    /**
868     * Hardware-reported OpenGLES version.
869     */
870    final int GL_ES_VERSION;
871
872    /**
873     * List of initialization arguments to pass to all processes when binding applications to them.
874     * For example, references to the commonly used services.
875     */
876    HashMap<String, IBinder> mAppBindArgs;
877
878    /**
879     * Temporary to avoid allocations.  Protected by main lock.
880     */
881    final StringBuilder mStringBuilder = new StringBuilder(256);
882
883    /**
884     * Used to control how we initialize the service.
885     */
886    ComponentName mTopComponent;
887    String mTopAction = Intent.ACTION_MAIN;
888    String mTopData;
889    boolean mProcessesReady = false;
890    boolean mSystemReady = false;
891    boolean mBooting = false;
892    boolean mWaitingUpdate = false;
893    boolean mDidUpdate = false;
894    boolean mOnBattery = false;
895    boolean mLaunchWarningShown = false;
896
897    Context mContext;
898
899    int mFactoryTest;
900
901    boolean mCheckedForSetup;
902
903    /**
904     * The time at which we will allow normal application switches again,
905     * after a call to {@link #stopAppSwitches()}.
906     */
907    long mAppSwitchesAllowedTime;
908
909    /**
910     * This is set to true after the first switch after mAppSwitchesAllowedTime
911     * is set; any switches after that will clear the time.
912     */
913    boolean mDidAppSwitch;
914
915    /**
916     * Last time (in realtime) at which we checked for power usage.
917     */
918    long mLastPowerCheckRealtime;
919
920    /**
921     * Last time (in uptime) at which we checked for power usage.
922     */
923    long mLastPowerCheckUptime;
924
925    /**
926     * Set while we are wanting to sleep, to prevent any
927     * activities from being started/resumed.
928     */
929    private boolean mSleeping = false;
930
931    /**
932     * Set while we are running a voice interaction.  This overrides
933     * sleeping while it is active.
934     */
935    private boolean mRunningVoice = false;
936
937    /**
938     * State of external calls telling us if the device is asleep.
939     */
940    private boolean mWentToSleep = false;
941
942    /**
943     * State of external call telling us if the lock screen is shown.
944     */
945    private boolean mLockScreenShown = false;
946
947    /**
948     * Set if we are shutting down the system, similar to sleeping.
949     */
950    boolean mShuttingDown = false;
951
952    /**
953     * Current sequence id for oom_adj computation traversal.
954     */
955    int mAdjSeq = 0;
956
957    /**
958     * Current sequence id for process LRU updating.
959     */
960    int mLruSeq = 0;
961
962    /**
963     * Keep track of the non-cached/empty process we last found, to help
964     * determine how to distribute cached/empty processes next time.
965     */
966    int mNumNonCachedProcs = 0;
967
968    /**
969     * Keep track of the number of cached hidden procs, to balance oom adj
970     * distribution between those and empty procs.
971     */
972    int mNumCachedHiddenProcs = 0;
973
974    /**
975     * Keep track of the number of service processes we last found, to
976     * determine on the next iteration which should be B services.
977     */
978    int mNumServiceProcs = 0;
979    int mNewNumAServiceProcs = 0;
980    int mNewNumServiceProcs = 0;
981
982    /**
983     * Allow the current computed overall memory level of the system to go down?
984     * This is set to false when we are killing processes for reasons other than
985     * memory management, so that the now smaller process list will not be taken as
986     * an indication that memory is tighter.
987     */
988    boolean mAllowLowerMemLevel = false;
989
990    /**
991     * The last computed memory level, for holding when we are in a state that
992     * processes are going away for other reasons.
993     */
994    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
995
996    /**
997     * The last total number of process we have, to determine if changes actually look
998     * like a shrinking number of process due to lower RAM.
999     */
1000    int mLastNumProcesses;
1001
1002    /**
1003     * The uptime of the last time we performed idle maintenance.
1004     */
1005    long mLastIdleTime = SystemClock.uptimeMillis();
1006
1007    /**
1008     * Total time spent with RAM that has been added in the past since the last idle time.
1009     */
1010    long mLowRamTimeSinceLastIdle = 0;
1011
1012    /**
1013     * If RAM is currently low, when that horrible situation started.
1014     */
1015    long mLowRamStartTime = 0;
1016
1017    /**
1018     * For reporting to battery stats the current top application.
1019     */
1020    private String mCurResumedPackage = null;
1021    private int mCurResumedUid = -1;
1022
1023    /**
1024     * For reporting to battery stats the apps currently running foreground
1025     * service.  The ProcessMap is package/uid tuples; each of these contain
1026     * an array of the currently foreground processes.
1027     */
1028    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1029            = new ProcessMap<ArrayList<ProcessRecord>>();
1030
1031    /**
1032     * This is set if we had to do a delayed dexopt of an app before launching
1033     * it, to increase the ANR timeouts in that case.
1034     */
1035    boolean mDidDexOpt;
1036
1037    /**
1038     * Set if the systemServer made a call to enterSafeMode.
1039     */
1040    boolean mSafeMode;
1041
1042    String mDebugApp = null;
1043    boolean mWaitForDebugger = false;
1044    boolean mDebugTransient = false;
1045    String mOrigDebugApp = null;
1046    boolean mOrigWaitForDebugger = false;
1047    boolean mAlwaysFinishActivities = false;
1048    IActivityController mController = null;
1049    String mProfileApp = null;
1050    ProcessRecord mProfileProc = null;
1051    String mProfileFile;
1052    ParcelFileDescriptor mProfileFd;
1053    int mProfileType = 0;
1054    boolean mAutoStopProfiler = false;
1055    String mOpenGlTraceApp = null;
1056
1057    static class ProcessChangeItem {
1058        static final int CHANGE_ACTIVITIES = 1<<0;
1059        static final int CHANGE_PROCESS_STATE = 1<<1;
1060        int changes;
1061        int uid;
1062        int pid;
1063        int processState;
1064        boolean foregroundActivities;
1065    }
1066
1067    final RemoteCallbackList<IProcessObserver> mProcessObservers
1068            = new RemoteCallbackList<IProcessObserver>();
1069    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1070
1071    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1072            = new ArrayList<ProcessChangeItem>();
1073    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075
1076    /**
1077     * Runtime CPU use collection thread.  This object's lock is used to
1078     * protect all related state.
1079     */
1080    final Thread mProcessCpuThread;
1081
1082    /**
1083     * Used to collect process stats when showing not responding dialog.
1084     * Protected by mProcessCpuThread.
1085     */
1086    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1087            MONITOR_THREAD_CPU_USAGE);
1088    final AtomicLong mLastCpuTime = new AtomicLong(0);
1089    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1090
1091    long mLastWriteTime = 0;
1092
1093    /**
1094     * Used to retain an update lock when the foreground activity is in
1095     * immersive mode.
1096     */
1097    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1098
1099    /**
1100     * Set to true after the system has finished booting.
1101     */
1102    boolean mBooted = false;
1103
1104    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1105    int mProcessLimitOverride = -1;
1106
1107    WindowManagerService mWindowManager;
1108
1109    final ActivityThread mSystemThread;
1110
1111    int mCurrentUserId = 0;
1112    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1113
1114    /**
1115     * Mapping from each known user ID to the profile group ID it is associated with.
1116     */
1117    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1118
1119    private UserManagerService mUserManager;
1120
1121    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1122        final ProcessRecord mApp;
1123        final int mPid;
1124        final IApplicationThread mAppThread;
1125
1126        AppDeathRecipient(ProcessRecord app, int pid,
1127                IApplicationThread thread) {
1128            if (localLOGV) Slog.v(
1129                TAG, "New death recipient " + this
1130                + " for thread " + thread.asBinder());
1131            mApp = app;
1132            mPid = pid;
1133            mAppThread = thread;
1134        }
1135
1136        @Override
1137        public void binderDied() {
1138            if (localLOGV) Slog.v(
1139                TAG, "Death received in " + this
1140                + " for thread " + mAppThread.asBinder());
1141            synchronized(ActivityManagerService.this) {
1142                appDiedLocked(mApp, mPid, mAppThread);
1143            }
1144        }
1145    }
1146
1147    static final int SHOW_ERROR_MSG = 1;
1148    static final int SHOW_NOT_RESPONDING_MSG = 2;
1149    static final int SHOW_FACTORY_ERROR_MSG = 3;
1150    static final int UPDATE_CONFIGURATION_MSG = 4;
1151    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1152    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1153    static final int SERVICE_TIMEOUT_MSG = 12;
1154    static final int UPDATE_TIME_ZONE = 13;
1155    static final int SHOW_UID_ERROR_MSG = 14;
1156    static final int IM_FEELING_LUCKY_MSG = 15;
1157    static final int PROC_START_TIMEOUT_MSG = 20;
1158    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1159    static final int KILL_APPLICATION_MSG = 22;
1160    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1161    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1162    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1163    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1164    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1165    static final int CLEAR_DNS_CACHE_MSG = 28;
1166    static final int UPDATE_HTTP_PROXY_MSG = 29;
1167    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1168    static final int DISPATCH_PROCESSES_CHANGED = 31;
1169    static final int DISPATCH_PROCESS_DIED = 32;
1170    static final int REPORT_MEM_USAGE_MSG = 33;
1171    static final int REPORT_USER_SWITCH_MSG = 34;
1172    static final int CONTINUE_USER_SWITCH_MSG = 35;
1173    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1174    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1175    static final int PERSIST_URI_GRANTS_MSG = 38;
1176    static final int REQUEST_ALL_PSS_MSG = 39;
1177    static final int START_PROFILES_MSG = 40;
1178    static final int UPDATE_TIME = 41;
1179    static final int SYSTEM_USER_START_MSG = 42;
1180    static final int SYSTEM_USER_CURRENT_MSG = 43;
1181    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1182    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1183    static final int START_USER_SWITCH_MSG = 46;
1184
1185    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1186    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1187    static final int FIRST_COMPAT_MODE_MSG = 300;
1188    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1189
1190    AlertDialog mUidAlert;
1191    CompatModeDialog mCompatModeDialog;
1192    long mLastMemUsageReportTime = 0;
1193
1194    private LockToAppRequestDialog mLockToAppRequest;
1195
1196    /**
1197     * Flag whether the current user is a "monkey", i.e. whether
1198     * the UI is driven by a UI automation tool.
1199     */
1200    private boolean mUserIsMonkey;
1201
1202    /** Flag whether the device has a recents UI */
1203    final boolean mHasRecents;
1204
1205    final int mThumbnailWidth;
1206    final int mThumbnailHeight;
1207
1208    final ServiceThread mHandlerThread;
1209    final MainHandler mHandler;
1210
1211    final class MainHandler extends Handler {
1212        public MainHandler(Looper looper) {
1213            super(looper, null, true);
1214        }
1215
1216        @Override
1217        public void handleMessage(Message msg) {
1218            switch (msg.what) {
1219            case SHOW_ERROR_MSG: {
1220                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1221                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1222                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1223                synchronized (ActivityManagerService.this) {
1224                    ProcessRecord proc = (ProcessRecord)data.get("app");
1225                    AppErrorResult res = (AppErrorResult) data.get("result");
1226                    if (proc != null && proc.crashDialog != null) {
1227                        Slog.e(TAG, "App already has crash dialog: " + proc);
1228                        if (res != null) {
1229                            res.set(0);
1230                        }
1231                        return;
1232                    }
1233                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1234                            >= Process.FIRST_APPLICATION_UID
1235                            && proc.pid != MY_PID);
1236                    for (int userId : mCurrentProfileIds) {
1237                        isBackground &= (proc.userId != userId);
1238                    }
1239                    if (isBackground && !showBackground) {
1240                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1241                        if (res != null) {
1242                            res.set(0);
1243                        }
1244                        return;
1245                    }
1246                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1247                        Dialog d = new AppErrorDialog(mContext,
1248                                ActivityManagerService.this, res, proc);
1249                        d.show();
1250                        proc.crashDialog = d;
1251                    } else {
1252                        // The device is asleep, so just pretend that the user
1253                        // saw a crash dialog and hit "force quit".
1254                        if (res != null) {
1255                            res.set(0);
1256                        }
1257                    }
1258                }
1259
1260                ensureBootCompleted();
1261            } break;
1262            case SHOW_NOT_RESPONDING_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1265                    ProcessRecord proc = (ProcessRecord)data.get("app");
1266                    if (proc != null && proc.anrDialog != null) {
1267                        Slog.e(TAG, "App already has anr dialog: " + proc);
1268                        return;
1269                    }
1270
1271                    Intent intent = new Intent("android.intent.action.ANR");
1272                    if (!mProcessesReady) {
1273                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1274                                | Intent.FLAG_RECEIVER_FOREGROUND);
1275                    }
1276                    broadcastIntentLocked(null, null, intent,
1277                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1278                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1279
1280                    if (mShowDialogs) {
1281                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1282                                mContext, proc, (ActivityRecord)data.get("activity"),
1283                                msg.arg1 != 0);
1284                        d.show();
1285                        proc.anrDialog = d;
1286                    } else {
1287                        // Just kill the app if there is no dialog to be shown.
1288                        killAppAtUsersRequest(proc, null);
1289                    }
1290                }
1291
1292                ensureBootCompleted();
1293            } break;
1294            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1295                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1296                synchronized (ActivityManagerService.this) {
1297                    ProcessRecord proc = (ProcessRecord) data.get("app");
1298                    if (proc == null) {
1299                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1300                        break;
1301                    }
1302                    if (proc.crashDialog != null) {
1303                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1304                        return;
1305                    }
1306                    AppErrorResult res = (AppErrorResult) data.get("result");
1307                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1308                        Dialog d = new StrictModeViolationDialog(mContext,
1309                                ActivityManagerService.this, res, proc);
1310                        d.show();
1311                        proc.crashDialog = d;
1312                    } else {
1313                        // The device is asleep, so just pretend that the user
1314                        // saw a crash dialog and hit "force quit".
1315                        res.set(0);
1316                    }
1317                }
1318                ensureBootCompleted();
1319            } break;
1320            case SHOW_FACTORY_ERROR_MSG: {
1321                Dialog d = new FactoryErrorDialog(
1322                    mContext, msg.getData().getCharSequence("msg"));
1323                d.show();
1324                ensureBootCompleted();
1325            } break;
1326            case UPDATE_CONFIGURATION_MSG: {
1327                final ContentResolver resolver = mContext.getContentResolver();
1328                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1329            } break;
1330            case GC_BACKGROUND_PROCESSES_MSG: {
1331                synchronized (ActivityManagerService.this) {
1332                    performAppGcsIfAppropriateLocked();
1333                }
1334            } break;
1335            case WAIT_FOR_DEBUGGER_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    ProcessRecord app = (ProcessRecord)msg.obj;
1338                    if (msg.arg1 != 0) {
1339                        if (!app.waitedForDebugger) {
1340                            Dialog d = new AppWaitingForDebuggerDialog(
1341                                    ActivityManagerService.this,
1342                                    mContext, app);
1343                            app.waitDialog = d;
1344                            app.waitedForDebugger = true;
1345                            d.show();
1346                        }
1347                    } else {
1348                        if (app.waitDialog != null) {
1349                            app.waitDialog.dismiss();
1350                            app.waitDialog = null;
1351                        }
1352                    }
1353                }
1354            } break;
1355            case SERVICE_TIMEOUT_MSG: {
1356                if (mDidDexOpt) {
1357                    mDidDexOpt = false;
1358                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1359                    nmsg.obj = msg.obj;
1360                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1361                    return;
1362                }
1363                mServices.serviceTimeout((ProcessRecord)msg.obj);
1364            } break;
1365            case UPDATE_TIME_ZONE: {
1366                synchronized (ActivityManagerService.this) {
1367                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1368                        ProcessRecord r = mLruProcesses.get(i);
1369                        if (r.thread != null) {
1370                            try {
1371                                r.thread.updateTimeZone();
1372                            } catch (RemoteException ex) {
1373                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1374                            }
1375                        }
1376                    }
1377                }
1378            } break;
1379            case CLEAR_DNS_CACHE_MSG: {
1380                synchronized (ActivityManagerService.this) {
1381                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1382                        ProcessRecord r = mLruProcesses.get(i);
1383                        if (r.thread != null) {
1384                            try {
1385                                r.thread.clearDnsCache();
1386                            } catch (RemoteException ex) {
1387                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1388                            }
1389                        }
1390                    }
1391                }
1392            } break;
1393            case UPDATE_HTTP_PROXY_MSG: {
1394                ProxyInfo proxy = (ProxyInfo)msg.obj;
1395                String host = "";
1396                String port = "";
1397                String exclList = "";
1398                Uri pacFileUrl = Uri.EMPTY;
1399                if (proxy != null) {
1400                    host = proxy.getHost();
1401                    port = Integer.toString(proxy.getPort());
1402                    exclList = proxy.getExclusionListAsString();
1403                    pacFileUrl = proxy.getPacFileUrl();
1404                }
1405                synchronized (ActivityManagerService.this) {
1406                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1407                        ProcessRecord r = mLruProcesses.get(i);
1408                        if (r.thread != null) {
1409                            try {
1410                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1411                            } catch (RemoteException ex) {
1412                                Slog.w(TAG, "Failed to update http proxy for: " +
1413                                        r.info.processName);
1414                            }
1415                        }
1416                    }
1417                }
1418            } break;
1419            case SHOW_UID_ERROR_MSG: {
1420                String title = "System UIDs Inconsistent";
1421                String text = "UIDs on the system are inconsistent, you need to wipe your"
1422                        + " data partition or your device will be unstable.";
1423                Log.e(TAG, title + ": " + text);
1424                if (mShowDialogs) {
1425                    // XXX This is a temporary dialog, no need to localize.
1426                    AlertDialog d = new BaseErrorDialog(mContext);
1427                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1428                    d.setCancelable(false);
1429                    d.setTitle(title);
1430                    d.setMessage(text);
1431                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1432                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1433                    mUidAlert = d;
1434                    d.show();
1435                }
1436            } break;
1437            case IM_FEELING_LUCKY_MSG: {
1438                if (mUidAlert != null) {
1439                    mUidAlert.dismiss();
1440                    mUidAlert = null;
1441                }
1442            } break;
1443            case PROC_START_TIMEOUT_MSG: {
1444                if (mDidDexOpt) {
1445                    mDidDexOpt = false;
1446                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1447                    nmsg.obj = msg.obj;
1448                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1449                    return;
1450                }
1451                ProcessRecord app = (ProcessRecord)msg.obj;
1452                synchronized (ActivityManagerService.this) {
1453                    processStartTimedOutLocked(app);
1454                }
1455            } break;
1456            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1457                synchronized (ActivityManagerService.this) {
1458                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1459                }
1460            } break;
1461            case KILL_APPLICATION_MSG: {
1462                synchronized (ActivityManagerService.this) {
1463                    int appid = msg.arg1;
1464                    boolean restart = (msg.arg2 == 1);
1465                    Bundle bundle = (Bundle)msg.obj;
1466                    String pkg = bundle.getString("pkg");
1467                    String reason = bundle.getString("reason");
1468                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1469                            false, UserHandle.USER_ALL, reason);
1470                }
1471            } break;
1472            case FINALIZE_PENDING_INTENT_MSG: {
1473                ((PendingIntentRecord)msg.obj).completeFinalize();
1474            } break;
1475            case POST_HEAVY_NOTIFICATION_MSG: {
1476                INotificationManager inm = NotificationManager.getService();
1477                if (inm == null) {
1478                    return;
1479                }
1480
1481                ActivityRecord root = (ActivityRecord)msg.obj;
1482                ProcessRecord process = root.app;
1483                if (process == null) {
1484                    return;
1485                }
1486
1487                try {
1488                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1489                    String text = mContext.getString(R.string.heavy_weight_notification,
1490                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1491                    Notification notification = new Notification();
1492                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1493                    notification.when = 0;
1494                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1495                    notification.tickerText = text;
1496                    notification.defaults = 0; // please be quiet
1497                    notification.sound = null;
1498                    notification.vibrate = null;
1499                    notification.color = mContext.getResources().getColor(
1500                            com.android.internal.R.color.system_notification_accent_color);
1501                    notification.setLatestEventInfo(context, text,
1502                            mContext.getText(R.string.heavy_weight_notification_detail),
1503                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1504                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1505                                    new UserHandle(root.userId)));
1506
1507                    try {
1508                        int[] outId = new int[1];
1509                        inm.enqueueNotificationWithTag("android", "android", null,
1510                                R.string.heavy_weight_notification,
1511                                notification, outId, root.userId);
1512                    } catch (RuntimeException e) {
1513                        Slog.w(ActivityManagerService.TAG,
1514                                "Error showing notification for heavy-weight app", e);
1515                    } catch (RemoteException e) {
1516                    }
1517                } catch (NameNotFoundException e) {
1518                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1519                }
1520            } break;
1521            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1522                INotificationManager inm = NotificationManager.getService();
1523                if (inm == null) {
1524                    return;
1525                }
1526                try {
1527                    inm.cancelNotificationWithTag("android", null,
1528                            R.string.heavy_weight_notification,  msg.arg1);
1529                } catch (RuntimeException e) {
1530                    Slog.w(ActivityManagerService.TAG,
1531                            "Error canceling notification for service", e);
1532                } catch (RemoteException e) {
1533                }
1534            } break;
1535            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    checkExcessivePowerUsageLocked(true);
1538                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1539                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1540                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1541                }
1542            } break;
1543            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    ActivityRecord ar = (ActivityRecord)msg.obj;
1546                    if (mCompatModeDialog != null) {
1547                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1548                                ar.info.applicationInfo.packageName)) {
1549                            return;
1550                        }
1551                        mCompatModeDialog.dismiss();
1552                        mCompatModeDialog = null;
1553                    }
1554                    if (ar != null && false) {
1555                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1556                                ar.packageName)) {
1557                            int mode = mCompatModePackages.computeCompatModeLocked(
1558                                    ar.info.applicationInfo);
1559                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1560                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1561                                mCompatModeDialog = new CompatModeDialog(
1562                                        ActivityManagerService.this, mContext,
1563                                        ar.info.applicationInfo);
1564                                mCompatModeDialog.show();
1565                            }
1566                        }
1567                    }
1568                }
1569                break;
1570            }
1571            case DISPATCH_PROCESSES_CHANGED: {
1572                dispatchProcessesChanged();
1573                break;
1574            }
1575            case DISPATCH_PROCESS_DIED: {
1576                final int pid = msg.arg1;
1577                final int uid = msg.arg2;
1578                dispatchProcessDied(pid, uid);
1579                break;
1580            }
1581            case REPORT_MEM_USAGE_MSG: {
1582                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1583                Thread thread = new Thread() {
1584                    @Override public void run() {
1585                        final SparseArray<ProcessMemInfo> infoMap
1586                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589                            infoMap.put(mi.pid, mi);
1590                        }
1591                        updateCpuStatsNow();
1592                        synchronized (mProcessCpuThread) {
1593                            final int N = mProcessCpuTracker.countStats();
1594                            for (int i=0; i<N; i++) {
1595                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1596                                if (st.vsize > 0) {
1597                                    long pss = Debug.getPss(st.pid, null);
1598                                    if (pss > 0) {
1599                                        if (infoMap.indexOfKey(st.pid) < 0) {
1600                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1601                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1602                                            mi.pss = pss;
1603                                            memInfos.add(mi);
1604                                        }
1605                                    }
1606                                }
1607                            }
1608                        }
1609
1610                        long totalPss = 0;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            if (mi.pss == 0) {
1614                                mi.pss = Debug.getPss(mi.pid, null);
1615                            }
1616                            totalPss += mi.pss;
1617                        }
1618                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1619                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1620                                if (lhs.oomAdj != rhs.oomAdj) {
1621                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1622                                }
1623                                if (lhs.pss != rhs.pss) {
1624                                    return lhs.pss < rhs.pss ? 1 : -1;
1625                                }
1626                                return 0;
1627                            }
1628                        });
1629
1630                        StringBuilder tag = new StringBuilder(128);
1631                        StringBuilder stack = new StringBuilder(128);
1632                        tag.append("Low on memory -- ");
1633                        appendMemBucket(tag, totalPss, "total", false);
1634                        appendMemBucket(stack, totalPss, "total", true);
1635
1636                        StringBuilder logBuilder = new StringBuilder(1024);
1637                        logBuilder.append("Low on memory:\n");
1638
1639                        boolean firstLine = true;
1640                        int lastOomAdj = Integer.MIN_VALUE;
1641                        for (int i=0, N=memInfos.size(); i<N; i++) {
1642                            ProcessMemInfo mi = memInfos.get(i);
1643
1644                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1645                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1646                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1647                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1648                                if (lastOomAdj != mi.oomAdj) {
1649                                    lastOomAdj = mi.oomAdj;
1650                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1651                                        tag.append(" / ");
1652                                    }
1653                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1654                                        if (firstLine) {
1655                                            stack.append(":");
1656                                            firstLine = false;
1657                                        }
1658                                        stack.append("\n\t at ");
1659                                    } else {
1660                                        stack.append("$");
1661                                    }
1662                                } else {
1663                                    tag.append(" ");
1664                                    stack.append("$");
1665                                }
1666                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1667                                    appendMemBucket(tag, mi.pss, mi.name, false);
1668                                }
1669                                appendMemBucket(stack, mi.pss, mi.name, true);
1670                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1671                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1672                                    stack.append("(");
1673                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1674                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1675                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1676                                            stack.append(":");
1677                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1678                                        }
1679                                    }
1680                                    stack.append(")");
1681                                }
1682                            }
1683
1684                            logBuilder.append("  ");
1685                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1686                            logBuilder.append(' ');
1687                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1688                            logBuilder.append(' ');
1689                            ProcessList.appendRamKb(logBuilder, mi.pss);
1690                            logBuilder.append(" kB: ");
1691                            logBuilder.append(mi.name);
1692                            logBuilder.append(" (");
1693                            logBuilder.append(mi.pid);
1694                            logBuilder.append(") ");
1695                            logBuilder.append(mi.adjType);
1696                            logBuilder.append('\n');
1697                            if (mi.adjReason != null) {
1698                                logBuilder.append("                      ");
1699                                logBuilder.append(mi.adjReason);
1700                                logBuilder.append('\n');
1701                            }
1702                        }
1703
1704                        logBuilder.append("           ");
1705                        ProcessList.appendRamKb(logBuilder, totalPss);
1706                        logBuilder.append(" kB: TOTAL\n");
1707
1708                        long[] infos = new long[Debug.MEMINFO_COUNT];
1709                        Debug.getMemInfo(infos);
1710                        logBuilder.append("  MemInfo: ");
1711                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1715                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1716                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1717                            logBuilder.append("  ZRAM: ");
1718                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1719                            logBuilder.append(" kB RAM, ");
1720                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1721                            logBuilder.append(" kB swap total, ");
1722                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1723                            logBuilder.append(" kB swap free\n");
1724                        }
1725                        Slog.i(TAG, logBuilder.toString());
1726
1727                        StringBuilder dropBuilder = new StringBuilder(1024);
1728                        /*
1729                        StringWriter oomSw = new StringWriter();
1730                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1731                        StringWriter catSw = new StringWriter();
1732                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1733                        String[] emptyArgs = new String[] { };
1734                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1735                        oomPw.flush();
1736                        String oomString = oomSw.toString();
1737                        */
1738                        dropBuilder.append(stack);
1739                        dropBuilder.append('\n');
1740                        dropBuilder.append('\n');
1741                        dropBuilder.append(logBuilder);
1742                        dropBuilder.append('\n');
1743                        /*
1744                        dropBuilder.append(oomString);
1745                        dropBuilder.append('\n');
1746                        */
1747                        StringWriter catSw = new StringWriter();
1748                        synchronized (ActivityManagerService.this) {
1749                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1750                            String[] emptyArgs = new String[] { };
1751                            catPw.println();
1752                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1753                            catPw.println();
1754                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1755                                    false, false, null);
1756                            catPw.println();
1757                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1758                            catPw.flush();
1759                        }
1760                        dropBuilder.append(catSw.toString());
1761                        addErrorToDropBox("lowmem", null, "system_server", null,
1762                                null, tag.toString(), dropBuilder.toString(), null, null);
1763                        //Slog.i(TAG, "Sent to dropbox:");
1764                        //Slog.i(TAG, dropBuilder.toString());
1765                        synchronized (ActivityManagerService.this) {
1766                            long now = SystemClock.uptimeMillis();
1767                            if (mLastMemUsageReportTime < now) {
1768                                mLastMemUsageReportTime = now;
1769                            }
1770                        }
1771                    }
1772                };
1773                thread.start();
1774                break;
1775            }
1776            case START_USER_SWITCH_MSG: {
1777                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1778                break;
1779            }
1780            case REPORT_USER_SWITCH_MSG: {
1781                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1782                break;
1783            }
1784            case CONTINUE_USER_SWITCH_MSG: {
1785                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1786                break;
1787            }
1788            case USER_SWITCH_TIMEOUT_MSG: {
1789                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case IMMERSIVE_MODE_LOCK_MSG: {
1793                final boolean nextState = (msg.arg1 != 0);
1794                if (mUpdateLock.isHeld() != nextState) {
1795                    if (DEBUG_IMMERSIVE) {
1796                        final ActivityRecord r = (ActivityRecord) msg.obj;
1797                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1798                    }
1799                    if (nextState) {
1800                        mUpdateLock.acquire();
1801                    } else {
1802                        mUpdateLock.release();
1803                    }
1804                }
1805                break;
1806            }
1807            case PERSIST_URI_GRANTS_MSG: {
1808                writeGrantedUriPermissions();
1809                break;
1810            }
1811            case REQUEST_ALL_PSS_MSG: {
1812                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1813                break;
1814            }
1815            case START_PROFILES_MSG: {
1816                synchronized (ActivityManagerService.this) {
1817                    startProfilesLocked();
1818                }
1819                break;
1820            }
1821            case UPDATE_TIME: {
1822                synchronized (ActivityManagerService.this) {
1823                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1824                        ProcessRecord r = mLruProcesses.get(i);
1825                        if (r.thread != null) {
1826                            try {
1827                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1828                            } catch (RemoteException ex) {
1829                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1830                            }
1831                        }
1832                    }
1833                }
1834                break;
1835            }
1836            case SYSTEM_USER_START_MSG: {
1837                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1838                        Integer.toString(msg.arg1), msg.arg1);
1839                mSystemServiceManager.startUser(msg.arg1);
1840                break;
1841            }
1842            case SYSTEM_USER_CURRENT_MSG: {
1843                mBatteryStatsService.noteEvent(
1844                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1845                        Integer.toString(msg.arg2), msg.arg2);
1846                mBatteryStatsService.noteEvent(
1847                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1848                        Integer.toString(msg.arg1), msg.arg1);
1849                mSystemServiceManager.switchUser(msg.arg1);
1850                mLockToAppRequest.clearPrompt();
1851                break;
1852            }
1853            case ENTER_ANIMATION_COMPLETE_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1856                    if (r != null && r.app != null && r.app.thread != null) {
1857                        try {
1858                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1859                        } catch (RemoteException e) {
1860                        }
1861                    }
1862                }
1863                break;
1864            }
1865            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1866                enableScreenAfterBoot();
1867                break;
1868            }
1869            }
1870        }
1871    };
1872
1873    static final int COLLECT_PSS_BG_MSG = 1;
1874
1875    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1876        @Override
1877        public void handleMessage(Message msg) {
1878            switch (msg.what) {
1879            case COLLECT_PSS_BG_MSG: {
1880                long start = SystemClock.uptimeMillis();
1881                MemInfoReader memInfo = null;
1882                synchronized (ActivityManagerService.this) {
1883                    if (mFullPssPending) {
1884                        mFullPssPending = false;
1885                        memInfo = new MemInfoReader();
1886                    }
1887                }
1888                if (memInfo != null) {
1889                    updateCpuStatsNow();
1890                    long nativeTotalPss = 0;
1891                    synchronized (mProcessCpuThread) {
1892                        final int N = mProcessCpuTracker.countStats();
1893                        for (int j=0; j<N; j++) {
1894                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1895                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1896                                // This is definitely an application process; skip it.
1897                                continue;
1898                            }
1899                            synchronized (mPidsSelfLocked) {
1900                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1901                                    // This is one of our own processes; skip it.
1902                                    continue;
1903                                }
1904                            }
1905                            nativeTotalPss += Debug.getPss(st.pid, null);
1906                        }
1907                    }
1908                    memInfo.readMemInfo();
1909                    synchronized (this) {
1910                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1911                                + (SystemClock.uptimeMillis()-start) + "ms");
1912                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1913                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1914                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1915                                        +memInfo.getSlabSizeKb(),
1916                                nativeTotalPss);
1917                    }
1918                }
1919
1920                int i=0, num=0;
1921                long[] tmp = new long[1];
1922                do {
1923                    ProcessRecord proc;
1924                    int procState;
1925                    int pid;
1926                    synchronized (ActivityManagerService.this) {
1927                        if (i >= mPendingPssProcesses.size()) {
1928                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1929                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1930                            mPendingPssProcesses.clear();
1931                            return;
1932                        }
1933                        proc = mPendingPssProcesses.get(i);
1934                        procState = proc.pssProcState;
1935                        if (proc.thread != null && procState == proc.setProcState) {
1936                            pid = proc.pid;
1937                        } else {
1938                            proc = null;
1939                            pid = 0;
1940                        }
1941                        i++;
1942                    }
1943                    if (proc != null) {
1944                        long pss = Debug.getPss(pid, tmp);
1945                        synchronized (ActivityManagerService.this) {
1946                            if (proc.thread != null && proc.setProcState == procState
1947                                    && proc.pid == pid) {
1948                                num++;
1949                                proc.lastPssTime = SystemClock.uptimeMillis();
1950                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1951                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1952                                        + ": " + pss + " lastPss=" + proc.lastPss
1953                                        + " state=" + ProcessList.makeProcStateString(procState));
1954                                if (proc.initialIdlePss == 0) {
1955                                    proc.initialIdlePss = pss;
1956                                }
1957                                proc.lastPss = pss;
1958                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1959                                    proc.lastCachedPss = pss;
1960                                }
1961                            }
1962                        }
1963                    }
1964                } while (true);
1965            }
1966            }
1967        }
1968    };
1969
1970    /**
1971     * Monitor for package changes and update our internal state.
1972     */
1973    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1974        @Override
1975        public void onPackageRemoved(String packageName, int uid) {
1976            // Remove all tasks with activities in the specified package from the list of recent tasks
1977            synchronized (ActivityManagerService.this) {
1978                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1979                    TaskRecord tr = mRecentTasks.get(i);
1980                    ComponentName cn = tr.intent.getComponent();
1981                    if (cn != null && cn.getPackageName().equals(packageName)) {
1982                        // If the package name matches, remove the task and kill the process
1983                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1984                    }
1985                }
1986            }
1987        }
1988
1989        @Override
1990        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1991            onPackageModified(packageName);
1992            return true;
1993        }
1994
1995        @Override
1996        public void onPackageModified(String packageName) {
1997            final PackageManager pm = mContext.getPackageManager();
1998            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1999                    new ArrayList<Pair<Intent, Integer>>();
2000            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2001            // Copy the list of recent tasks so that we don't hold onto the lock on
2002            // ActivityManagerService for long periods while checking if components exist.
2003            synchronized (ActivityManagerService.this) {
2004                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2005                    TaskRecord tr = mRecentTasks.get(i);
2006                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2007                }
2008            }
2009            // Check the recent tasks and filter out all tasks with components that no longer exist.
2010            Intent tmpI = new Intent();
2011            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2012                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2013                ComponentName cn = p.first.getComponent();
2014                if (cn != null && cn.getPackageName().equals(packageName)) {
2015                    try {
2016                        // Add the task to the list to remove if the component no longer exists
2017                        tmpI.setComponent(cn);
2018                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2019                            tasksToRemove.add(p.second);
2020                        }
2021                    } catch (Exception e) {}
2022                }
2023            }
2024            // Prune all the tasks with removed components from the list of recent tasks
2025            synchronized (ActivityManagerService.this) {
2026                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2027                    // Remove the task but don't kill the process (since other components in that
2028                    // package may still be running and in the background)
2029                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2030                }
2031            }
2032        }
2033
2034        @Override
2035        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2036            // Force stop the specified packages
2037            if (packages != null) {
2038                for (String pkg : packages) {
2039                    synchronized (ActivityManagerService.this) {
2040                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2041                                "finished booting")) {
2042                            return true;
2043                        }
2044                    }
2045                }
2046            }
2047            return false;
2048        }
2049    };
2050
2051    public void setSystemProcess() {
2052        try {
2053            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2054            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2055            ServiceManager.addService("meminfo", new MemBinder(this));
2056            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2057            ServiceManager.addService("dbinfo", new DbBinder(this));
2058            if (MONITOR_CPU_USAGE) {
2059                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2060            }
2061            ServiceManager.addService("permission", new PermissionController(this));
2062
2063            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2064                    "android", STOCK_PM_FLAGS);
2065            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2066
2067            synchronized (this) {
2068                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2069                app.persistent = true;
2070                app.pid = MY_PID;
2071                app.maxAdj = ProcessList.SYSTEM_ADJ;
2072                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2073                mProcessNames.put(app.processName, app.uid, app);
2074                synchronized (mPidsSelfLocked) {
2075                    mPidsSelfLocked.put(app.pid, app);
2076                }
2077                updateLruProcessLocked(app, false, null);
2078                updateOomAdjLocked();
2079            }
2080        } catch (PackageManager.NameNotFoundException e) {
2081            throw new RuntimeException(
2082                    "Unable to find android system package", e);
2083        }
2084    }
2085
2086    public void setWindowManager(WindowManagerService wm) {
2087        mWindowManager = wm;
2088        mStackSupervisor.setWindowManager(wm);
2089    }
2090
2091    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2092        mUsageStatsService = usageStatsManager;
2093    }
2094
2095    public void startObservingNativeCrashes() {
2096        final NativeCrashListener ncl = new NativeCrashListener(this);
2097        ncl.start();
2098    }
2099
2100    public IAppOpsService getAppOpsService() {
2101        return mAppOpsService;
2102    }
2103
2104    static class MemBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        MemBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump meminfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2121        }
2122    }
2123
2124    static class GraphicsBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        GraphicsBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2141        }
2142    }
2143
2144    static class DbBinder extends Binder {
2145        ActivityManagerService mActivityManagerService;
2146        DbBinder(ActivityManagerService activityManagerService) {
2147            mActivityManagerService = activityManagerService;
2148        }
2149
2150        @Override
2151        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2152            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2153                    != PackageManager.PERMISSION_GRANTED) {
2154                pw.println("Permission Denial: can't dump dbinfo from from pid="
2155                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2156                        + " without permission " + android.Manifest.permission.DUMP);
2157                return;
2158            }
2159
2160            mActivityManagerService.dumpDbInfo(fd, pw, args);
2161        }
2162    }
2163
2164    static class CpuBinder extends Binder {
2165        ActivityManagerService mActivityManagerService;
2166        CpuBinder(ActivityManagerService activityManagerService) {
2167            mActivityManagerService = activityManagerService;
2168        }
2169
2170        @Override
2171        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2172            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2173                    != PackageManager.PERMISSION_GRANTED) {
2174                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2175                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2176                        + " without permission " + android.Manifest.permission.DUMP);
2177                return;
2178            }
2179
2180            synchronized (mActivityManagerService.mProcessCpuThread) {
2181                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2182                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2183                        SystemClock.uptimeMillis()));
2184            }
2185        }
2186    }
2187
2188    public static final class Lifecycle extends SystemService {
2189        private final ActivityManagerService mService;
2190
2191        public Lifecycle(Context context) {
2192            super(context);
2193            mService = new ActivityManagerService(context);
2194        }
2195
2196        @Override
2197        public void onStart() {
2198            mService.start();
2199        }
2200
2201        public ActivityManagerService getService() {
2202            return mService;
2203        }
2204    }
2205
2206    // Note: This method is invoked on the main thread but may need to attach various
2207    // handlers to other threads.  So take care to be explicit about the looper.
2208    public ActivityManagerService(Context systemContext) {
2209        mContext = systemContext;
2210        mFactoryTest = FactoryTest.getMode();
2211        mSystemThread = ActivityThread.currentActivityThread();
2212
2213        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2214
2215        mHandlerThread = new ServiceThread(TAG,
2216                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2217        mHandlerThread.start();
2218        mHandler = new MainHandler(mHandlerThread.getLooper());
2219
2220        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2221                "foreground", BROADCAST_FG_TIMEOUT, false);
2222        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2223                "background", BROADCAST_BG_TIMEOUT, true);
2224        mBroadcastQueues[0] = mFgBroadcastQueue;
2225        mBroadcastQueues[1] = mBgBroadcastQueue;
2226
2227        mServices = new ActiveServices(this);
2228        mProviderMap = new ProviderMap(this);
2229
2230        // TODO: Move creation of battery stats service outside of activity manager service.
2231        File dataDir = Environment.getDataDirectory();
2232        File systemDir = new File(dataDir, "system");
2233        systemDir.mkdirs();
2234        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2235        mBatteryStatsService.getActiveStatistics().readLocked();
2236        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2237        mOnBattery = DEBUG_POWER ? true
2238                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2239        mBatteryStatsService.getActiveStatistics().setCallback(this);
2240
2241        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2242
2243        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2244
2245        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2246
2247        // User 0 is the first and only user that runs at boot.
2248        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2249        mUserLru.add(Integer.valueOf(0));
2250        updateStartedUserArrayLocked();
2251
2252        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2253            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2254
2255        mConfiguration.setToDefaults();
2256        mConfiguration.setLocale(Locale.getDefault());
2257
2258        mConfigurationSeq = mConfiguration.seq = 1;
2259        mProcessCpuTracker.init();
2260
2261        final Resources res = mContext.getResources();
2262        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2263        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2264        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2265
2266        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2267        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2268        mStackSupervisor = new ActivityStackSupervisor(this);
2269        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2270
2271        mProcessCpuThread = new Thread("CpuTracker") {
2272            @Override
2273            public void run() {
2274                while (true) {
2275                    try {
2276                        try {
2277                            synchronized(this) {
2278                                final long now = SystemClock.uptimeMillis();
2279                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2280                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2281                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2282                                //        + ", write delay=" + nextWriteDelay);
2283                                if (nextWriteDelay < nextCpuDelay) {
2284                                    nextCpuDelay = nextWriteDelay;
2285                                }
2286                                if (nextCpuDelay > 0) {
2287                                    mProcessCpuMutexFree.set(true);
2288                                    this.wait(nextCpuDelay);
2289                                }
2290                            }
2291                        } catch (InterruptedException e) {
2292                        }
2293                        updateCpuStatsNow();
2294                    } catch (Exception e) {
2295                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2296                    }
2297                }
2298            }
2299        };
2300
2301        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2302
2303        Watchdog.getInstance().addMonitor(this);
2304        Watchdog.getInstance().addThread(mHandler);
2305    }
2306
2307    public void setSystemServiceManager(SystemServiceManager mgr) {
2308        mSystemServiceManager = mgr;
2309    }
2310
2311    private void start() {
2312        Process.removeAllProcessGroups();
2313        mProcessCpuThread.start();
2314
2315        mBatteryStatsService.publish(mContext);
2316        mAppOpsService.publish(mContext);
2317        Slog.d("AppOps", "AppOpsService published");
2318        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2319    }
2320
2321    public void initPowerManagement() {
2322        mStackSupervisor.initPowerManagement();
2323        mBatteryStatsService.initPowerManagement();
2324    }
2325
2326    @Override
2327    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2328            throws RemoteException {
2329        if (code == SYSPROPS_TRANSACTION) {
2330            // We need to tell all apps about the system property change.
2331            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2332            synchronized(this) {
2333                final int NP = mProcessNames.getMap().size();
2334                for (int ip=0; ip<NP; ip++) {
2335                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2336                    final int NA = apps.size();
2337                    for (int ia=0; ia<NA; ia++) {
2338                        ProcessRecord app = apps.valueAt(ia);
2339                        if (app.thread != null) {
2340                            procs.add(app.thread.asBinder());
2341                        }
2342                    }
2343                }
2344            }
2345
2346            int N = procs.size();
2347            for (int i=0; i<N; i++) {
2348                Parcel data2 = Parcel.obtain();
2349                try {
2350                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2351                } catch (RemoteException e) {
2352                }
2353                data2.recycle();
2354            }
2355        }
2356        try {
2357            return super.onTransact(code, data, reply, flags);
2358        } catch (RuntimeException e) {
2359            // The activity manager only throws security exceptions, so let's
2360            // log all others.
2361            if (!(e instanceof SecurityException)) {
2362                Slog.wtf(TAG, "Activity Manager Crash", e);
2363            }
2364            throw e;
2365        }
2366    }
2367
2368    void updateCpuStats() {
2369        final long now = SystemClock.uptimeMillis();
2370        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2371            return;
2372        }
2373        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2374            synchronized (mProcessCpuThread) {
2375                mProcessCpuThread.notify();
2376            }
2377        }
2378    }
2379
2380    void updateCpuStatsNow() {
2381        synchronized (mProcessCpuThread) {
2382            mProcessCpuMutexFree.set(false);
2383            final long now = SystemClock.uptimeMillis();
2384            boolean haveNewCpuStats = false;
2385
2386            if (MONITOR_CPU_USAGE &&
2387                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2388                mLastCpuTime.set(now);
2389                haveNewCpuStats = true;
2390                mProcessCpuTracker.update();
2391                //Slog.i(TAG, mProcessCpu.printCurrentState());
2392                //Slog.i(TAG, "Total CPU usage: "
2393                //        + mProcessCpu.getTotalCpuPercent() + "%");
2394
2395                // Slog the cpu usage if the property is set.
2396                if ("true".equals(SystemProperties.get("events.cpu"))) {
2397                    int user = mProcessCpuTracker.getLastUserTime();
2398                    int system = mProcessCpuTracker.getLastSystemTime();
2399                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2400                    int irq = mProcessCpuTracker.getLastIrqTime();
2401                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2402                    int idle = mProcessCpuTracker.getLastIdleTime();
2403
2404                    int total = user + system + iowait + irq + softIrq + idle;
2405                    if (total == 0) total = 1;
2406
2407                    EventLog.writeEvent(EventLogTags.CPU,
2408                            ((user+system+iowait+irq+softIrq) * 100) / total,
2409                            (user * 100) / total,
2410                            (system * 100) / total,
2411                            (iowait * 100) / total,
2412                            (irq * 100) / total,
2413                            (softIrq * 100) / total);
2414                }
2415            }
2416
2417            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2418            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2419            synchronized(bstats) {
2420                synchronized(mPidsSelfLocked) {
2421                    if (haveNewCpuStats) {
2422                        if (mOnBattery) {
2423                            int perc = bstats.startAddingCpuLocked();
2424                            int totalUTime = 0;
2425                            int totalSTime = 0;
2426                            final int N = mProcessCpuTracker.countStats();
2427                            for (int i=0; i<N; i++) {
2428                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2429                                if (!st.working) {
2430                                    continue;
2431                                }
2432                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2433                                int otherUTime = (st.rel_utime*perc)/100;
2434                                int otherSTime = (st.rel_stime*perc)/100;
2435                                totalUTime += otherUTime;
2436                                totalSTime += otherSTime;
2437                                if (pr != null) {
2438                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2439                                    if (ps == null || !ps.isActive()) {
2440                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2441                                                pr.info.uid, pr.processName);
2442                                    }
2443                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2444                                            st.rel_stime-otherSTime);
2445                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2446                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2447                                } else {
2448                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2449                                    if (ps == null || !ps.isActive()) {
2450                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2451                                                bstats.mapUid(st.uid), st.name);
2452                                    }
2453                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2454                                            st.rel_stime-otherSTime);
2455                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2456                                }
2457                            }
2458                            bstats.finishAddingCpuLocked(perc, totalUTime,
2459                                    totalSTime, cpuSpeedTimes);
2460                        }
2461                    }
2462                }
2463
2464                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2465                    mLastWriteTime = now;
2466                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void batteryNeedsCpuUpdate() {
2474        updateCpuStatsNow();
2475    }
2476
2477    @Override
2478    public void batteryPowerChanged(boolean onBattery) {
2479        // When plugging in, update the CPU stats first before changing
2480        // the plug state.
2481        updateCpuStatsNow();
2482        synchronized (this) {
2483            synchronized(mPidsSelfLocked) {
2484                mOnBattery = DEBUG_POWER ? true : onBattery;
2485            }
2486        }
2487    }
2488
2489    /**
2490     * Initialize the application bind args. These are passed to each
2491     * process when the bindApplication() IPC is sent to the process. They're
2492     * lazily setup to make sure the services are running when they're asked for.
2493     */
2494    private HashMap<String, IBinder> getCommonServicesLocked() {
2495        if (mAppBindArgs == null) {
2496            mAppBindArgs = new HashMap<String, IBinder>();
2497
2498            // Setup the application init args
2499            mAppBindArgs.put("package", ServiceManager.getService("package"));
2500            mAppBindArgs.put("window", ServiceManager.getService("window"));
2501            mAppBindArgs.put(Context.ALARM_SERVICE,
2502                    ServiceManager.getService(Context.ALARM_SERVICE));
2503        }
2504        return mAppBindArgs;
2505    }
2506
2507    final void setFocusedActivityLocked(ActivityRecord r) {
2508        if (mFocusedActivity != r) {
2509            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2510            mFocusedActivity = r;
2511            if (r.task != null && r.task.voiceInteractor != null) {
2512                startRunningVoiceLocked();
2513            } else {
2514                finishRunningVoiceLocked();
2515            }
2516            mStackSupervisor.setFocusedStack(r);
2517            if (r != null) {
2518                mWindowManager.setFocusedApp(r.appToken, true);
2519            }
2520            applyUpdateLockStateLocked(r);
2521        }
2522    }
2523
2524    final void clearFocusedActivity(ActivityRecord r) {
2525        if (mFocusedActivity == r) {
2526            mFocusedActivity = null;
2527        }
2528    }
2529
2530    @Override
2531    public void setFocusedStack(int stackId) {
2532        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2533        synchronized (ActivityManagerService.this) {
2534            ActivityStack stack = mStackSupervisor.getStack(stackId);
2535            if (stack != null) {
2536                ActivityRecord r = stack.topRunningActivityLocked(null);
2537                if (r != null) {
2538                    setFocusedActivityLocked(r);
2539                }
2540            }
2541        }
2542    }
2543
2544    @Override
2545    public void notifyActivityDrawn(IBinder token) {
2546        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2547        synchronized (this) {
2548            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2549            if (r != null) {
2550                r.task.stack.notifyActivityDrawnLocked(r);
2551            }
2552        }
2553    }
2554
2555    final void applyUpdateLockStateLocked(ActivityRecord r) {
2556        // Modifications to the UpdateLock state are done on our handler, outside
2557        // the activity manager's locks.  The new state is determined based on the
2558        // state *now* of the relevant activity record.  The object is passed to
2559        // the handler solely for logging detail, not to be consulted/modified.
2560        final boolean nextState = r != null && r.immersive;
2561        mHandler.sendMessage(
2562                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2563    }
2564
2565    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2566        Message msg = Message.obtain();
2567        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2568        msg.obj = r.task.askedCompatMode ? null : r;
2569        mHandler.sendMessage(msg);
2570    }
2571
2572    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2573            String what, Object obj, ProcessRecord srcApp) {
2574        app.lastActivityTime = now;
2575
2576        if (app.activities.size() > 0) {
2577            // Don't want to touch dependent processes that are hosting activities.
2578            return index;
2579        }
2580
2581        int lrui = mLruProcesses.lastIndexOf(app);
2582        if (lrui < 0) {
2583            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2584                    + what + " " + obj + " from " + srcApp);
2585            return index;
2586        }
2587
2588        if (lrui >= index) {
2589            // Don't want to cause this to move dependent processes *back* in the
2590            // list as if they were less frequently used.
2591            return index;
2592        }
2593
2594        if (lrui >= mLruProcessActivityStart) {
2595            // Don't want to touch dependent processes that are hosting activities.
2596            return index;
2597        }
2598
2599        mLruProcesses.remove(lrui);
2600        if (index > 0) {
2601            index--;
2602        }
2603        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2604                + " in LRU list: " + app);
2605        mLruProcesses.add(index, app);
2606        return index;
2607    }
2608
2609    final void removeLruProcessLocked(ProcessRecord app) {
2610        int lrui = mLruProcesses.lastIndexOf(app);
2611        if (lrui >= 0) {
2612            if (lrui <= mLruProcessActivityStart) {
2613                mLruProcessActivityStart--;
2614            }
2615            if (lrui <= mLruProcessServiceStart) {
2616                mLruProcessServiceStart--;
2617            }
2618            mLruProcesses.remove(lrui);
2619        }
2620    }
2621
2622    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2623            ProcessRecord client) {
2624        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2625                || app.treatLikeActivity;
2626        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2627        if (!activityChange && hasActivity) {
2628            // The process has activities, so we are only allowing activity-based adjustments
2629            // to move it.  It should be kept in the front of the list with other
2630            // processes that have activities, and we don't want those to change their
2631            // order except due to activity operations.
2632            return;
2633        }
2634
2635        mLruSeq++;
2636        final long now = SystemClock.uptimeMillis();
2637        app.lastActivityTime = now;
2638
2639        // First a quick reject: if the app is already at the position we will
2640        // put it, then there is nothing to do.
2641        if (hasActivity) {
2642            final int N = mLruProcesses.size();
2643            if (N > 0 && mLruProcesses.get(N-1) == app) {
2644                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2645                return;
2646            }
2647        } else {
2648            if (mLruProcessServiceStart > 0
2649                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2650                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2651                return;
2652            }
2653        }
2654
2655        int lrui = mLruProcesses.lastIndexOf(app);
2656
2657        if (app.persistent && lrui >= 0) {
2658            // We don't care about the position of persistent processes, as long as
2659            // they are in the list.
2660            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2661            return;
2662        }
2663
2664        /* In progress: compute new position first, so we can avoid doing work
2665           if the process is not actually going to move.  Not yet working.
2666        int addIndex;
2667        int nextIndex;
2668        boolean inActivity = false, inService = false;
2669        if (hasActivity) {
2670            // Process has activities, put it at the very tipsy-top.
2671            addIndex = mLruProcesses.size();
2672            nextIndex = mLruProcessServiceStart;
2673            inActivity = true;
2674        } else if (hasService) {
2675            // Process has services, put it at the top of the service list.
2676            addIndex = mLruProcessActivityStart;
2677            nextIndex = mLruProcessServiceStart;
2678            inActivity = true;
2679            inService = true;
2680        } else  {
2681            // Process not otherwise of interest, it goes to the top of the non-service area.
2682            addIndex = mLruProcessServiceStart;
2683            if (client != null) {
2684                int clientIndex = mLruProcesses.lastIndexOf(client);
2685                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2686                        + app);
2687                if (clientIndex >= 0 && addIndex > clientIndex) {
2688                    addIndex = clientIndex;
2689                }
2690            }
2691            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2692        }
2693
2694        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2695                + mLruProcessActivityStart + "): " + app);
2696        */
2697
2698        if (lrui >= 0) {
2699            if (lrui < mLruProcessActivityStart) {
2700                mLruProcessActivityStart--;
2701            }
2702            if (lrui < mLruProcessServiceStart) {
2703                mLruProcessServiceStart--;
2704            }
2705            /*
2706            if (addIndex > lrui) {
2707                addIndex--;
2708            }
2709            if (nextIndex > lrui) {
2710                nextIndex--;
2711            }
2712            */
2713            mLruProcesses.remove(lrui);
2714        }
2715
2716        /*
2717        mLruProcesses.add(addIndex, app);
2718        if (inActivity) {
2719            mLruProcessActivityStart++;
2720        }
2721        if (inService) {
2722            mLruProcessActivityStart++;
2723        }
2724        */
2725
2726        int nextIndex;
2727        if (hasActivity) {
2728            final int N = mLruProcesses.size();
2729            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2730                // Process doesn't have activities, but has clients with
2731                // activities...  move it up, but one below the top (the top
2732                // should always have a real activity).
2733                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2734                mLruProcesses.add(N-1, app);
2735                // To keep it from spamming the LRU list (by making a bunch of clients),
2736                // we will push down any other entries owned by the app.
2737                final int uid = app.info.uid;
2738                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2739                    ProcessRecord subProc = mLruProcesses.get(i);
2740                    if (subProc.info.uid == uid) {
2741                        // We want to push this one down the list.  If the process after
2742                        // it is for the same uid, however, don't do so, because we don't
2743                        // want them internally to be re-ordered.
2744                        if (mLruProcesses.get(i-1).info.uid != uid) {
2745                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2746                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2747                            ProcessRecord tmp = mLruProcesses.get(i);
2748                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2749                            mLruProcesses.set(i-1, tmp);
2750                            i--;
2751                        }
2752                    } else {
2753                        // A gap, we can stop here.
2754                        break;
2755                    }
2756                }
2757            } else {
2758                // Process has activities, put it at the very tipsy-top.
2759                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2760                mLruProcesses.add(app);
2761            }
2762            nextIndex = mLruProcessServiceStart;
2763        } else if (hasService) {
2764            // Process has services, put it at the top of the service list.
2765            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2766            mLruProcesses.add(mLruProcessActivityStart, app);
2767            nextIndex = mLruProcessServiceStart;
2768            mLruProcessActivityStart++;
2769        } else  {
2770            // Process not otherwise of interest, it goes to the top of the non-service area.
2771            int index = mLruProcessServiceStart;
2772            if (client != null) {
2773                // If there is a client, don't allow the process to be moved up higher
2774                // in the list than that client.
2775                int clientIndex = mLruProcesses.lastIndexOf(client);
2776                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2777                        + " when updating " + app);
2778                if (clientIndex <= lrui) {
2779                    // Don't allow the client index restriction to push it down farther in the
2780                    // list than it already is.
2781                    clientIndex = lrui;
2782                }
2783                if (clientIndex >= 0 && index > clientIndex) {
2784                    index = clientIndex;
2785                }
2786            }
2787            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2788            mLruProcesses.add(index, app);
2789            nextIndex = index-1;
2790            mLruProcessActivityStart++;
2791            mLruProcessServiceStart++;
2792        }
2793
2794        // If the app is currently using a content provider or service,
2795        // bump those processes as well.
2796        for (int j=app.connections.size()-1; j>=0; j--) {
2797            ConnectionRecord cr = app.connections.valueAt(j);
2798            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2799                    && cr.binding.service.app != null
2800                    && cr.binding.service.app.lruSeq != mLruSeq
2801                    && !cr.binding.service.app.persistent) {
2802                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2803                        "service connection", cr, app);
2804            }
2805        }
2806        for (int j=app.conProviders.size()-1; j>=0; j--) {
2807            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2808            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2809                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2810                        "provider reference", cpr, app);
2811            }
2812        }
2813    }
2814
2815    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2816        if (uid == Process.SYSTEM_UID) {
2817            // The system gets to run in any process.  If there are multiple
2818            // processes with the same uid, just pick the first (this
2819            // should never happen).
2820            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2821            if (procs == null) return null;
2822            final int N = procs.size();
2823            for (int i = 0; i < N; i++) {
2824                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2825            }
2826        }
2827        ProcessRecord proc = mProcessNames.get(processName, uid);
2828        if (false && proc != null && !keepIfLarge
2829                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2830                && proc.lastCachedPss >= 4000) {
2831            // Turn this condition on to cause killing to happen regularly, for testing.
2832            if (proc.baseProcessTracker != null) {
2833                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2834            }
2835            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2836        } else if (proc != null && !keepIfLarge
2837                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2838                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2839            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2840            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2841                if (proc.baseProcessTracker != null) {
2842                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2843                }
2844                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2845            }
2846        }
2847        return proc;
2848    }
2849
2850    void ensurePackageDexOpt(String packageName) {
2851        IPackageManager pm = AppGlobals.getPackageManager();
2852        try {
2853            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2854                mDidDexOpt = true;
2855            }
2856        } catch (RemoteException e) {
2857        }
2858    }
2859
2860    boolean isNextTransitionForward() {
2861        int transit = mWindowManager.getPendingAppTransition();
2862        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2863                || transit == AppTransition.TRANSIT_TASK_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2865    }
2866
2867    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2868            String processName, String abiOverride, int uid, Runnable crashHandler) {
2869        synchronized(this) {
2870            ApplicationInfo info = new ApplicationInfo();
2871            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2872            // For isolated processes, the former contains the parent's uid and the latter the
2873            // actual uid of the isolated process.
2874            // In the special case introduced by this method (which is, starting an isolated
2875            // process directly from the SystemServer without an actual parent app process) the
2876            // closest thing to a parent's uid is SYSTEM_UID.
2877            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2878            // the |isolated| logic in the ProcessRecord constructor.
2879            info.uid = Process.SYSTEM_UID;
2880            info.processName = processName;
2881            info.className = entryPoint;
2882            info.packageName = "android";
2883            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2884                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2885                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2886                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2887                    crashHandler);
2888            return proc != null ? proc.pid : 0;
2889        }
2890    }
2891
2892    final ProcessRecord startProcessLocked(String processName,
2893            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2894            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2895            boolean isolated, boolean keepIfLarge) {
2896        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2897                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2898                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2899                null /* crashHandler */);
2900    }
2901
2902    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2903            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2904            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2905            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2906        ProcessRecord app;
2907        if (!isolated) {
2908            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2909        } else {
2910            // If this is an isolated process, it can't re-use an existing process.
2911            app = null;
2912        }
2913        // We don't have to do anything more if:
2914        // (1) There is an existing application record; and
2915        // (2) The caller doesn't think it is dead, OR there is no thread
2916        //     object attached to it so we know it couldn't have crashed; and
2917        // (3) There is a pid assigned to it, so it is either starting or
2918        //     already running.
2919        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2920                + " app=" + app + " knownToBeDead=" + knownToBeDead
2921                + " thread=" + (app != null ? app.thread : null)
2922                + " pid=" + (app != null ? app.pid : -1));
2923        if (app != null && app.pid > 0) {
2924            if (!knownToBeDead || app.thread == null) {
2925                // We already have the app running, or are waiting for it to
2926                // come up (we have a pid but not yet its thread), so keep it.
2927                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2928                // If this is a new package in the process, add the package to the list
2929                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2930                return app;
2931            }
2932
2933            // An application record is attached to a previous process,
2934            // clean it up now.
2935            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2936            Process.killProcessGroup(app.info.uid, app.pid);
2937            handleAppDiedLocked(app, true, true);
2938        }
2939
2940        String hostingNameStr = hostingName != null
2941                ? hostingName.flattenToShortString() : null;
2942
2943        if (!isolated) {
2944            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2945                // If we are in the background, then check to see if this process
2946                // is bad.  If so, we will just silently fail.
2947                if (mBadProcesses.get(info.processName, info.uid) != null) {
2948                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2949                            + "/" + info.processName);
2950                    return null;
2951                }
2952            } else {
2953                // When the user is explicitly starting a process, then clear its
2954                // crash count so that we won't make it bad until they see at
2955                // least one crash dialog again, and make the process good again
2956                // if it had been bad.
2957                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2958                        + "/" + info.processName);
2959                mProcessCrashTimes.remove(info.processName, info.uid);
2960                if (mBadProcesses.get(info.processName, info.uid) != null) {
2961                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2962                            UserHandle.getUserId(info.uid), info.uid,
2963                            info.processName);
2964                    mBadProcesses.remove(info.processName, info.uid);
2965                    if (app != null) {
2966                        app.bad = false;
2967                    }
2968                }
2969            }
2970        }
2971
2972        if (app == null) {
2973            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2974            app.crashHandler = crashHandler;
2975            if (app == null) {
2976                Slog.w(TAG, "Failed making new process record for "
2977                        + processName + "/" + info.uid + " isolated=" + isolated);
2978                return null;
2979            }
2980            mProcessNames.put(processName, app.uid, app);
2981            if (isolated) {
2982                mIsolatedProcesses.put(app.uid, app);
2983            }
2984        } else {
2985            // If this is a new package in the process, add the package to the list
2986            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2987        }
2988
2989        // If the system is not ready yet, then hold off on starting this
2990        // process until it is.
2991        if (!mProcessesReady
2992                && !isAllowedWhileBooting(info)
2993                && !allowWhileBooting) {
2994            if (!mProcessesOnHold.contains(app)) {
2995                mProcessesOnHold.add(app);
2996            }
2997            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2998            return app;
2999        }
3000
3001        startProcessLocked(
3002                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3003        return (app.pid != 0) ? app : null;
3004    }
3005
3006    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3007        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3008    }
3009
3010    private final void startProcessLocked(ProcessRecord app,
3011            String hostingType, String hostingNameStr) {
3012        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3013                null /* entryPoint */, null /* entryPointArgs */);
3014    }
3015
3016    private final void startProcessLocked(ProcessRecord app, String hostingType,
3017            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3018        if (app.pid > 0 && app.pid != MY_PID) {
3019            synchronized (mPidsSelfLocked) {
3020                mPidsSelfLocked.remove(app.pid);
3021                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3022            }
3023            app.setPid(0);
3024        }
3025
3026        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3027                "startProcessLocked removing on hold: " + app);
3028        mProcessesOnHold.remove(app);
3029
3030        updateCpuStats();
3031
3032        try {
3033            int uid = app.uid;
3034
3035            int[] gids = null;
3036            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3037            if (!app.isolated) {
3038                int[] permGids = null;
3039                try {
3040                    final PackageManager pm = mContext.getPackageManager();
3041                    permGids = pm.getPackageGids(app.info.packageName);
3042
3043                    if (Environment.isExternalStorageEmulated()) {
3044                        if (pm.checkPermission(
3045                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3046                                app.info.packageName) == PERMISSION_GRANTED) {
3047                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3048                        } else {
3049                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3050                        }
3051                    }
3052                } catch (PackageManager.NameNotFoundException e) {
3053                    Slog.w(TAG, "Unable to retrieve gids", e);
3054                }
3055
3056                /*
3057                 * Add shared application and profile GIDs so applications can share some
3058                 * resources like shared libraries and access user-wide resources
3059                 */
3060                if (permGids == null) {
3061                    gids = new int[2];
3062                } else {
3063                    gids = new int[permGids.length + 2];
3064                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3065                }
3066                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3067                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3068            }
3069            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3070                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3071                        && mTopComponent != null
3072                        && app.processName.equals(mTopComponent.getPackageName())) {
3073                    uid = 0;
3074                }
3075                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3076                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3077                    uid = 0;
3078                }
3079            }
3080            int debugFlags = 0;
3081            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3082                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3083                // Also turn on CheckJNI for debuggable apps. It's quite
3084                // awkward to turn on otherwise.
3085                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3086            }
3087            // Run the app in safe mode if its manifest requests so or the
3088            // system is booted in safe mode.
3089            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3090                mSafeMode == true) {
3091                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3092            }
3093            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3094                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3095            }
3096            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3097                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3098            }
3099            if ("1".equals(SystemProperties.get("debug.assert"))) {
3100                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3101            }
3102
3103            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3104            if (requiredAbi == null) {
3105                requiredAbi = Build.SUPPORTED_ABIS[0];
3106            }
3107
3108            // Start the process.  It will either succeed and return a result containing
3109            // the PID of the new process, or else throw a RuntimeException.
3110            boolean isActivityProcess = (entryPoint == null);
3111            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3112            Process.ProcessStartResult startResult = Process.start(entryPoint,
3113                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3114                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3115
3116            if (app.isolated) {
3117                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3118            }
3119            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3120
3121            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3122                    UserHandle.getUserId(uid), startResult.pid, uid,
3123                    app.processName, hostingType,
3124                    hostingNameStr != null ? hostingNameStr : "");
3125
3126            if (app.persistent) {
3127                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3128            }
3129
3130            StringBuilder buf = mStringBuilder;
3131            buf.setLength(0);
3132            buf.append("Start proc ");
3133            buf.append(app.processName);
3134            if (!isActivityProcess) {
3135                buf.append(" [");
3136                buf.append(entryPoint);
3137                buf.append("]");
3138            }
3139            buf.append(" for ");
3140            buf.append(hostingType);
3141            if (hostingNameStr != null) {
3142                buf.append(" ");
3143                buf.append(hostingNameStr);
3144            }
3145            buf.append(": pid=");
3146            buf.append(startResult.pid);
3147            buf.append(" uid=");
3148            buf.append(uid);
3149            buf.append(" gids={");
3150            if (gids != null) {
3151                for (int gi=0; gi<gids.length; gi++) {
3152                    if (gi != 0) buf.append(", ");
3153                    buf.append(gids[gi]);
3154
3155                }
3156            }
3157            buf.append("}");
3158            if (requiredAbi != null) {
3159                buf.append(" abi=");
3160                buf.append(requiredAbi);
3161            }
3162            Slog.i(TAG, buf.toString());
3163            app.setPid(startResult.pid);
3164            app.usingWrapper = startResult.usingWrapper;
3165            app.removed = false;
3166            app.killedByAm = false;
3167            synchronized (mPidsSelfLocked) {
3168                this.mPidsSelfLocked.put(startResult.pid, app);
3169                if (isActivityProcess) {
3170                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3171                    msg.obj = app;
3172                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3173                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3174                }
3175            }
3176        } catch (RuntimeException e) {
3177            // XXX do better error recovery.
3178            app.setPid(0);
3179            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3180            if (app.isolated) {
3181                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3182            }
3183            Slog.e(TAG, "Failure starting process " + app.processName, e);
3184        }
3185    }
3186
3187    void updateUsageStats(ActivityRecord component, boolean resumed) {
3188        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3189        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3190        if (resumed) {
3191            if (mUsageStatsService != null) {
3192                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3193                        System.currentTimeMillis(),
3194                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3195            }
3196            synchronized (stats) {
3197                stats.noteActivityResumedLocked(component.app.uid);
3198            }
3199        } else {
3200            if (mUsageStatsService != null) {
3201                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3202                        System.currentTimeMillis(),
3203                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3204            }
3205            synchronized (stats) {
3206                stats.noteActivityPausedLocked(component.app.uid);
3207            }
3208        }
3209    }
3210
3211    Intent getHomeIntent() {
3212        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3213        intent.setComponent(mTopComponent);
3214        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3215            intent.addCategory(Intent.CATEGORY_HOME);
3216        }
3217        return intent;
3218    }
3219
3220    boolean startHomeActivityLocked(int userId) {
3221        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3222                && mTopAction == null) {
3223            // We are running in factory test mode, but unable to find
3224            // the factory test app, so just sit around displaying the
3225            // error message and don't try to start anything.
3226            return false;
3227        }
3228        Intent intent = getHomeIntent();
3229        ActivityInfo aInfo =
3230            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3231        if (aInfo != null) {
3232            intent.setComponent(new ComponentName(
3233                    aInfo.applicationInfo.packageName, aInfo.name));
3234            // Don't do this if the home app is currently being
3235            // instrumented.
3236            aInfo = new ActivityInfo(aInfo);
3237            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3238            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3239                    aInfo.applicationInfo.uid, true);
3240            if (app == null || app.instrumentationClass == null) {
3241                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3242                mStackSupervisor.startHomeActivity(intent, aInfo);
3243            }
3244        }
3245
3246        return true;
3247    }
3248
3249    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3250        ActivityInfo ai = null;
3251        ComponentName comp = intent.getComponent();
3252        try {
3253            if (comp != null) {
3254                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3255            } else {
3256                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3257                        intent,
3258                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3259                            flags, userId);
3260
3261                if (info != null) {
3262                    ai = info.activityInfo;
3263                }
3264            }
3265        } catch (RemoteException e) {
3266            // ignore
3267        }
3268
3269        return ai;
3270    }
3271
3272    /**
3273     * Starts the "new version setup screen" if appropriate.
3274     */
3275    void startSetupActivityLocked() {
3276        // Only do this once per boot.
3277        if (mCheckedForSetup) {
3278            return;
3279        }
3280
3281        // We will show this screen if the current one is a different
3282        // version than the last one shown, and we are not running in
3283        // low-level factory test mode.
3284        final ContentResolver resolver = mContext.getContentResolver();
3285        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3286                Settings.Global.getInt(resolver,
3287                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3288            mCheckedForSetup = true;
3289
3290            // See if we should be showing the platform update setup UI.
3291            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3292            List<ResolveInfo> ris = mContext.getPackageManager()
3293                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3294
3295            // We don't allow third party apps to replace this.
3296            ResolveInfo ri = null;
3297            for (int i=0; ris != null && i<ris.size(); i++) {
3298                if ((ris.get(i).activityInfo.applicationInfo.flags
3299                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3300                    ri = ris.get(i);
3301                    break;
3302                }
3303            }
3304
3305            if (ri != null) {
3306                String vers = ri.activityInfo.metaData != null
3307                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3308                        : null;
3309                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3310                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3311                            Intent.METADATA_SETUP_VERSION);
3312                }
3313                String lastVers = Settings.Secure.getString(
3314                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3315                if (vers != null && !vers.equals(lastVers)) {
3316                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3317                    intent.setComponent(new ComponentName(
3318                            ri.activityInfo.packageName, ri.activityInfo.name));
3319                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3320                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3321                            null);
3322                }
3323            }
3324        }
3325    }
3326
3327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3329    }
3330
3331    void enforceNotIsolatedCaller(String caller) {
3332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3333            throw new SecurityException("Isolated process not allowed to call " + caller);
3334        }
3335    }
3336
3337    @Override
3338    public int getFrontActivityScreenCompatMode() {
3339        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3340        synchronized (this) {
3341            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3342        }
3343    }
3344
3345    @Override
3346    public void setFrontActivityScreenCompatMode(int mode) {
3347        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3348                "setFrontActivityScreenCompatMode");
3349        synchronized (this) {
3350            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3351        }
3352    }
3353
3354    @Override
3355    public int getPackageScreenCompatMode(String packageName) {
3356        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3357        synchronized (this) {
3358            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3359        }
3360    }
3361
3362    @Override
3363    public void setPackageScreenCompatMode(String packageName, int mode) {
3364        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3365                "setPackageScreenCompatMode");
3366        synchronized (this) {
3367            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3368        }
3369    }
3370
3371    @Override
3372    public boolean getPackageAskScreenCompat(String packageName) {
3373        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3374        synchronized (this) {
3375            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3376        }
3377    }
3378
3379    @Override
3380    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3381        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3382                "setPackageAskScreenCompat");
3383        synchronized (this) {
3384            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3385        }
3386    }
3387
3388    private void dispatchProcessesChanged() {
3389        int N;
3390        synchronized (this) {
3391            N = mPendingProcessChanges.size();
3392            if (mActiveProcessChanges.length < N) {
3393                mActiveProcessChanges = new ProcessChangeItem[N];
3394            }
3395            mPendingProcessChanges.toArray(mActiveProcessChanges);
3396            mAvailProcessChanges.addAll(mPendingProcessChanges);
3397            mPendingProcessChanges.clear();
3398            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3399        }
3400
3401        int i = mProcessObservers.beginBroadcast();
3402        while (i > 0) {
3403            i--;
3404            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3405            if (observer != null) {
3406                try {
3407                    for (int j=0; j<N; j++) {
3408                        ProcessChangeItem item = mActiveProcessChanges[j];
3409                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3410                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3411                                    + item.pid + " uid=" + item.uid + ": "
3412                                    + item.foregroundActivities);
3413                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3414                                    item.foregroundActivities);
3415                        }
3416                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3417                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3418                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3419                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3420                        }
3421                    }
3422                } catch (RemoteException e) {
3423                }
3424            }
3425        }
3426        mProcessObservers.finishBroadcast();
3427    }
3428
3429    private void dispatchProcessDied(int pid, int uid) {
3430        int i = mProcessObservers.beginBroadcast();
3431        while (i > 0) {
3432            i--;
3433            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3434            if (observer != null) {
3435                try {
3436                    observer.onProcessDied(pid, uid);
3437                } catch (RemoteException e) {
3438                }
3439            }
3440        }
3441        mProcessObservers.finishBroadcast();
3442    }
3443
3444    @Override
3445    public final int startActivity(IApplicationThread caller, String callingPackage,
3446            Intent intent, String resolvedType, IBinder resultTo,
3447            String resultWho, int requestCode, int startFlags,
3448            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3449        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3450                resultWho, requestCode,
3451                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3452    }
3453
3454    @Override
3455    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3456            Intent intent, String resolvedType, IBinder resultTo,
3457            String resultWho, int requestCode, int startFlags,
3458            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3459        enforceNotIsolatedCaller("startActivity");
3460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3461                false, ALLOW_FULL_ONLY, "startActivity", null);
3462        // TODO: Switch to user app stacks here.
3463        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3464                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3465                null, null, options, userId, null, null);
3466    }
3467
3468    @Override
3469    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3470            Intent intent, String resolvedType, IBinder resultTo,
3471            String resultWho, int requestCode, int startFlags,
3472            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3473
3474        // This is very dangerous -- it allows you to perform a start activity (including
3475        // permission grants) as any app that may launch one of your own activities.  So
3476        // we will only allow this to be done from activities that are part of the core framework,
3477        // and then only when they are running as the system.
3478        final ActivityRecord sourceRecord;
3479        final int targetUid;
3480        final String targetPackage;
3481        synchronized (this) {
3482            if (resultTo == null) {
3483                throw new SecurityException("Must be called from an activity");
3484            }
3485            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3486            if (sourceRecord == null) {
3487                throw new SecurityException("Called with bad activity token: " + resultTo);
3488            }
3489            if (!sourceRecord.info.packageName.equals("android")) {
3490                throw new SecurityException(
3491                        "Must be called from an activity that is declared in the android package");
3492            }
3493            if (sourceRecord.app == null) {
3494                throw new SecurityException("Called without a process attached to activity");
3495            }
3496            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3497                // This is still okay, as long as this activity is running under the
3498                // uid of the original calling activity.
3499                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3500                    throw new SecurityException(
3501                            "Calling activity in uid " + sourceRecord.app.uid
3502                                    + " must be system uid or original calling uid "
3503                                    + sourceRecord.launchedFromUid);
3504                }
3505            }
3506            targetUid = sourceRecord.launchedFromUid;
3507            targetPackage = sourceRecord.launchedFromPackage;
3508        }
3509
3510        // TODO: Switch to user app stacks here.
3511        try {
3512            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3513                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3514                    null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid),
3515                    null, null);
3516            return ret;
3517        } catch (SecurityException e) {
3518            // XXX need to figure out how to propagate to original app.
3519            // A SecurityException here is generally actually a fault of the original
3520            // calling activity (such as a fairly granting permissions), so propagate it
3521            // back to them.
3522            /*
3523            StringBuilder msg = new StringBuilder();
3524            msg.append("While launching");
3525            msg.append(intent.toString());
3526            msg.append(": ");
3527            msg.append(e.getMessage());
3528            */
3529            throw e;
3530        }
3531    }
3532
3533    @Override
3534    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3535            Intent intent, String resolvedType, IBinder resultTo,
3536            String resultWho, int requestCode, int startFlags, String profileFile,
3537            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3538        enforceNotIsolatedCaller("startActivityAndWait");
3539        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3540                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3541        WaitResult res = new WaitResult();
3542        // TODO: Switch to user app stacks here.
3543        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3544                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3545                res, null, options, userId, null, null);
3546        return res;
3547    }
3548
3549    @Override
3550    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3551            Intent intent, String resolvedType, IBinder resultTo,
3552            String resultWho, int requestCode, int startFlags, Configuration config,
3553            Bundle options, int userId) {
3554        enforceNotIsolatedCaller("startActivityWithConfig");
3555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3556                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3557        // TODO: Switch to user app stacks here.
3558        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3559                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3560                null, null, null, config, options, userId, null, null);
3561        return ret;
3562    }
3563
3564    @Override
3565    public int startActivityIntentSender(IApplicationThread caller,
3566            IntentSender intent, Intent fillInIntent, String resolvedType,
3567            IBinder resultTo, String resultWho, int requestCode,
3568            int flagsMask, int flagsValues, Bundle options) {
3569        enforceNotIsolatedCaller("startActivityIntentSender");
3570        // Refuse possible leaked file descriptors
3571        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3572            throw new IllegalArgumentException("File descriptors passed in Intent");
3573        }
3574
3575        IIntentSender sender = intent.getTarget();
3576        if (!(sender instanceof PendingIntentRecord)) {
3577            throw new IllegalArgumentException("Bad PendingIntent object");
3578        }
3579
3580        PendingIntentRecord pir = (PendingIntentRecord)sender;
3581
3582        synchronized (this) {
3583            // If this is coming from the currently resumed activity, it is
3584            // effectively saying that app switches are allowed at this point.
3585            final ActivityStack stack = getFocusedStack();
3586            if (stack.mResumedActivity != null &&
3587                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3588                mAppSwitchesAllowedTime = 0;
3589            }
3590        }
3591        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3592                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3593        return ret;
3594    }
3595
3596    @Override
3597    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3598            Intent intent, String resolvedType, IVoiceInteractionSession session,
3599            IVoiceInteractor interactor, int startFlags, String profileFile,
3600            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3601        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3602                != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startVoiceActivity() from pid="
3604                    + Binder.getCallingPid()
3605                    + ", uid=" + Binder.getCallingUid()
3606                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3607            Slog.w(TAG, msg);
3608            throw new SecurityException(msg);
3609        }
3610        if (session == null || interactor == null) {
3611            throw new NullPointerException("null session or interactor");
3612        }
3613        userId = handleIncomingUser(callingPid, callingUid, userId,
3614                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3615        // TODO: Switch to user app stacks here.
3616        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3617                resolvedType, session, interactor, null, null, 0, startFlags,
3618                profileFile, profileFd, null, null, options, userId, null, null);
3619    }
3620
3621    @Override
3622    public boolean startNextMatchingActivity(IBinder callingActivity,
3623            Intent intent, Bundle options) {
3624        // Refuse possible leaked file descriptors
3625        if (intent != null && intent.hasFileDescriptors() == true) {
3626            throw new IllegalArgumentException("File descriptors passed in Intent");
3627        }
3628
3629        synchronized (this) {
3630            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3631            if (r == null) {
3632                ActivityOptions.abort(options);
3633                return false;
3634            }
3635            if (r.app == null || r.app.thread == null) {
3636                // The caller is not running...  d'oh!
3637                ActivityOptions.abort(options);
3638                return false;
3639            }
3640            intent = new Intent(intent);
3641            // The caller is not allowed to change the data.
3642            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3643            // And we are resetting to find the next component...
3644            intent.setComponent(null);
3645
3646            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3647
3648            ActivityInfo aInfo = null;
3649            try {
3650                List<ResolveInfo> resolves =
3651                    AppGlobals.getPackageManager().queryIntentActivities(
3652                            intent, r.resolvedType,
3653                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3654                            UserHandle.getCallingUserId());
3655
3656                // Look for the original activity in the list...
3657                final int N = resolves != null ? resolves.size() : 0;
3658                for (int i=0; i<N; i++) {
3659                    ResolveInfo rInfo = resolves.get(i);
3660                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3661                            && rInfo.activityInfo.name.equals(r.info.name)) {
3662                        // We found the current one...  the next matching is
3663                        // after it.
3664                        i++;
3665                        if (i<N) {
3666                            aInfo = resolves.get(i).activityInfo;
3667                        }
3668                        if (debug) {
3669                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3670                                    + "/" + r.info.name);
3671                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3672                                    + "/" + aInfo.name);
3673                        }
3674                        break;
3675                    }
3676                }
3677            } catch (RemoteException e) {
3678            }
3679
3680            if (aInfo == null) {
3681                // Nobody who is next!
3682                ActivityOptions.abort(options);
3683                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3684                return false;
3685            }
3686
3687            intent.setComponent(new ComponentName(
3688                    aInfo.applicationInfo.packageName, aInfo.name));
3689            intent.setFlags(intent.getFlags()&~(
3690                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3691                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3692                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3693                    Intent.FLAG_ACTIVITY_NEW_TASK));
3694
3695            // Okay now we need to start the new activity, replacing the
3696            // currently running activity.  This is a little tricky because
3697            // we want to start the new one as if the current one is finished,
3698            // but not finish the current one first so that there is no flicker.
3699            // And thus...
3700            final boolean wasFinishing = r.finishing;
3701            r.finishing = true;
3702
3703            // Propagate reply information over to the new activity.
3704            final ActivityRecord resultTo = r.resultTo;
3705            final String resultWho = r.resultWho;
3706            final int requestCode = r.requestCode;
3707            r.resultTo = null;
3708            if (resultTo != null) {
3709                resultTo.removeResultsLocked(r, resultWho, requestCode);
3710            }
3711
3712            final long origId = Binder.clearCallingIdentity();
3713            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3714                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3715                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3716                    options, false, null, null, null);
3717            Binder.restoreCallingIdentity(origId);
3718
3719            r.finishing = wasFinishing;
3720            if (res != ActivityManager.START_SUCCESS) {
3721                return false;
3722            }
3723            return true;
3724        }
3725    }
3726
3727    @Override
3728    public final int startActivityFromRecents(int taskId, Bundle options) {
3729        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3730            String msg = "Permission Denial: startActivityFromRecents called without " +
3731                    START_TASKS_FROM_RECENTS;
3732            Slog.w(TAG, msg);
3733            throw new SecurityException(msg);
3734        }
3735        return startActivityFromRecentsInner(taskId, options);
3736    }
3737
3738    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3739        final TaskRecord task;
3740        final int callingUid;
3741        final String callingPackage;
3742        final Intent intent;
3743        final int userId;
3744        synchronized (this) {
3745            task = recentTaskForIdLocked(taskId);
3746            if (task == null) {
3747                throw new IllegalArgumentException("Task " + taskId + " not found.");
3748            }
3749            callingUid = task.mCallingUid;
3750            callingPackage = task.mCallingPackage;
3751            intent = task.intent;
3752            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3753            userId = task.userId;
3754        }
3755        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3756                options, userId, null, task);
3757    }
3758
3759    final int startActivityInPackage(int uid, String callingPackage,
3760            Intent intent, String resolvedType, IBinder resultTo,
3761            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3762            IActivityContainer container, TaskRecord inTask) {
3763
3764        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3765                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3766
3767        // TODO: Switch to user app stacks here.
3768        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3769                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3770                null, null, null, null, options, userId, container, inTask);
3771        return ret;
3772    }
3773
3774    @Override
3775    public final int startActivities(IApplicationThread caller, String callingPackage,
3776            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3777            int userId) {
3778        enforceNotIsolatedCaller("startActivities");
3779        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3780                false, ALLOW_FULL_ONLY, "startActivity", null);
3781        // TODO: Switch to user app stacks here.
3782        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3783                resolvedTypes, resultTo, options, userId);
3784        return ret;
3785    }
3786
3787    final int startActivitiesInPackage(int uid, String callingPackage,
3788            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3789            Bundle options, int userId) {
3790
3791        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3792                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3793        // TODO: Switch to user app stacks here.
3794        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3795                resultTo, options, userId);
3796        return ret;
3797    }
3798
3799    //explicitly remove thd old information in mRecentTasks when removing existing user.
3800    private void removeRecentTasksForUserLocked(int userId) {
3801        if(userId <= 0) {
3802            Slog.i(TAG, "Can't remove recent task on user " + userId);
3803            return;
3804        }
3805
3806        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3807            TaskRecord tr = mRecentTasks.get(i);
3808            if (tr.userId == userId) {
3809                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3810                        + " when finishing user" + userId);
3811                tr.disposeThumbnail();
3812                mRecentTasks.remove(i);
3813            }
3814        }
3815
3816        // Remove tasks from persistent storage.
3817        mTaskPersister.wakeup(null, true);
3818    }
3819
3820    final void addRecentTaskLocked(TaskRecord task) {
3821        final int N = mRecentTasks.size();
3822        // Quick case: check if the top-most recent task is the same.
3823        if (N > 0 && mRecentTasks.get(0) == task) {
3824            return;
3825        }
3826        // Another quick case: never add voice sessions.
3827        if (task.voiceSession != null) {
3828            return;
3829        }
3830
3831        trimRecentsForTask(task, true);
3832
3833        if (N >= MAX_RECENT_TASKS) {
3834            final TaskRecord tr = mRecentTasks.remove(N - 1);
3835            tr.disposeThumbnail();
3836            tr.closeRecentsChain();
3837        }
3838        mRecentTasks.add(0, task);
3839    }
3840
3841    /**
3842     * If needed, remove oldest existing entries in recents that are for the same kind
3843     * of task as the given one.
3844     */
3845    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
3846        int N = mRecentTasks.size();
3847        final Intent intent = task.intent;
3848        final boolean document = intent != null && intent.isDocument();
3849
3850        int maxRecents = task.maxRecents - 1;
3851        for (int i=0; i<N; i++) {
3852            final TaskRecord tr = mRecentTasks.get(i);
3853            if (task != tr) {
3854                if (task.userId != tr.userId) {
3855                    continue;
3856                }
3857                if (i > MAX_RECENT_BITMAPS) {
3858                    tr.freeLastThumbnail();
3859                }
3860                final Intent trIntent = tr.intent;
3861                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3862                    (intent == null || !intent.filterEquals(trIntent))) {
3863                    continue;
3864                }
3865                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3866                if (document && trIsDocument) {
3867                    // These are the same document activity (not necessarily the same doc).
3868                    if (maxRecents > 0) {
3869                        --maxRecents;
3870                        continue;
3871                    }
3872                    // Hit the maximum number of documents for this task. Fall through
3873                    // and remove this document from recents.
3874                } else if (document || trIsDocument) {
3875                    // Only one of these is a document. Not the droid we're looking for.
3876                    continue;
3877                }
3878            }
3879
3880            if (!doTrim) {
3881                // If the caller is not actually asking for a trim, just tell them we reached
3882                // a point where the trim would happen.
3883                return i;
3884            }
3885
3886            // Either task and tr are the same or, their affinities match or their intents match
3887            // and neither of them is a document, or they are documents using the same activity
3888            // and their maxRecents has been reached.
3889            tr.disposeThumbnail();
3890            mRecentTasks.remove(i);
3891            if (task != tr) {
3892                tr.closeRecentsChain();
3893            }
3894            i--;
3895            N--;
3896            if (task.intent == null) {
3897                // If the new recent task we are adding is not fully
3898                // specified, then replace it with the existing recent task.
3899                task = tr;
3900            }
3901            notifyTaskPersisterLocked(tr, false);
3902        }
3903
3904        return -1;
3905    }
3906
3907    @Override
3908    public void reportActivityFullyDrawn(IBinder token) {
3909        synchronized (this) {
3910            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3911            if (r == null) {
3912                return;
3913            }
3914            r.reportFullyDrawnLocked();
3915        }
3916    }
3917
3918    @Override
3919    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3920        synchronized (this) {
3921            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3922            if (r == null) {
3923                return;
3924            }
3925            final long origId = Binder.clearCallingIdentity();
3926            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3927            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3928                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3929            if (config != null) {
3930                r.frozenBeforeDestroy = true;
3931                if (!updateConfigurationLocked(config, r, false, false)) {
3932                    mStackSupervisor.resumeTopActivitiesLocked();
3933                }
3934            }
3935            Binder.restoreCallingIdentity(origId);
3936        }
3937    }
3938
3939    @Override
3940    public int getRequestedOrientation(IBinder token) {
3941        synchronized (this) {
3942            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3943            if (r == null) {
3944                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3945            }
3946            return mWindowManager.getAppOrientation(r.appToken);
3947        }
3948    }
3949
3950    /**
3951     * This is the internal entry point for handling Activity.finish().
3952     *
3953     * @param token The Binder token referencing the Activity we want to finish.
3954     * @param resultCode Result code, if any, from this Activity.
3955     * @param resultData Result data (Intent), if any, from this Activity.
3956     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3957     *            the root Activity in the task.
3958     *
3959     * @return Returns true if the activity successfully finished, or false if it is still running.
3960     */
3961    @Override
3962    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3963            boolean finishTask) {
3964        // Refuse possible leaked file descriptors
3965        if (resultData != null && resultData.hasFileDescriptors() == true) {
3966            throw new IllegalArgumentException("File descriptors passed in Intent");
3967        }
3968
3969        synchronized(this) {
3970            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3971            if (r == null) {
3972                return true;
3973            }
3974            // Keep track of the root activity of the task before we finish it
3975            TaskRecord tr = r.task;
3976            ActivityRecord rootR = tr.getRootActivity();
3977            // Do not allow task to finish in Lock Task mode.
3978            if (tr == mStackSupervisor.mLockTaskModeTask) {
3979                if (rootR == r) {
3980                    mStackSupervisor.showLockTaskToast();
3981                    return false;
3982                }
3983            }
3984            if (mController != null) {
3985                // Find the first activity that is not finishing.
3986                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3987                if (next != null) {
3988                    // ask watcher if this is allowed
3989                    boolean resumeOK = true;
3990                    try {
3991                        resumeOK = mController.activityResuming(next.packageName);
3992                    } catch (RemoteException e) {
3993                        mController = null;
3994                        Watchdog.getInstance().setActivityController(null);
3995                    }
3996
3997                    if (!resumeOK) {
3998                        return false;
3999                    }
4000                }
4001            }
4002            final long origId = Binder.clearCallingIdentity();
4003            try {
4004                boolean res;
4005                if (finishTask && r == rootR) {
4006                    // If requested, remove the task that is associated to this activity only if it
4007                    // was the root activity in the task.  The result code and data is ignored because
4008                    // we don't support returning them across task boundaries.
4009                    res = removeTaskByIdLocked(tr.taskId, 0);
4010                } else {
4011                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4012                            resultData, "app-request", true);
4013                }
4014                return res;
4015            } finally {
4016                Binder.restoreCallingIdentity(origId);
4017            }
4018        }
4019    }
4020
4021    @Override
4022    public final void finishHeavyWeightApp() {
4023        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4024                != PackageManager.PERMISSION_GRANTED) {
4025            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4026                    + Binder.getCallingPid()
4027                    + ", uid=" + Binder.getCallingUid()
4028                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4029            Slog.w(TAG, msg);
4030            throw new SecurityException(msg);
4031        }
4032
4033        synchronized(this) {
4034            if (mHeavyWeightProcess == null) {
4035                return;
4036            }
4037
4038            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4039                    mHeavyWeightProcess.activities);
4040            for (int i=0; i<activities.size(); i++) {
4041                ActivityRecord r = activities.get(i);
4042                if (!r.finishing) {
4043                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4044                            null, "finish-heavy", true);
4045                }
4046            }
4047
4048            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4049                    mHeavyWeightProcess.userId, 0));
4050            mHeavyWeightProcess = null;
4051        }
4052    }
4053
4054    @Override
4055    public void crashApplication(int uid, int initialPid, String packageName,
4056            String message) {
4057        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4058                != PackageManager.PERMISSION_GRANTED) {
4059            String msg = "Permission Denial: crashApplication() from pid="
4060                    + Binder.getCallingPid()
4061                    + ", uid=" + Binder.getCallingUid()
4062                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4063            Slog.w(TAG, msg);
4064            throw new SecurityException(msg);
4065        }
4066
4067        synchronized(this) {
4068            ProcessRecord proc = null;
4069
4070            // Figure out which process to kill.  We don't trust that initialPid
4071            // still has any relation to current pids, so must scan through the
4072            // list.
4073            synchronized (mPidsSelfLocked) {
4074                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4075                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4076                    if (p.uid != uid) {
4077                        continue;
4078                    }
4079                    if (p.pid == initialPid) {
4080                        proc = p;
4081                        break;
4082                    }
4083                    if (p.pkgList.containsKey(packageName)) {
4084                        proc = p;
4085                    }
4086                }
4087            }
4088
4089            if (proc == null) {
4090                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4091                        + " initialPid=" + initialPid
4092                        + " packageName=" + packageName);
4093                return;
4094            }
4095
4096            if (proc.thread != null) {
4097                if (proc.pid == Process.myPid()) {
4098                    Log.w(TAG, "crashApplication: trying to crash self!");
4099                    return;
4100                }
4101                long ident = Binder.clearCallingIdentity();
4102                try {
4103                    proc.thread.scheduleCrash(message);
4104                } catch (RemoteException e) {
4105                }
4106                Binder.restoreCallingIdentity(ident);
4107            }
4108        }
4109    }
4110
4111    @Override
4112    public final void finishSubActivity(IBinder token, String resultWho,
4113            int requestCode) {
4114        synchronized(this) {
4115            final long origId = Binder.clearCallingIdentity();
4116            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4117            if (r != null) {
4118                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4119            }
4120            Binder.restoreCallingIdentity(origId);
4121        }
4122    }
4123
4124    @Override
4125    public boolean finishActivityAffinity(IBinder token) {
4126        synchronized(this) {
4127            final long origId = Binder.clearCallingIdentity();
4128            try {
4129                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4130
4131                ActivityRecord rootR = r.task.getRootActivity();
4132                // Do not allow task to finish in Lock Task mode.
4133                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4134                    if (rootR == r) {
4135                        mStackSupervisor.showLockTaskToast();
4136                        return false;
4137                    }
4138                }
4139                boolean res = false;
4140                if (r != null) {
4141                    res = r.task.stack.finishActivityAffinityLocked(r);
4142                }
4143                return res;
4144            } finally {
4145                Binder.restoreCallingIdentity(origId);
4146            }
4147        }
4148    }
4149
4150    @Override
4151    public void finishVoiceTask(IVoiceInteractionSession session) {
4152        synchronized(this) {
4153            final long origId = Binder.clearCallingIdentity();
4154            try {
4155                mStackSupervisor.finishVoiceTask(session);
4156            } finally {
4157                Binder.restoreCallingIdentity(origId);
4158            }
4159        }
4160
4161    }
4162
4163    @Override
4164    public boolean releaseActivityInstance(IBinder token) {
4165        synchronized(this) {
4166            final long origId = Binder.clearCallingIdentity();
4167            try {
4168                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4169                if (r.task == null || r.task.stack == null) {
4170                    return false;
4171                }
4172                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4173            } finally {
4174                Binder.restoreCallingIdentity(origId);
4175            }
4176        }
4177    }
4178
4179    @Override
4180    public void releaseSomeActivities(IApplicationThread appInt) {
4181        synchronized(this) {
4182            final long origId = Binder.clearCallingIdentity();
4183            try {
4184                ProcessRecord app = getRecordForAppLocked(appInt);
4185                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4186            } finally {
4187                Binder.restoreCallingIdentity(origId);
4188            }
4189        }
4190    }
4191
4192    @Override
4193    public boolean willActivityBeVisible(IBinder token) {
4194        synchronized(this) {
4195            ActivityStack stack = ActivityRecord.getStackLocked(token);
4196            if (stack != null) {
4197                return stack.willActivityBeVisibleLocked(token);
4198            }
4199            return false;
4200        }
4201    }
4202
4203    @Override
4204    public void overridePendingTransition(IBinder token, String packageName,
4205            int enterAnim, int exitAnim) {
4206        synchronized(this) {
4207            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4208            if (self == null) {
4209                return;
4210            }
4211
4212            final long origId = Binder.clearCallingIdentity();
4213
4214            if (self.state == ActivityState.RESUMED
4215                    || self.state == ActivityState.PAUSING) {
4216                mWindowManager.overridePendingAppTransition(packageName,
4217                        enterAnim, exitAnim, null);
4218            }
4219
4220            Binder.restoreCallingIdentity(origId);
4221        }
4222    }
4223
4224    /**
4225     * Main function for removing an existing process from the activity manager
4226     * as a result of that process going away.  Clears out all connections
4227     * to the process.
4228     */
4229    private final void handleAppDiedLocked(ProcessRecord app,
4230            boolean restarting, boolean allowRestart) {
4231        int pid = app.pid;
4232        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4233        if (!restarting) {
4234            removeLruProcessLocked(app);
4235            if (pid > 0) {
4236                ProcessList.remove(pid);
4237            }
4238        }
4239
4240        if (mProfileProc == app) {
4241            clearProfilerLocked();
4242        }
4243
4244        // Remove this application's activities from active lists.
4245        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4246
4247        app.activities.clear();
4248
4249        if (app.instrumentationClass != null) {
4250            Slog.w(TAG, "Crash of app " + app.processName
4251                  + " running instrumentation " + app.instrumentationClass);
4252            Bundle info = new Bundle();
4253            info.putString("shortMsg", "Process crashed.");
4254            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4255        }
4256
4257        if (!restarting) {
4258            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4259                // If there was nothing to resume, and we are not already
4260                // restarting this process, but there is a visible activity that
4261                // is hosted by the process...  then make sure all visible
4262                // activities are running, taking care of restarting this
4263                // process.
4264                if (hasVisibleActivities) {
4265                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4266                }
4267            }
4268        }
4269    }
4270
4271    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4272        IBinder threadBinder = thread.asBinder();
4273        // Find the application record.
4274        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4275            ProcessRecord rec = mLruProcesses.get(i);
4276            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4277                return i;
4278            }
4279        }
4280        return -1;
4281    }
4282
4283    final ProcessRecord getRecordForAppLocked(
4284            IApplicationThread thread) {
4285        if (thread == null) {
4286            return null;
4287        }
4288
4289        int appIndex = getLRURecordIndexForAppLocked(thread);
4290        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4291    }
4292
4293    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4294        // If there are no longer any background processes running,
4295        // and the app that died was not running instrumentation,
4296        // then tell everyone we are now low on memory.
4297        boolean haveBg = false;
4298        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4299            ProcessRecord rec = mLruProcesses.get(i);
4300            if (rec.thread != null
4301                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4302                haveBg = true;
4303                break;
4304            }
4305        }
4306
4307        if (!haveBg) {
4308            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4309            if (doReport) {
4310                long now = SystemClock.uptimeMillis();
4311                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4312                    doReport = false;
4313                } else {
4314                    mLastMemUsageReportTime = now;
4315                }
4316            }
4317            final ArrayList<ProcessMemInfo> memInfos
4318                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4319            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4320            long now = SystemClock.uptimeMillis();
4321            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4322                ProcessRecord rec = mLruProcesses.get(i);
4323                if (rec == dyingProc || rec.thread == null) {
4324                    continue;
4325                }
4326                if (doReport) {
4327                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4328                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4329                }
4330                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4331                    // The low memory report is overriding any current
4332                    // state for a GC request.  Make sure to do
4333                    // heavy/important/visible/foreground processes first.
4334                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4335                        rec.lastRequestedGc = 0;
4336                    } else {
4337                        rec.lastRequestedGc = rec.lastLowMemory;
4338                    }
4339                    rec.reportLowMemory = true;
4340                    rec.lastLowMemory = now;
4341                    mProcessesToGc.remove(rec);
4342                    addProcessToGcListLocked(rec);
4343                }
4344            }
4345            if (doReport) {
4346                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4347                mHandler.sendMessage(msg);
4348            }
4349            scheduleAppGcsLocked();
4350        }
4351    }
4352
4353    final void appDiedLocked(ProcessRecord app) {
4354       appDiedLocked(app, app.pid, app.thread);
4355    }
4356
4357    final void appDiedLocked(ProcessRecord app, int pid,
4358            IApplicationThread thread) {
4359
4360        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4361        synchronized (stats) {
4362            stats.noteProcessDiedLocked(app.info.uid, pid);
4363        }
4364
4365        Process.killProcessGroup(app.info.uid, pid);
4366
4367        // Clean up already done if the process has been re-started.
4368        if (app.pid == pid && app.thread != null &&
4369                app.thread.asBinder() == thread.asBinder()) {
4370            boolean doLowMem = app.instrumentationClass == null;
4371            boolean doOomAdj = doLowMem;
4372            if (!app.killedByAm) {
4373                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4374                        + ") has died.");
4375                mAllowLowerMemLevel = true;
4376            } else {
4377                // Note that we always want to do oom adj to update our state with the
4378                // new number of procs.
4379                mAllowLowerMemLevel = false;
4380                doLowMem = false;
4381            }
4382            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4383            if (DEBUG_CLEANUP) Slog.v(
4384                TAG, "Dying app: " + app + ", pid: " + pid
4385                + ", thread: " + thread.asBinder());
4386            handleAppDiedLocked(app, false, true);
4387
4388            if (doOomAdj) {
4389                updateOomAdjLocked();
4390            }
4391            if (doLowMem) {
4392                doLowMemReportIfNeededLocked(app);
4393            }
4394        } else if (app.pid != pid) {
4395            // A new process has already been started.
4396            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4397                    + ") has died and restarted (pid " + app.pid + ").");
4398            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4399        } else if (DEBUG_PROCESSES) {
4400            Slog.d(TAG, "Received spurious death notification for thread "
4401                    + thread.asBinder());
4402        }
4403    }
4404
4405    /**
4406     * If a stack trace dump file is configured, dump process stack traces.
4407     * @param clearTraces causes the dump file to be erased prior to the new
4408     *    traces being written, if true; when false, the new traces will be
4409     *    appended to any existing file content.
4410     * @param firstPids of dalvik VM processes to dump stack traces for first
4411     * @param lastPids of dalvik VM processes to dump stack traces for last
4412     * @param nativeProcs optional list of native process names to dump stack crawls
4413     * @return file containing stack traces, or null if no dump file is configured
4414     */
4415    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4416            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4417        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4418        if (tracesPath == null || tracesPath.length() == 0) {
4419            return null;
4420        }
4421
4422        File tracesFile = new File(tracesPath);
4423        try {
4424            File tracesDir = tracesFile.getParentFile();
4425            if (!tracesDir.exists()) {
4426                tracesFile.mkdirs();
4427                if (!SELinux.restorecon(tracesDir)) {
4428                    return null;
4429                }
4430            }
4431            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4432
4433            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4434            tracesFile.createNewFile();
4435            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4436        } catch (IOException e) {
4437            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4438            return null;
4439        }
4440
4441        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4442        return tracesFile;
4443    }
4444
4445    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4446            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4447        // Use a FileObserver to detect when traces finish writing.
4448        // The order of traces is considered important to maintain for legibility.
4449        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4450            @Override
4451            public synchronized void onEvent(int event, String path) { notify(); }
4452        };
4453
4454        try {
4455            observer.startWatching();
4456
4457            // First collect all of the stacks of the most important pids.
4458            if (firstPids != null) {
4459                try {
4460                    int num = firstPids.size();
4461                    for (int i = 0; i < num; i++) {
4462                        synchronized (observer) {
4463                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4464                            observer.wait(200);  // Wait for write-close, give up after 200msec
4465                        }
4466                    }
4467                } catch (InterruptedException e) {
4468                    Log.wtf(TAG, e);
4469                }
4470            }
4471
4472            // Next collect the stacks of the native pids
4473            if (nativeProcs != null) {
4474                int[] pids = Process.getPidsForCommands(nativeProcs);
4475                if (pids != null) {
4476                    for (int pid : pids) {
4477                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4478                    }
4479                }
4480            }
4481
4482            // Lastly, measure CPU usage.
4483            if (processCpuTracker != null) {
4484                processCpuTracker.init();
4485                System.gc();
4486                processCpuTracker.update();
4487                try {
4488                    synchronized (processCpuTracker) {
4489                        processCpuTracker.wait(500); // measure over 1/2 second.
4490                    }
4491                } catch (InterruptedException e) {
4492                }
4493                processCpuTracker.update();
4494
4495                // We'll take the stack crawls of just the top apps using CPU.
4496                final int N = processCpuTracker.countWorkingStats();
4497                int numProcs = 0;
4498                for (int i=0; i<N && numProcs<5; i++) {
4499                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4500                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4501                        numProcs++;
4502                        try {
4503                            synchronized (observer) {
4504                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4505                                observer.wait(200);  // Wait for write-close, give up after 200msec
4506                            }
4507                        } catch (InterruptedException e) {
4508                            Log.wtf(TAG, e);
4509                        }
4510
4511                    }
4512                }
4513            }
4514        } finally {
4515            observer.stopWatching();
4516        }
4517    }
4518
4519    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4520        if (true || IS_USER_BUILD) {
4521            return;
4522        }
4523        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4524        if (tracesPath == null || tracesPath.length() == 0) {
4525            return;
4526        }
4527
4528        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4529        StrictMode.allowThreadDiskWrites();
4530        try {
4531            final File tracesFile = new File(tracesPath);
4532            final File tracesDir = tracesFile.getParentFile();
4533            final File tracesTmp = new File(tracesDir, "__tmp__");
4534            try {
4535                if (!tracesDir.exists()) {
4536                    tracesFile.mkdirs();
4537                    if (!SELinux.restorecon(tracesDir.getPath())) {
4538                        return;
4539                    }
4540                }
4541                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4542
4543                if (tracesFile.exists()) {
4544                    tracesTmp.delete();
4545                    tracesFile.renameTo(tracesTmp);
4546                }
4547                StringBuilder sb = new StringBuilder();
4548                Time tobj = new Time();
4549                tobj.set(System.currentTimeMillis());
4550                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4551                sb.append(": ");
4552                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4553                sb.append(" since ");
4554                sb.append(msg);
4555                FileOutputStream fos = new FileOutputStream(tracesFile);
4556                fos.write(sb.toString().getBytes());
4557                if (app == null) {
4558                    fos.write("\n*** No application process!".getBytes());
4559                }
4560                fos.close();
4561                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4562            } catch (IOException e) {
4563                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4564                return;
4565            }
4566
4567            if (app != null) {
4568                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4569                firstPids.add(app.pid);
4570                dumpStackTraces(tracesPath, firstPids, null, null, null);
4571            }
4572
4573            File lastTracesFile = null;
4574            File curTracesFile = null;
4575            for (int i=9; i>=0; i--) {
4576                String name = String.format(Locale.US, "slow%02d.txt", i);
4577                curTracesFile = new File(tracesDir, name);
4578                if (curTracesFile.exists()) {
4579                    if (lastTracesFile != null) {
4580                        curTracesFile.renameTo(lastTracesFile);
4581                    } else {
4582                        curTracesFile.delete();
4583                    }
4584                }
4585                lastTracesFile = curTracesFile;
4586            }
4587            tracesFile.renameTo(curTracesFile);
4588            if (tracesTmp.exists()) {
4589                tracesTmp.renameTo(tracesFile);
4590            }
4591        } finally {
4592            StrictMode.setThreadPolicy(oldPolicy);
4593        }
4594    }
4595
4596    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4597            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4598        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4599        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4600
4601        if (mController != null) {
4602            try {
4603                // 0 == continue, -1 = kill process immediately
4604                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4605                if (res < 0 && app.pid != MY_PID) {
4606                    app.kill("anr", true);
4607                }
4608            } catch (RemoteException e) {
4609                mController = null;
4610                Watchdog.getInstance().setActivityController(null);
4611            }
4612        }
4613
4614        long anrTime = SystemClock.uptimeMillis();
4615        if (MONITOR_CPU_USAGE) {
4616            updateCpuStatsNow();
4617        }
4618
4619        synchronized (this) {
4620            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4621            if (mShuttingDown) {
4622                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4623                return;
4624            } else if (app.notResponding) {
4625                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4626                return;
4627            } else if (app.crashing) {
4628                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4629                return;
4630            }
4631
4632            // In case we come through here for the same app before completing
4633            // this one, mark as anring now so we will bail out.
4634            app.notResponding = true;
4635
4636            // Log the ANR to the event log.
4637            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4638                    app.processName, app.info.flags, annotation);
4639
4640            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4641            firstPids.add(app.pid);
4642
4643            int parentPid = app.pid;
4644            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4645            if (parentPid != app.pid) firstPids.add(parentPid);
4646
4647            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4648
4649            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4650                ProcessRecord r = mLruProcesses.get(i);
4651                if (r != null && r.thread != null) {
4652                    int pid = r.pid;
4653                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4654                        if (r.persistent) {
4655                            firstPids.add(pid);
4656                        } else {
4657                            lastPids.put(pid, Boolean.TRUE);
4658                        }
4659                    }
4660                }
4661            }
4662        }
4663
4664        // Log the ANR to the main log.
4665        StringBuilder info = new StringBuilder();
4666        info.setLength(0);
4667        info.append("ANR in ").append(app.processName);
4668        if (activity != null && activity.shortComponentName != null) {
4669            info.append(" (").append(activity.shortComponentName).append(")");
4670        }
4671        info.append("\n");
4672        info.append("PID: ").append(app.pid).append("\n");
4673        if (annotation != null) {
4674            info.append("Reason: ").append(annotation).append("\n");
4675        }
4676        if (parent != null && parent != activity) {
4677            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4678        }
4679
4680        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4681
4682        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4683                NATIVE_STACKS_OF_INTEREST);
4684
4685        String cpuInfo = null;
4686        if (MONITOR_CPU_USAGE) {
4687            updateCpuStatsNow();
4688            synchronized (mProcessCpuThread) {
4689                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4690            }
4691            info.append(processCpuTracker.printCurrentLoad());
4692            info.append(cpuInfo);
4693        }
4694
4695        info.append(processCpuTracker.printCurrentState(anrTime));
4696
4697        Slog.e(TAG, info.toString());
4698        if (tracesFile == null) {
4699            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4700            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4701        }
4702
4703        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4704                cpuInfo, tracesFile, null);
4705
4706        if (mController != null) {
4707            try {
4708                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4709                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4710                if (res != 0) {
4711                    if (res < 0 && app.pid != MY_PID) {
4712                        app.kill("anr", true);
4713                    } else {
4714                        synchronized (this) {
4715                            mServices.scheduleServiceTimeoutLocked(app);
4716                        }
4717                    }
4718                    return;
4719                }
4720            } catch (RemoteException e) {
4721                mController = null;
4722                Watchdog.getInstance().setActivityController(null);
4723            }
4724        }
4725
4726        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4727        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4728                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4729
4730        synchronized (this) {
4731            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4732                app.kill("bg anr", true);
4733                return;
4734            }
4735
4736            // Set the app's notResponding state, and look up the errorReportReceiver
4737            makeAppNotRespondingLocked(app,
4738                    activity != null ? activity.shortComponentName : null,
4739                    annotation != null ? "ANR " + annotation : "ANR",
4740                    info.toString());
4741
4742            // Bring up the infamous App Not Responding dialog
4743            Message msg = Message.obtain();
4744            HashMap<String, Object> map = new HashMap<String, Object>();
4745            msg.what = SHOW_NOT_RESPONDING_MSG;
4746            msg.obj = map;
4747            msg.arg1 = aboveSystem ? 1 : 0;
4748            map.put("app", app);
4749            if (activity != null) {
4750                map.put("activity", activity);
4751            }
4752
4753            mHandler.sendMessage(msg);
4754        }
4755    }
4756
4757    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4758        if (!mLaunchWarningShown) {
4759            mLaunchWarningShown = true;
4760            mHandler.post(new Runnable() {
4761                @Override
4762                public void run() {
4763                    synchronized (ActivityManagerService.this) {
4764                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4765                        d.show();
4766                        mHandler.postDelayed(new Runnable() {
4767                            @Override
4768                            public void run() {
4769                                synchronized (ActivityManagerService.this) {
4770                                    d.dismiss();
4771                                    mLaunchWarningShown = false;
4772                                }
4773                            }
4774                        }, 4000);
4775                    }
4776                }
4777            });
4778        }
4779    }
4780
4781    @Override
4782    public boolean clearApplicationUserData(final String packageName,
4783            final IPackageDataObserver observer, int userId) {
4784        enforceNotIsolatedCaller("clearApplicationUserData");
4785        int uid = Binder.getCallingUid();
4786        int pid = Binder.getCallingPid();
4787        userId = handleIncomingUser(pid, uid,
4788                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4789        long callingId = Binder.clearCallingIdentity();
4790        try {
4791            IPackageManager pm = AppGlobals.getPackageManager();
4792            int pkgUid = -1;
4793            synchronized(this) {
4794                try {
4795                    pkgUid = pm.getPackageUid(packageName, userId);
4796                } catch (RemoteException e) {
4797                }
4798                if (pkgUid == -1) {
4799                    Slog.w(TAG, "Invalid packageName: " + packageName);
4800                    if (observer != null) {
4801                        try {
4802                            observer.onRemoveCompleted(packageName, false);
4803                        } catch (RemoteException e) {
4804                            Slog.i(TAG, "Observer no longer exists.");
4805                        }
4806                    }
4807                    return false;
4808                }
4809                if (uid == pkgUid || checkComponentPermission(
4810                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4811                        pid, uid, -1, true)
4812                        == PackageManager.PERMISSION_GRANTED) {
4813                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4814                } else {
4815                    throw new SecurityException("PID " + pid + " does not have permission "
4816                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4817                                    + " of package " + packageName);
4818                }
4819
4820                // Remove all tasks match the cleared application package and user
4821                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4822                    final TaskRecord tr = mRecentTasks.get(i);
4823                    final String taskPackageName =
4824                            tr.getBaseIntent().getComponent().getPackageName();
4825                    if (tr.userId != userId) continue;
4826                    if (!taskPackageName.equals(packageName)) continue;
4827                    removeTaskByIdLocked(tr.taskId, 0);
4828                }
4829            }
4830
4831            try {
4832                // Clear application user data
4833                pm.clearApplicationUserData(packageName, observer, userId);
4834
4835                synchronized(this) {
4836                    // Remove all permissions granted from/to this package
4837                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4838                }
4839
4840                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4841                        Uri.fromParts("package", packageName, null));
4842                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4843                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4844                        null, null, 0, null, null, null, false, false, userId);
4845            } catch (RemoteException e) {
4846            }
4847        } finally {
4848            Binder.restoreCallingIdentity(callingId);
4849        }
4850        return true;
4851    }
4852
4853    @Override
4854    public void killBackgroundProcesses(final String packageName, int userId) {
4855        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4856                != PackageManager.PERMISSION_GRANTED &&
4857                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4858                        != PackageManager.PERMISSION_GRANTED) {
4859            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4860                    + Binder.getCallingPid()
4861                    + ", uid=" + Binder.getCallingUid()
4862                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4863            Slog.w(TAG, msg);
4864            throw new SecurityException(msg);
4865        }
4866
4867        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4868                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4869        long callingId = Binder.clearCallingIdentity();
4870        try {
4871            IPackageManager pm = AppGlobals.getPackageManager();
4872            synchronized(this) {
4873                int appId = -1;
4874                try {
4875                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4876                } catch (RemoteException e) {
4877                }
4878                if (appId == -1) {
4879                    Slog.w(TAG, "Invalid packageName: " + packageName);
4880                    return;
4881                }
4882                killPackageProcessesLocked(packageName, appId, userId,
4883                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4884            }
4885        } finally {
4886            Binder.restoreCallingIdentity(callingId);
4887        }
4888    }
4889
4890    @Override
4891    public void killAllBackgroundProcesses() {
4892        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4893                != PackageManager.PERMISSION_GRANTED) {
4894            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4895                    + Binder.getCallingPid()
4896                    + ", uid=" + Binder.getCallingUid()
4897                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4898            Slog.w(TAG, msg);
4899            throw new SecurityException(msg);
4900        }
4901
4902        long callingId = Binder.clearCallingIdentity();
4903        try {
4904            synchronized(this) {
4905                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4906                final int NP = mProcessNames.getMap().size();
4907                for (int ip=0; ip<NP; ip++) {
4908                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4909                    final int NA = apps.size();
4910                    for (int ia=0; ia<NA; ia++) {
4911                        ProcessRecord app = apps.valueAt(ia);
4912                        if (app.persistent) {
4913                            // we don't kill persistent processes
4914                            continue;
4915                        }
4916                        if (app.removed) {
4917                            procs.add(app);
4918                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4919                            app.removed = true;
4920                            procs.add(app);
4921                        }
4922                    }
4923                }
4924
4925                int N = procs.size();
4926                for (int i=0; i<N; i++) {
4927                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4928                }
4929                mAllowLowerMemLevel = true;
4930                updateOomAdjLocked();
4931                doLowMemReportIfNeededLocked(null);
4932            }
4933        } finally {
4934            Binder.restoreCallingIdentity(callingId);
4935        }
4936    }
4937
4938    @Override
4939    public void forceStopPackage(final String packageName, int userId) {
4940        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4941                != PackageManager.PERMISSION_GRANTED) {
4942            String msg = "Permission Denial: forceStopPackage() from pid="
4943                    + Binder.getCallingPid()
4944                    + ", uid=" + Binder.getCallingUid()
4945                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4946            Slog.w(TAG, msg);
4947            throw new SecurityException(msg);
4948        }
4949        final int callingPid = Binder.getCallingPid();
4950        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4951                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4952        long callingId = Binder.clearCallingIdentity();
4953        try {
4954            IPackageManager pm = AppGlobals.getPackageManager();
4955            synchronized(this) {
4956                int[] users = userId == UserHandle.USER_ALL
4957                        ? getUsersLocked() : new int[] { userId };
4958                for (int user : users) {
4959                    int pkgUid = -1;
4960                    try {
4961                        pkgUid = pm.getPackageUid(packageName, user);
4962                    } catch (RemoteException e) {
4963                    }
4964                    if (pkgUid == -1) {
4965                        Slog.w(TAG, "Invalid packageName: " + packageName);
4966                        continue;
4967                    }
4968                    try {
4969                        pm.setPackageStoppedState(packageName, true, user);
4970                    } catch (RemoteException e) {
4971                    } catch (IllegalArgumentException e) {
4972                        Slog.w(TAG, "Failed trying to unstop package "
4973                                + packageName + ": " + e);
4974                    }
4975                    if (isUserRunningLocked(user, false)) {
4976                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4977                    }
4978                }
4979            }
4980        } finally {
4981            Binder.restoreCallingIdentity(callingId);
4982        }
4983    }
4984
4985    @Override
4986    public void addPackageDependency(String packageName) {
4987        synchronized (this) {
4988            int callingPid = Binder.getCallingPid();
4989            if (callingPid == Process.myPid()) {
4990                //  Yeah, um, no.
4991                Slog.w(TAG, "Can't addPackageDependency on system process");
4992                return;
4993            }
4994            ProcessRecord proc;
4995            synchronized (mPidsSelfLocked) {
4996                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4997            }
4998            if (proc != null) {
4999                if (proc.pkgDeps == null) {
5000                    proc.pkgDeps = new ArraySet<String>(1);
5001                }
5002                proc.pkgDeps.add(packageName);
5003            }
5004        }
5005    }
5006
5007    /*
5008     * The pkg name and app id have to be specified.
5009     */
5010    @Override
5011    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5012        if (pkg == null) {
5013            return;
5014        }
5015        // Make sure the uid is valid.
5016        if (appid < 0) {
5017            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5018            return;
5019        }
5020        int callerUid = Binder.getCallingUid();
5021        // Only the system server can kill an application
5022        if (callerUid == Process.SYSTEM_UID) {
5023            // Post an aysnc message to kill the application
5024            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5025            msg.arg1 = appid;
5026            msg.arg2 = 0;
5027            Bundle bundle = new Bundle();
5028            bundle.putString("pkg", pkg);
5029            bundle.putString("reason", reason);
5030            msg.obj = bundle;
5031            mHandler.sendMessage(msg);
5032        } else {
5033            throw new SecurityException(callerUid + " cannot kill pkg: " +
5034                    pkg);
5035        }
5036    }
5037
5038    @Override
5039    public void closeSystemDialogs(String reason) {
5040        enforceNotIsolatedCaller("closeSystemDialogs");
5041
5042        final int pid = Binder.getCallingPid();
5043        final int uid = Binder.getCallingUid();
5044        final long origId = Binder.clearCallingIdentity();
5045        try {
5046            synchronized (this) {
5047                // Only allow this from foreground processes, so that background
5048                // applications can't abuse it to prevent system UI from being shown.
5049                if (uid >= Process.FIRST_APPLICATION_UID) {
5050                    ProcessRecord proc;
5051                    synchronized (mPidsSelfLocked) {
5052                        proc = mPidsSelfLocked.get(pid);
5053                    }
5054                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5055                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5056                                + " from background process " + proc);
5057                        return;
5058                    }
5059                }
5060                closeSystemDialogsLocked(reason);
5061            }
5062        } finally {
5063            Binder.restoreCallingIdentity(origId);
5064        }
5065    }
5066
5067    void closeSystemDialogsLocked(String reason) {
5068        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5069        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5070                | Intent.FLAG_RECEIVER_FOREGROUND);
5071        if (reason != null) {
5072            intent.putExtra("reason", reason);
5073        }
5074        mWindowManager.closeSystemDialogs(reason);
5075
5076        mStackSupervisor.closeSystemDialogsLocked();
5077
5078        broadcastIntentLocked(null, null, intent, null,
5079                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5080                Process.SYSTEM_UID, UserHandle.USER_ALL);
5081    }
5082
5083    @Override
5084    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5085        enforceNotIsolatedCaller("getProcessMemoryInfo");
5086        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5087        for (int i=pids.length-1; i>=0; i--) {
5088            ProcessRecord proc;
5089            int oomAdj;
5090            synchronized (this) {
5091                synchronized (mPidsSelfLocked) {
5092                    proc = mPidsSelfLocked.get(pids[i]);
5093                    oomAdj = proc != null ? proc.setAdj : 0;
5094                }
5095            }
5096            infos[i] = new Debug.MemoryInfo();
5097            Debug.getMemoryInfo(pids[i], infos[i]);
5098            if (proc != null) {
5099                synchronized (this) {
5100                    if (proc.thread != null && proc.setAdj == oomAdj) {
5101                        // Record this for posterity if the process has been stable.
5102                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5103                                infos[i].getTotalUss(), false, proc.pkgList);
5104                    }
5105                }
5106            }
5107        }
5108        return infos;
5109    }
5110
5111    @Override
5112    public long[] getProcessPss(int[] pids) {
5113        enforceNotIsolatedCaller("getProcessPss");
5114        long[] pss = new long[pids.length];
5115        for (int i=pids.length-1; i>=0; i--) {
5116            ProcessRecord proc;
5117            int oomAdj;
5118            synchronized (this) {
5119                synchronized (mPidsSelfLocked) {
5120                    proc = mPidsSelfLocked.get(pids[i]);
5121                    oomAdj = proc != null ? proc.setAdj : 0;
5122                }
5123            }
5124            long[] tmpUss = new long[1];
5125            pss[i] = Debug.getPss(pids[i], tmpUss);
5126            if (proc != null) {
5127                synchronized (this) {
5128                    if (proc.thread != null && proc.setAdj == oomAdj) {
5129                        // Record this for posterity if the process has been stable.
5130                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5131                    }
5132                }
5133            }
5134        }
5135        return pss;
5136    }
5137
5138    @Override
5139    public void killApplicationProcess(String processName, int uid) {
5140        if (processName == null) {
5141            return;
5142        }
5143
5144        int callerUid = Binder.getCallingUid();
5145        // Only the system server can kill an application
5146        if (callerUid == Process.SYSTEM_UID) {
5147            synchronized (this) {
5148                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5149                if (app != null && app.thread != null) {
5150                    try {
5151                        app.thread.scheduleSuicide();
5152                    } catch (RemoteException e) {
5153                        // If the other end already died, then our work here is done.
5154                    }
5155                } else {
5156                    Slog.w(TAG, "Process/uid not found attempting kill of "
5157                            + processName + " / " + uid);
5158                }
5159            }
5160        } else {
5161            throw new SecurityException(callerUid + " cannot kill app process: " +
5162                    processName);
5163        }
5164    }
5165
5166    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5167        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5168                false, true, false, false, UserHandle.getUserId(uid), reason);
5169        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5170                Uri.fromParts("package", packageName, null));
5171        if (!mProcessesReady) {
5172            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5173                    | Intent.FLAG_RECEIVER_FOREGROUND);
5174        }
5175        intent.putExtra(Intent.EXTRA_UID, uid);
5176        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5177        broadcastIntentLocked(null, null, intent,
5178                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5179                false, false,
5180                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5181    }
5182
5183    private void forceStopUserLocked(int userId, String reason) {
5184        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5185        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5186        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5187                | Intent.FLAG_RECEIVER_FOREGROUND);
5188        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5189        broadcastIntentLocked(null, null, intent,
5190                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5191                false, false,
5192                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5193    }
5194
5195    private final boolean killPackageProcessesLocked(String packageName, int appId,
5196            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5197            boolean doit, boolean evenPersistent, String reason) {
5198        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5199
5200        // Remove all processes this package may have touched: all with the
5201        // same UID (except for the system or root user), and all whose name
5202        // matches the package name.
5203        final int NP = mProcessNames.getMap().size();
5204        for (int ip=0; ip<NP; ip++) {
5205            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5206            final int NA = apps.size();
5207            for (int ia=0; ia<NA; ia++) {
5208                ProcessRecord app = apps.valueAt(ia);
5209                if (app.persistent && !evenPersistent) {
5210                    // we don't kill persistent processes
5211                    continue;
5212                }
5213                if (app.removed) {
5214                    if (doit) {
5215                        procs.add(app);
5216                    }
5217                    continue;
5218                }
5219
5220                // Skip process if it doesn't meet our oom adj requirement.
5221                if (app.setAdj < minOomAdj) {
5222                    continue;
5223                }
5224
5225                // If no package is specified, we call all processes under the
5226                // give user id.
5227                if (packageName == null) {
5228                    if (app.userId != userId) {
5229                        continue;
5230                    }
5231                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5232                        continue;
5233                    }
5234                // Package has been specified, we want to hit all processes
5235                // that match it.  We need to qualify this by the processes
5236                // that are running under the specified app and user ID.
5237                } else {
5238                    final boolean isDep = app.pkgDeps != null
5239                            && app.pkgDeps.contains(packageName);
5240                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5241                        continue;
5242                    }
5243                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5244                        continue;
5245                    }
5246                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5247                        continue;
5248                    }
5249                }
5250
5251                // Process has passed all conditions, kill it!
5252                if (!doit) {
5253                    return true;
5254                }
5255                app.removed = true;
5256                procs.add(app);
5257            }
5258        }
5259
5260        int N = procs.size();
5261        for (int i=0; i<N; i++) {
5262            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5263        }
5264        updateOomAdjLocked();
5265        return N > 0;
5266    }
5267
5268    private final boolean forceStopPackageLocked(String name, int appId,
5269            boolean callerWillRestart, boolean purgeCache, boolean doit,
5270            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5271        int i;
5272        int N;
5273
5274        if (userId == UserHandle.USER_ALL && name == null) {
5275            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5276        }
5277
5278        if (appId < 0 && name != null) {
5279            try {
5280                appId = UserHandle.getAppId(
5281                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5282            } catch (RemoteException e) {
5283            }
5284        }
5285
5286        if (doit) {
5287            if (name != null) {
5288                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5289                        + " user=" + userId + ": " + reason);
5290            } else {
5291                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5292            }
5293
5294            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5295            for (int ip=pmap.size()-1; ip>=0; ip--) {
5296                SparseArray<Long> ba = pmap.valueAt(ip);
5297                for (i=ba.size()-1; i>=0; i--) {
5298                    boolean remove = false;
5299                    final int entUid = ba.keyAt(i);
5300                    if (name != null) {
5301                        if (userId == UserHandle.USER_ALL) {
5302                            if (UserHandle.getAppId(entUid) == appId) {
5303                                remove = true;
5304                            }
5305                        } else {
5306                            if (entUid == UserHandle.getUid(userId, appId)) {
5307                                remove = true;
5308                            }
5309                        }
5310                    } else if (UserHandle.getUserId(entUid) == userId) {
5311                        remove = true;
5312                    }
5313                    if (remove) {
5314                        ba.removeAt(i);
5315                    }
5316                }
5317                if (ba.size() == 0) {
5318                    pmap.removeAt(ip);
5319                }
5320            }
5321        }
5322
5323        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5324                -100, callerWillRestart, true, doit, evenPersistent,
5325                name == null ? ("stop user " + userId) : ("stop " + name));
5326
5327        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5328            if (!doit) {
5329                return true;
5330            }
5331            didSomething = true;
5332        }
5333
5334        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5335            if (!doit) {
5336                return true;
5337            }
5338            didSomething = true;
5339        }
5340
5341        if (name == null) {
5342            // Remove all sticky broadcasts from this user.
5343            mStickyBroadcasts.remove(userId);
5344        }
5345
5346        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5347        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5348                userId, providers)) {
5349            if (!doit) {
5350                return true;
5351            }
5352            didSomething = true;
5353        }
5354        N = providers.size();
5355        for (i=0; i<N; i++) {
5356            removeDyingProviderLocked(null, providers.get(i), true);
5357        }
5358
5359        // Remove transient permissions granted from/to this package/user
5360        removeUriPermissionsForPackageLocked(name, userId, false);
5361
5362        if (name == null || uninstalling) {
5363            // Remove pending intents.  For now we only do this when force
5364            // stopping users, because we have some problems when doing this
5365            // for packages -- app widgets are not currently cleaned up for
5366            // such packages, so they can be left with bad pending intents.
5367            if (mIntentSenderRecords.size() > 0) {
5368                Iterator<WeakReference<PendingIntentRecord>> it
5369                        = mIntentSenderRecords.values().iterator();
5370                while (it.hasNext()) {
5371                    WeakReference<PendingIntentRecord> wpir = it.next();
5372                    if (wpir == null) {
5373                        it.remove();
5374                        continue;
5375                    }
5376                    PendingIntentRecord pir = wpir.get();
5377                    if (pir == null) {
5378                        it.remove();
5379                        continue;
5380                    }
5381                    if (name == null) {
5382                        // Stopping user, remove all objects for the user.
5383                        if (pir.key.userId != userId) {
5384                            // Not the same user, skip it.
5385                            continue;
5386                        }
5387                    } else {
5388                        if (UserHandle.getAppId(pir.uid) != appId) {
5389                            // Different app id, skip it.
5390                            continue;
5391                        }
5392                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5393                            // Different user, skip it.
5394                            continue;
5395                        }
5396                        if (!pir.key.packageName.equals(name)) {
5397                            // Different package, skip it.
5398                            continue;
5399                        }
5400                    }
5401                    if (!doit) {
5402                        return true;
5403                    }
5404                    didSomething = true;
5405                    it.remove();
5406                    pir.canceled = true;
5407                    if (pir.key.activity != null) {
5408                        pir.key.activity.pendingResults.remove(pir.ref);
5409                    }
5410                }
5411            }
5412        }
5413
5414        if (doit) {
5415            if (purgeCache && name != null) {
5416                AttributeCache ac = AttributeCache.instance();
5417                if (ac != null) {
5418                    ac.removePackage(name);
5419                }
5420            }
5421            if (mBooted) {
5422                mStackSupervisor.resumeTopActivitiesLocked();
5423                mStackSupervisor.scheduleIdleLocked();
5424            }
5425        }
5426
5427        return didSomething;
5428    }
5429
5430    private final boolean removeProcessLocked(ProcessRecord app,
5431            boolean callerWillRestart, boolean allowRestart, String reason) {
5432        final String name = app.processName;
5433        final int uid = app.uid;
5434        if (DEBUG_PROCESSES) Slog.d(
5435            TAG, "Force removing proc " + app.toShortString() + " (" + name
5436            + "/" + uid + ")");
5437
5438        mProcessNames.remove(name, uid);
5439        mIsolatedProcesses.remove(app.uid);
5440        if (mHeavyWeightProcess == app) {
5441            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5442                    mHeavyWeightProcess.userId, 0));
5443            mHeavyWeightProcess = null;
5444        }
5445        boolean needRestart = false;
5446        if (app.pid > 0 && app.pid != MY_PID) {
5447            int pid = app.pid;
5448            synchronized (mPidsSelfLocked) {
5449                mPidsSelfLocked.remove(pid);
5450                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5451            }
5452            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5453            if (app.isolated) {
5454                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5455            }
5456            app.kill(reason, true);
5457            handleAppDiedLocked(app, true, allowRestart);
5458            removeLruProcessLocked(app);
5459
5460            if (app.persistent && !app.isolated) {
5461                if (!callerWillRestart) {
5462                    addAppLocked(app.info, false, null /* ABI override */);
5463                } else {
5464                    needRestart = true;
5465                }
5466            }
5467        } else {
5468            mRemovedProcesses.add(app);
5469        }
5470
5471        return needRestart;
5472    }
5473
5474    private final void processStartTimedOutLocked(ProcessRecord app) {
5475        final int pid = app.pid;
5476        boolean gone = false;
5477        synchronized (mPidsSelfLocked) {
5478            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5479            if (knownApp != null && knownApp.thread == null) {
5480                mPidsSelfLocked.remove(pid);
5481                gone = true;
5482            }
5483        }
5484
5485        if (gone) {
5486            Slog.w(TAG, "Process " + app + " failed to attach");
5487            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5488                    pid, app.uid, app.processName);
5489            mProcessNames.remove(app.processName, app.uid);
5490            mIsolatedProcesses.remove(app.uid);
5491            if (mHeavyWeightProcess == app) {
5492                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5493                        mHeavyWeightProcess.userId, 0));
5494                mHeavyWeightProcess = null;
5495            }
5496            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5497            if (app.isolated) {
5498                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5499            }
5500            // Take care of any launching providers waiting for this process.
5501            checkAppInLaunchingProvidersLocked(app, true);
5502            // Take care of any services that are waiting for the process.
5503            mServices.processStartTimedOutLocked(app);
5504            app.kill("start timeout", true);
5505            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5506                Slog.w(TAG, "Unattached app died before backup, skipping");
5507                try {
5508                    IBackupManager bm = IBackupManager.Stub.asInterface(
5509                            ServiceManager.getService(Context.BACKUP_SERVICE));
5510                    bm.agentDisconnected(app.info.packageName);
5511                } catch (RemoteException e) {
5512                    // Can't happen; the backup manager is local
5513                }
5514            }
5515            if (isPendingBroadcastProcessLocked(pid)) {
5516                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5517                skipPendingBroadcastLocked(pid);
5518            }
5519        } else {
5520            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5521        }
5522    }
5523
5524    private final boolean attachApplicationLocked(IApplicationThread thread,
5525            int pid) {
5526
5527        // Find the application record that is being attached...  either via
5528        // the pid if we are running in multiple processes, or just pull the
5529        // next app record if we are emulating process with anonymous threads.
5530        ProcessRecord app;
5531        if (pid != MY_PID && pid >= 0) {
5532            synchronized (mPidsSelfLocked) {
5533                app = mPidsSelfLocked.get(pid);
5534            }
5535        } else {
5536            app = null;
5537        }
5538
5539        if (app == null) {
5540            Slog.w(TAG, "No pending application record for pid " + pid
5541                    + " (IApplicationThread " + thread + "); dropping process");
5542            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5543            if (pid > 0 && pid != MY_PID) {
5544                Process.killProcessQuiet(pid);
5545                //TODO: Process.killProcessGroup(app.info.uid, pid);
5546            } else {
5547                try {
5548                    thread.scheduleExit();
5549                } catch (Exception e) {
5550                    // Ignore exceptions.
5551                }
5552            }
5553            return false;
5554        }
5555
5556        // If this application record is still attached to a previous
5557        // process, clean it up now.
5558        if (app.thread != null) {
5559            handleAppDiedLocked(app, true, true);
5560        }
5561
5562        // Tell the process all about itself.
5563
5564        if (localLOGV) Slog.v(
5565                TAG, "Binding process pid " + pid + " to record " + app);
5566
5567        final String processName = app.processName;
5568        try {
5569            AppDeathRecipient adr = new AppDeathRecipient(
5570                    app, pid, thread);
5571            thread.asBinder().linkToDeath(adr, 0);
5572            app.deathRecipient = adr;
5573        } catch (RemoteException e) {
5574            app.resetPackageList(mProcessStats);
5575            startProcessLocked(app, "link fail", processName);
5576            return false;
5577        }
5578
5579        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5580
5581        app.makeActive(thread, mProcessStats);
5582        app.curAdj = app.setAdj = -100;
5583        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5584        app.forcingToForeground = null;
5585        updateProcessForegroundLocked(app, false, false);
5586        app.hasShownUi = false;
5587        app.debugging = false;
5588        app.cached = false;
5589
5590        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5591
5592        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5593        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5594
5595        if (!normalMode) {
5596            Slog.i(TAG, "Launching preboot mode app: " + app);
5597        }
5598
5599        if (localLOGV) Slog.v(
5600            TAG, "New app record " + app
5601            + " thread=" + thread.asBinder() + " pid=" + pid);
5602        try {
5603            int testMode = IApplicationThread.DEBUG_OFF;
5604            if (mDebugApp != null && mDebugApp.equals(processName)) {
5605                testMode = mWaitForDebugger
5606                    ? IApplicationThread.DEBUG_WAIT
5607                    : IApplicationThread.DEBUG_ON;
5608                app.debugging = true;
5609                if (mDebugTransient) {
5610                    mDebugApp = mOrigDebugApp;
5611                    mWaitForDebugger = mOrigWaitForDebugger;
5612                }
5613            }
5614            String profileFile = app.instrumentationProfileFile;
5615            ParcelFileDescriptor profileFd = null;
5616            boolean profileAutoStop = false;
5617            if (mProfileApp != null && mProfileApp.equals(processName)) {
5618                mProfileProc = app;
5619                profileFile = mProfileFile;
5620                profileFd = mProfileFd;
5621                profileAutoStop = mAutoStopProfiler;
5622            }
5623            boolean enableOpenGlTrace = false;
5624            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5625                enableOpenGlTrace = true;
5626                mOpenGlTraceApp = null;
5627            }
5628
5629            // If the app is being launched for restore or full backup, set it up specially
5630            boolean isRestrictedBackupMode = false;
5631            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5632                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5633                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5634                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5635            }
5636
5637            ensurePackageDexOpt(app.instrumentationInfo != null
5638                    ? app.instrumentationInfo.packageName
5639                    : app.info.packageName);
5640            if (app.instrumentationClass != null) {
5641                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5642            }
5643            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5644                    + processName + " with config " + mConfiguration);
5645            ApplicationInfo appInfo = app.instrumentationInfo != null
5646                    ? app.instrumentationInfo : app.info;
5647            app.compat = compatibilityInfoForPackageLocked(appInfo);
5648            if (profileFd != null) {
5649                profileFd = profileFd.dup();
5650            }
5651            thread.bindApplication(processName, appInfo, providers,
5652                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5653                    app.instrumentationArguments, app.instrumentationWatcher,
5654                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5655                    isRestrictedBackupMode || !normalMode, app.persistent,
5656                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5657                    mCoreSettingsObserver.getCoreSettingsLocked());
5658            updateLruProcessLocked(app, false, null);
5659            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5660        } catch (Exception e) {
5661            // todo: Yikes!  What should we do?  For now we will try to
5662            // start another process, but that could easily get us in
5663            // an infinite loop of restarting processes...
5664            Slog.w(TAG, "Exception thrown during bind!", e);
5665
5666            app.resetPackageList(mProcessStats);
5667            app.unlinkDeathRecipient();
5668            startProcessLocked(app, "bind fail", processName);
5669            return false;
5670        }
5671
5672        // Remove this record from the list of starting applications.
5673        mPersistentStartingProcesses.remove(app);
5674        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5675                "Attach application locked removing on hold: " + app);
5676        mProcessesOnHold.remove(app);
5677
5678        boolean badApp = false;
5679        boolean didSomething = false;
5680
5681        // See if the top visible activity is waiting to run in this process...
5682        if (normalMode) {
5683            try {
5684                if (mStackSupervisor.attachApplicationLocked(app)) {
5685                    didSomething = true;
5686                }
5687            } catch (Exception e) {
5688                badApp = true;
5689            }
5690        }
5691
5692        // Find any services that should be running in this process...
5693        if (!badApp) {
5694            try {
5695                didSomething |= mServices.attachApplicationLocked(app, processName);
5696            } catch (Exception e) {
5697                badApp = true;
5698            }
5699        }
5700
5701        // Check if a next-broadcast receiver is in this process...
5702        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5703            try {
5704                didSomething |= sendPendingBroadcastsLocked(app);
5705            } catch (Exception e) {
5706                // If the app died trying to launch the receiver we declare it 'bad'
5707                badApp = true;
5708            }
5709        }
5710
5711        // Check whether the next backup agent is in this process...
5712        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5713            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5714            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5715            try {
5716                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5717                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5718                        mBackupTarget.backupMode);
5719            } catch (Exception e) {
5720                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5721                e.printStackTrace();
5722            }
5723        }
5724
5725        if (badApp) {
5726            // todo: Also need to kill application to deal with all
5727            // kinds of exceptions.
5728            handleAppDiedLocked(app, false, true);
5729            return false;
5730        }
5731
5732        if (!didSomething) {
5733            updateOomAdjLocked();
5734        }
5735
5736        return true;
5737    }
5738
5739    @Override
5740    public final void attachApplication(IApplicationThread thread) {
5741        synchronized (this) {
5742            int callingPid = Binder.getCallingPid();
5743            final long origId = Binder.clearCallingIdentity();
5744            attachApplicationLocked(thread, callingPid);
5745            Binder.restoreCallingIdentity(origId);
5746        }
5747    }
5748
5749    @Override
5750    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5751        final long origId = Binder.clearCallingIdentity();
5752        synchronized (this) {
5753            ActivityStack stack = ActivityRecord.getStackLocked(token);
5754            if (stack != null) {
5755                ActivityRecord r =
5756                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5757                if (stopProfiling) {
5758                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5759                        try {
5760                            mProfileFd.close();
5761                        } catch (IOException e) {
5762                        }
5763                        clearProfilerLocked();
5764                    }
5765                }
5766            }
5767        }
5768        Binder.restoreCallingIdentity(origId);
5769    }
5770
5771    void postEnableScreenAfterBootLocked() {
5772        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5773    }
5774
5775    void enableScreenAfterBoot() {
5776        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5777                SystemClock.uptimeMillis());
5778        mWindowManager.enableScreenAfterBoot();
5779
5780        synchronized (this) {
5781            updateEventDispatchingLocked();
5782        }
5783    }
5784
5785    @Override
5786    public void showBootMessage(final CharSequence msg, final boolean always) {
5787        enforceNotIsolatedCaller("showBootMessage");
5788        mWindowManager.showBootMessage(msg, always);
5789    }
5790
5791    @Override
5792    public void keyguardWaitingForActivityDrawn() {
5793        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5794        final long token = Binder.clearCallingIdentity();
5795        try {
5796            synchronized (this) {
5797                if (DEBUG_LOCKSCREEN) logLockScreen("");
5798                mWindowManager.keyguardWaitingForActivityDrawn();
5799            }
5800        } finally {
5801            Binder.restoreCallingIdentity(token);
5802        }
5803    }
5804
5805    final void finishBooting() {
5806        // Register receivers to handle package update events
5807        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5808
5809        // Let system services know.
5810        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5811
5812        synchronized (this) {
5813            // Ensure that any processes we had put on hold are now started
5814            // up.
5815            final int NP = mProcessesOnHold.size();
5816            if (NP > 0) {
5817                ArrayList<ProcessRecord> procs =
5818                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5819                for (int ip=0; ip<NP; ip++) {
5820                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5821                            + procs.get(ip));
5822                    startProcessLocked(procs.get(ip), "on-hold", null);
5823                }
5824            }
5825
5826            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5827                // Start looking for apps that are abusing wake locks.
5828                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5829                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5830                // Tell anyone interested that we are done booting!
5831                SystemProperties.set("sys.boot_completed", "1");
5832                SystemProperties.set("dev.bootcomplete", "1");
5833                for (int i=0; i<mStartedUsers.size(); i++) {
5834                    UserStartedState uss = mStartedUsers.valueAt(i);
5835                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5836                        uss.mState = UserStartedState.STATE_RUNNING;
5837                        final int userId = mStartedUsers.keyAt(i);
5838                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5839                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5840                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5841                        broadcastIntentLocked(null, null, intent, null,
5842                                new IIntentReceiver.Stub() {
5843                                    @Override
5844                                    public void performReceive(Intent intent, int resultCode,
5845                                            String data, Bundle extras, boolean ordered,
5846                                            boolean sticky, int sendingUser) {
5847                                        synchronized (ActivityManagerService.this) {
5848                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5849                                                    true, false);
5850                                        }
5851                                    }
5852                                },
5853                                0, null, null,
5854                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5855                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5856                                userId);
5857                    }
5858                }
5859                scheduleStartProfilesLocked();
5860            }
5861        }
5862    }
5863
5864    final void ensureBootCompleted() {
5865        boolean booting;
5866        boolean enableScreen;
5867        synchronized (this) {
5868            booting = mBooting;
5869            mBooting = false;
5870            enableScreen = !mBooted;
5871            mBooted = true;
5872        }
5873
5874        if (booting) {
5875            finishBooting();
5876        }
5877
5878        if (enableScreen) {
5879            enableScreenAfterBoot();
5880        }
5881    }
5882
5883    @Override
5884    public final void activityResumed(IBinder token) {
5885        final long origId = Binder.clearCallingIdentity();
5886        synchronized(this) {
5887            ActivityStack stack = ActivityRecord.getStackLocked(token);
5888            if (stack != null) {
5889                ActivityRecord.activityResumedLocked(token);
5890            }
5891        }
5892        Binder.restoreCallingIdentity(origId);
5893    }
5894
5895    @Override
5896    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5897        final long origId = Binder.clearCallingIdentity();
5898        synchronized(this) {
5899            ActivityStack stack = ActivityRecord.getStackLocked(token);
5900            if (stack != null) {
5901                stack.activityPausedLocked(token, false, persistentState);
5902            }
5903        }
5904        Binder.restoreCallingIdentity(origId);
5905    }
5906
5907    @Override
5908    public final void activityStopped(IBinder token, Bundle icicle,
5909            PersistableBundle persistentState, CharSequence description) {
5910        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5911
5912        // Refuse possible leaked file descriptors
5913        if (icicle != null && icicle.hasFileDescriptors()) {
5914            throw new IllegalArgumentException("File descriptors passed in Bundle");
5915        }
5916
5917        final long origId = Binder.clearCallingIdentity();
5918
5919        synchronized (this) {
5920            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5921            if (r != null) {
5922                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5923            }
5924        }
5925
5926        trimApplications();
5927
5928        Binder.restoreCallingIdentity(origId);
5929    }
5930
5931    @Override
5932    public final void activityDestroyed(IBinder token) {
5933        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5934        synchronized (this) {
5935            ActivityStack stack = ActivityRecord.getStackLocked(token);
5936            if (stack != null) {
5937                stack.activityDestroyedLocked(token);
5938            }
5939        }
5940    }
5941
5942    @Override
5943    public final void backgroundResourcesReleased(IBinder token) {
5944        final long origId = Binder.clearCallingIdentity();
5945        try {
5946            synchronized (this) {
5947                ActivityStack stack = ActivityRecord.getStackLocked(token);
5948                if (stack != null) {
5949                    stack.backgroundResourcesReleased(token);
5950                }
5951            }
5952        } finally {
5953            Binder.restoreCallingIdentity(origId);
5954        }
5955    }
5956
5957    @Override
5958    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5959        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5960    }
5961
5962    @Override
5963    public final void notifyEnterAnimationComplete(IBinder token) {
5964        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5965    }
5966
5967    @Override
5968    public String getCallingPackage(IBinder token) {
5969        synchronized (this) {
5970            ActivityRecord r = getCallingRecordLocked(token);
5971            return r != null ? r.info.packageName : null;
5972        }
5973    }
5974
5975    @Override
5976    public ComponentName getCallingActivity(IBinder token) {
5977        synchronized (this) {
5978            ActivityRecord r = getCallingRecordLocked(token);
5979            return r != null ? r.intent.getComponent() : null;
5980        }
5981    }
5982
5983    private ActivityRecord getCallingRecordLocked(IBinder token) {
5984        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5985        if (r == null) {
5986            return null;
5987        }
5988        return r.resultTo;
5989    }
5990
5991    @Override
5992    public ComponentName getActivityClassForToken(IBinder token) {
5993        synchronized(this) {
5994            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5995            if (r == null) {
5996                return null;
5997            }
5998            return r.intent.getComponent();
5999        }
6000    }
6001
6002    @Override
6003    public String getPackageForToken(IBinder token) {
6004        synchronized(this) {
6005            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6006            if (r == null) {
6007                return null;
6008            }
6009            return r.packageName;
6010        }
6011    }
6012
6013    @Override
6014    public IIntentSender getIntentSender(int type,
6015            String packageName, IBinder token, String resultWho,
6016            int requestCode, Intent[] intents, String[] resolvedTypes,
6017            int flags, Bundle options, int userId) {
6018        enforceNotIsolatedCaller("getIntentSender");
6019        // Refuse possible leaked file descriptors
6020        if (intents != null) {
6021            if (intents.length < 1) {
6022                throw new IllegalArgumentException("Intents array length must be >= 1");
6023            }
6024            for (int i=0; i<intents.length; i++) {
6025                Intent intent = intents[i];
6026                if (intent != null) {
6027                    if (intent.hasFileDescriptors()) {
6028                        throw new IllegalArgumentException("File descriptors passed in Intent");
6029                    }
6030                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6031                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6032                        throw new IllegalArgumentException(
6033                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6034                    }
6035                    intents[i] = new Intent(intent);
6036                }
6037            }
6038            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6039                throw new IllegalArgumentException(
6040                        "Intent array length does not match resolvedTypes length");
6041            }
6042        }
6043        if (options != null) {
6044            if (options.hasFileDescriptors()) {
6045                throw new IllegalArgumentException("File descriptors passed in options");
6046            }
6047        }
6048
6049        synchronized(this) {
6050            int callingUid = Binder.getCallingUid();
6051            int origUserId = userId;
6052            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6053                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6054                    ALLOW_NON_FULL, "getIntentSender", null);
6055            if (origUserId == UserHandle.USER_CURRENT) {
6056                // We don't want to evaluate this until the pending intent is
6057                // actually executed.  However, we do want to always do the
6058                // security checking for it above.
6059                userId = UserHandle.USER_CURRENT;
6060            }
6061            try {
6062                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6063                    int uid = AppGlobals.getPackageManager()
6064                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6065                    if (!UserHandle.isSameApp(callingUid, uid)) {
6066                        String msg = "Permission Denial: getIntentSender() from pid="
6067                            + Binder.getCallingPid()
6068                            + ", uid=" + Binder.getCallingUid()
6069                            + ", (need uid=" + uid + ")"
6070                            + " is not allowed to send as package " + packageName;
6071                        Slog.w(TAG, msg);
6072                        throw new SecurityException(msg);
6073                    }
6074                }
6075
6076                return getIntentSenderLocked(type, packageName, callingUid, userId,
6077                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6078
6079            } catch (RemoteException e) {
6080                throw new SecurityException(e);
6081            }
6082        }
6083    }
6084
6085    IIntentSender getIntentSenderLocked(int type, String packageName,
6086            int callingUid, int userId, IBinder token, String resultWho,
6087            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6088            Bundle options) {
6089        if (DEBUG_MU)
6090            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6091        ActivityRecord activity = null;
6092        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6093            activity = ActivityRecord.isInStackLocked(token);
6094            if (activity == null) {
6095                return null;
6096            }
6097            if (activity.finishing) {
6098                return null;
6099            }
6100        }
6101
6102        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6103        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6104        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6105        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6106                |PendingIntent.FLAG_UPDATE_CURRENT);
6107
6108        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6109                type, packageName, activity, resultWho,
6110                requestCode, intents, resolvedTypes, flags, options, userId);
6111        WeakReference<PendingIntentRecord> ref;
6112        ref = mIntentSenderRecords.get(key);
6113        PendingIntentRecord rec = ref != null ? ref.get() : null;
6114        if (rec != null) {
6115            if (!cancelCurrent) {
6116                if (updateCurrent) {
6117                    if (rec.key.requestIntent != null) {
6118                        rec.key.requestIntent.replaceExtras(intents != null ?
6119                                intents[intents.length - 1] : null);
6120                    }
6121                    if (intents != null) {
6122                        intents[intents.length-1] = rec.key.requestIntent;
6123                        rec.key.allIntents = intents;
6124                        rec.key.allResolvedTypes = resolvedTypes;
6125                    } else {
6126                        rec.key.allIntents = null;
6127                        rec.key.allResolvedTypes = null;
6128                    }
6129                }
6130                return rec;
6131            }
6132            rec.canceled = true;
6133            mIntentSenderRecords.remove(key);
6134        }
6135        if (noCreate) {
6136            return rec;
6137        }
6138        rec = new PendingIntentRecord(this, key, callingUid);
6139        mIntentSenderRecords.put(key, rec.ref);
6140        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6141            if (activity.pendingResults == null) {
6142                activity.pendingResults
6143                        = new HashSet<WeakReference<PendingIntentRecord>>();
6144            }
6145            activity.pendingResults.add(rec.ref);
6146        }
6147        return rec;
6148    }
6149
6150    @Override
6151    public void cancelIntentSender(IIntentSender sender) {
6152        if (!(sender instanceof PendingIntentRecord)) {
6153            return;
6154        }
6155        synchronized(this) {
6156            PendingIntentRecord rec = (PendingIntentRecord)sender;
6157            try {
6158                int uid = AppGlobals.getPackageManager()
6159                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6160                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6161                    String msg = "Permission Denial: cancelIntentSender() from pid="
6162                        + Binder.getCallingPid()
6163                        + ", uid=" + Binder.getCallingUid()
6164                        + " is not allowed to cancel packges "
6165                        + rec.key.packageName;
6166                    Slog.w(TAG, msg);
6167                    throw new SecurityException(msg);
6168                }
6169            } catch (RemoteException e) {
6170                throw new SecurityException(e);
6171            }
6172            cancelIntentSenderLocked(rec, true);
6173        }
6174    }
6175
6176    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6177        rec.canceled = true;
6178        mIntentSenderRecords.remove(rec.key);
6179        if (cleanActivity && rec.key.activity != null) {
6180            rec.key.activity.pendingResults.remove(rec.ref);
6181        }
6182    }
6183
6184    @Override
6185    public String getPackageForIntentSender(IIntentSender pendingResult) {
6186        if (!(pendingResult instanceof PendingIntentRecord)) {
6187            return null;
6188        }
6189        try {
6190            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6191            return res.key.packageName;
6192        } catch (ClassCastException e) {
6193        }
6194        return null;
6195    }
6196
6197    @Override
6198    public int getUidForIntentSender(IIntentSender sender) {
6199        if (sender instanceof PendingIntentRecord) {
6200            try {
6201                PendingIntentRecord res = (PendingIntentRecord)sender;
6202                return res.uid;
6203            } catch (ClassCastException e) {
6204            }
6205        }
6206        return -1;
6207    }
6208
6209    @Override
6210    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6211        if (!(pendingResult instanceof PendingIntentRecord)) {
6212            return false;
6213        }
6214        try {
6215            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6216            if (res.key.allIntents == null) {
6217                return false;
6218            }
6219            for (int i=0; i<res.key.allIntents.length; i++) {
6220                Intent intent = res.key.allIntents[i];
6221                if (intent.getPackage() != null && intent.getComponent() != null) {
6222                    return false;
6223                }
6224            }
6225            return true;
6226        } catch (ClassCastException e) {
6227        }
6228        return false;
6229    }
6230
6231    @Override
6232    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6233        if (!(pendingResult instanceof PendingIntentRecord)) {
6234            return false;
6235        }
6236        try {
6237            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6238            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6239                return true;
6240            }
6241            return false;
6242        } catch (ClassCastException e) {
6243        }
6244        return false;
6245    }
6246
6247    @Override
6248    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6249        if (!(pendingResult instanceof PendingIntentRecord)) {
6250            return null;
6251        }
6252        try {
6253            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6254            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6255        } catch (ClassCastException e) {
6256        }
6257        return null;
6258    }
6259
6260    @Override
6261    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6262        if (!(pendingResult instanceof PendingIntentRecord)) {
6263            return null;
6264        }
6265        try {
6266            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6267            Intent intent = res.key.requestIntent;
6268            if (intent != null) {
6269                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6270                        || res.lastTagPrefix.equals(prefix))) {
6271                    return res.lastTag;
6272                }
6273                res.lastTagPrefix = prefix;
6274                StringBuilder sb = new StringBuilder(128);
6275                if (prefix != null) {
6276                    sb.append(prefix);
6277                }
6278                if (intent.getAction() != null) {
6279                    sb.append(intent.getAction());
6280                } else if (intent.getComponent() != null) {
6281                    intent.getComponent().appendShortString(sb);
6282                } else {
6283                    sb.append("?");
6284                }
6285                return res.lastTag = sb.toString();
6286            }
6287        } catch (ClassCastException e) {
6288        }
6289        return null;
6290    }
6291
6292    @Override
6293    public void setProcessLimit(int max) {
6294        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6295                "setProcessLimit()");
6296        synchronized (this) {
6297            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6298            mProcessLimitOverride = max;
6299        }
6300        trimApplications();
6301    }
6302
6303    @Override
6304    public int getProcessLimit() {
6305        synchronized (this) {
6306            return mProcessLimitOverride;
6307        }
6308    }
6309
6310    void foregroundTokenDied(ForegroundToken token) {
6311        synchronized (ActivityManagerService.this) {
6312            synchronized (mPidsSelfLocked) {
6313                ForegroundToken cur
6314                    = mForegroundProcesses.get(token.pid);
6315                if (cur != token) {
6316                    return;
6317                }
6318                mForegroundProcesses.remove(token.pid);
6319                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6320                if (pr == null) {
6321                    return;
6322                }
6323                pr.forcingToForeground = null;
6324                updateProcessForegroundLocked(pr, false, false);
6325            }
6326            updateOomAdjLocked();
6327        }
6328    }
6329
6330    @Override
6331    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6332        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6333                "setProcessForeground()");
6334        synchronized(this) {
6335            boolean changed = false;
6336
6337            synchronized (mPidsSelfLocked) {
6338                ProcessRecord pr = mPidsSelfLocked.get(pid);
6339                if (pr == null && isForeground) {
6340                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6341                    return;
6342                }
6343                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6344                if (oldToken != null) {
6345                    oldToken.token.unlinkToDeath(oldToken, 0);
6346                    mForegroundProcesses.remove(pid);
6347                    if (pr != null) {
6348                        pr.forcingToForeground = null;
6349                    }
6350                    changed = true;
6351                }
6352                if (isForeground && token != null) {
6353                    ForegroundToken newToken = new ForegroundToken() {
6354                        @Override
6355                        public void binderDied() {
6356                            foregroundTokenDied(this);
6357                        }
6358                    };
6359                    newToken.pid = pid;
6360                    newToken.token = token;
6361                    try {
6362                        token.linkToDeath(newToken, 0);
6363                        mForegroundProcesses.put(pid, newToken);
6364                        pr.forcingToForeground = token;
6365                        changed = true;
6366                    } catch (RemoteException e) {
6367                        // If the process died while doing this, we will later
6368                        // do the cleanup with the process death link.
6369                    }
6370                }
6371            }
6372
6373            if (changed) {
6374                updateOomAdjLocked();
6375            }
6376        }
6377    }
6378
6379    // =========================================================
6380    // PERMISSIONS
6381    // =========================================================
6382
6383    static class PermissionController extends IPermissionController.Stub {
6384        ActivityManagerService mActivityManagerService;
6385        PermissionController(ActivityManagerService activityManagerService) {
6386            mActivityManagerService = activityManagerService;
6387        }
6388
6389        @Override
6390        public boolean checkPermission(String permission, int pid, int uid) {
6391            return mActivityManagerService.checkPermission(permission, pid,
6392                    uid) == PackageManager.PERMISSION_GRANTED;
6393        }
6394    }
6395
6396    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6397        @Override
6398        public int checkComponentPermission(String permission, int pid, int uid,
6399                int owningUid, boolean exported) {
6400            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6401                    owningUid, exported);
6402        }
6403
6404        @Override
6405        public Object getAMSLock() {
6406            return ActivityManagerService.this;
6407        }
6408    }
6409
6410    /**
6411     * This can be called with or without the global lock held.
6412     */
6413    int checkComponentPermission(String permission, int pid, int uid,
6414            int owningUid, boolean exported) {
6415        // We might be performing an operation on behalf of an indirect binder
6416        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6417        // client identity accordingly before proceeding.
6418        Identity tlsIdentity = sCallerIdentity.get();
6419        if (tlsIdentity != null) {
6420            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6421                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6422            uid = tlsIdentity.uid;
6423            pid = tlsIdentity.pid;
6424        }
6425
6426        if (pid == MY_PID) {
6427            return PackageManager.PERMISSION_GRANTED;
6428        }
6429
6430        return ActivityManager.checkComponentPermission(permission, uid,
6431                owningUid, exported);
6432    }
6433
6434    /**
6435     * As the only public entry point for permissions checking, this method
6436     * can enforce the semantic that requesting a check on a null global
6437     * permission is automatically denied.  (Internally a null permission
6438     * string is used when calling {@link #checkComponentPermission} in cases
6439     * when only uid-based security is needed.)
6440     *
6441     * This can be called with or without the global lock held.
6442     */
6443    @Override
6444    public int checkPermission(String permission, int pid, int uid) {
6445        if (permission == null) {
6446            return PackageManager.PERMISSION_DENIED;
6447        }
6448        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6449    }
6450
6451    /**
6452     * Binder IPC calls go through the public entry point.
6453     * This can be called with or without the global lock held.
6454     */
6455    int checkCallingPermission(String permission) {
6456        return checkPermission(permission,
6457                Binder.getCallingPid(),
6458                UserHandle.getAppId(Binder.getCallingUid()));
6459    }
6460
6461    /**
6462     * This can be called with or without the global lock held.
6463     */
6464    void enforceCallingPermission(String permission, String func) {
6465        if (checkCallingPermission(permission)
6466                == PackageManager.PERMISSION_GRANTED) {
6467            return;
6468        }
6469
6470        String msg = "Permission Denial: " + func + " from pid="
6471                + Binder.getCallingPid()
6472                + ", uid=" + Binder.getCallingUid()
6473                + " requires " + permission;
6474        Slog.w(TAG, msg);
6475        throw new SecurityException(msg);
6476    }
6477
6478    /**
6479     * Determine if UID is holding permissions required to access {@link Uri} in
6480     * the given {@link ProviderInfo}. Final permission checking is always done
6481     * in {@link ContentProvider}.
6482     */
6483    private final boolean checkHoldingPermissionsLocked(
6484            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6485        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6486                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6487        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6488            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6489                    != PERMISSION_GRANTED) {
6490                return false;
6491            }
6492        }
6493        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6494    }
6495
6496    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6497            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6498        if (pi.applicationInfo.uid == uid) {
6499            return true;
6500        } else if (!pi.exported) {
6501            return false;
6502        }
6503
6504        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6505        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6506        try {
6507            // check if target holds top-level <provider> permissions
6508            if (!readMet && pi.readPermission != null && considerUidPermissions
6509                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6510                readMet = true;
6511            }
6512            if (!writeMet && pi.writePermission != null && considerUidPermissions
6513                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6514                writeMet = true;
6515            }
6516
6517            // track if unprotected read/write is allowed; any denied
6518            // <path-permission> below removes this ability
6519            boolean allowDefaultRead = pi.readPermission == null;
6520            boolean allowDefaultWrite = pi.writePermission == null;
6521
6522            // check if target holds any <path-permission> that match uri
6523            final PathPermission[] pps = pi.pathPermissions;
6524            if (pps != null) {
6525                final String path = grantUri.uri.getPath();
6526                int i = pps.length;
6527                while (i > 0 && (!readMet || !writeMet)) {
6528                    i--;
6529                    PathPermission pp = pps[i];
6530                    if (pp.match(path)) {
6531                        if (!readMet) {
6532                            final String pprperm = pp.getReadPermission();
6533                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6534                                    + pprperm + " for " + pp.getPath()
6535                                    + ": match=" + pp.match(path)
6536                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6537                            if (pprperm != null) {
6538                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6539                                        == PERMISSION_GRANTED) {
6540                                    readMet = true;
6541                                } else {
6542                                    allowDefaultRead = false;
6543                                }
6544                            }
6545                        }
6546                        if (!writeMet) {
6547                            final String ppwperm = pp.getWritePermission();
6548                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6549                                    + ppwperm + " for " + pp.getPath()
6550                                    + ": match=" + pp.match(path)
6551                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6552                            if (ppwperm != null) {
6553                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6554                                        == PERMISSION_GRANTED) {
6555                                    writeMet = true;
6556                                } else {
6557                                    allowDefaultWrite = false;
6558                                }
6559                            }
6560                        }
6561                    }
6562                }
6563            }
6564
6565            // grant unprotected <provider> read/write, if not blocked by
6566            // <path-permission> above
6567            if (allowDefaultRead) readMet = true;
6568            if (allowDefaultWrite) writeMet = true;
6569
6570        } catch (RemoteException e) {
6571            return false;
6572        }
6573
6574        return readMet && writeMet;
6575    }
6576
6577    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6578        ProviderInfo pi = null;
6579        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6580        if (cpr != null) {
6581            pi = cpr.info;
6582        } else {
6583            try {
6584                pi = AppGlobals.getPackageManager().resolveContentProvider(
6585                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6586            } catch (RemoteException ex) {
6587            }
6588        }
6589        return pi;
6590    }
6591
6592    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6593        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6594        if (targetUris != null) {
6595            return targetUris.get(grantUri);
6596        }
6597        return null;
6598    }
6599
6600    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6601            String targetPkg, int targetUid, GrantUri grantUri) {
6602        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6603        if (targetUris == null) {
6604            targetUris = Maps.newArrayMap();
6605            mGrantedUriPermissions.put(targetUid, targetUris);
6606        }
6607
6608        UriPermission perm = targetUris.get(grantUri);
6609        if (perm == null) {
6610            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6611            targetUris.put(grantUri, perm);
6612        }
6613
6614        return perm;
6615    }
6616
6617    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6618            final int modeFlags) {
6619        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6620        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6621                : UriPermission.STRENGTH_OWNED;
6622
6623        // Root gets to do everything.
6624        if (uid == 0) {
6625            return true;
6626        }
6627
6628        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6629        if (perms == null) return false;
6630
6631        // First look for exact match
6632        final UriPermission exactPerm = perms.get(grantUri);
6633        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6634            return true;
6635        }
6636
6637        // No exact match, look for prefixes
6638        final int N = perms.size();
6639        for (int i = 0; i < N; i++) {
6640            final UriPermission perm = perms.valueAt(i);
6641            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6642                    && perm.getStrength(modeFlags) >= minStrength) {
6643                return true;
6644            }
6645        }
6646
6647        return false;
6648    }
6649
6650    /**
6651     * @param uri This uri must NOT contain an embedded userId.
6652     * @param userId The userId in which the uri is to be resolved.
6653     */
6654    @Override
6655    public int checkUriPermission(Uri uri, int pid, int uid,
6656            final int modeFlags, int userId) {
6657        enforceNotIsolatedCaller("checkUriPermission");
6658
6659        // Another redirected-binder-call permissions check as in
6660        // {@link checkComponentPermission}.
6661        Identity tlsIdentity = sCallerIdentity.get();
6662        if (tlsIdentity != null) {
6663            uid = tlsIdentity.uid;
6664            pid = tlsIdentity.pid;
6665        }
6666
6667        // Our own process gets to do everything.
6668        if (pid == MY_PID) {
6669            return PackageManager.PERMISSION_GRANTED;
6670        }
6671        synchronized (this) {
6672            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6673                    ? PackageManager.PERMISSION_GRANTED
6674                    : PackageManager.PERMISSION_DENIED;
6675        }
6676    }
6677
6678    /**
6679     * Check if the targetPkg can be granted permission to access uri by
6680     * the callingUid using the given modeFlags.  Throws a security exception
6681     * if callingUid is not allowed to do this.  Returns the uid of the target
6682     * if the URI permission grant should be performed; returns -1 if it is not
6683     * needed (for example targetPkg already has permission to access the URI).
6684     * If you already know the uid of the target, you can supply it in
6685     * lastTargetUid else set that to -1.
6686     */
6687    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6688            final int modeFlags, int lastTargetUid) {
6689        if (!Intent.isAccessUriMode(modeFlags)) {
6690            return -1;
6691        }
6692
6693        if (targetPkg != null) {
6694            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6695                    "Checking grant " + targetPkg + " permission to " + grantUri);
6696        }
6697
6698        final IPackageManager pm = AppGlobals.getPackageManager();
6699
6700        // If this is not a content: uri, we can't do anything with it.
6701        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6702            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6703                    "Can't grant URI permission for non-content URI: " + grantUri);
6704            return -1;
6705        }
6706
6707        final String authority = grantUri.uri.getAuthority();
6708        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6709        if (pi == null) {
6710            Slog.w(TAG, "No content provider found for permission check: " +
6711                    grantUri.uri.toSafeString());
6712            return -1;
6713        }
6714
6715        int targetUid = lastTargetUid;
6716        if (targetUid < 0 && targetPkg != null) {
6717            try {
6718                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6719                if (targetUid < 0) {
6720                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6721                            "Can't grant URI permission no uid for: " + targetPkg);
6722                    return -1;
6723                }
6724            } catch (RemoteException ex) {
6725                return -1;
6726            }
6727        }
6728
6729        if (targetUid >= 0) {
6730            // First...  does the target actually need this permission?
6731            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6732                // No need to grant the target this permission.
6733                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6734                        "Target " + targetPkg + " already has full permission to " + grantUri);
6735                return -1;
6736            }
6737        } else {
6738            // First...  there is no target package, so can anyone access it?
6739            boolean allowed = pi.exported;
6740            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6741                if (pi.readPermission != null) {
6742                    allowed = false;
6743                }
6744            }
6745            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6746                if (pi.writePermission != null) {
6747                    allowed = false;
6748                }
6749            }
6750            if (allowed) {
6751                return -1;
6752            }
6753        }
6754
6755        /* There is a special cross user grant if:
6756         * - The target is on another user.
6757         * - Apps on the current user can access the uri without any uid permissions.
6758         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6759         * grant uri permissions.
6760         */
6761        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6762                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6763                modeFlags, false /*without considering the uid permissions*/);
6764
6765        // Second...  is the provider allowing granting of URI permissions?
6766        if (!specialCrossUserGrant) {
6767            if (!pi.grantUriPermissions) {
6768                throw new SecurityException("Provider " + pi.packageName
6769                        + "/" + pi.name
6770                        + " does not allow granting of Uri permissions (uri "
6771                        + grantUri + ")");
6772            }
6773            if (pi.uriPermissionPatterns != null) {
6774                final int N = pi.uriPermissionPatterns.length;
6775                boolean allowed = false;
6776                for (int i=0; i<N; i++) {
6777                    if (pi.uriPermissionPatterns[i] != null
6778                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6779                        allowed = true;
6780                        break;
6781                    }
6782                }
6783                if (!allowed) {
6784                    throw new SecurityException("Provider " + pi.packageName
6785                            + "/" + pi.name
6786                            + " does not allow granting of permission to path of Uri "
6787                            + grantUri);
6788                }
6789            }
6790        }
6791
6792        // Third...  does the caller itself have permission to access
6793        // this uri?
6794        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6795            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6796                // Require they hold a strong enough Uri permission
6797                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6798                    throw new SecurityException("Uid " + callingUid
6799                            + " does not have permission to uri " + grantUri);
6800                }
6801            }
6802        }
6803        return targetUid;
6804    }
6805
6806    /**
6807     * @param uri This uri must NOT contain an embedded userId.
6808     * @param userId The userId in which the uri is to be resolved.
6809     */
6810    @Override
6811    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6812            final int modeFlags, int userId) {
6813        enforceNotIsolatedCaller("checkGrantUriPermission");
6814        synchronized(this) {
6815            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6816                    new GrantUri(userId, uri, false), modeFlags, -1);
6817        }
6818    }
6819
6820    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6821            final int modeFlags, UriPermissionOwner owner) {
6822        if (!Intent.isAccessUriMode(modeFlags)) {
6823            return;
6824        }
6825
6826        // So here we are: the caller has the assumed permission
6827        // to the uri, and the target doesn't.  Let's now give this to
6828        // the target.
6829
6830        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6831                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6832
6833        final String authority = grantUri.uri.getAuthority();
6834        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6835        if (pi == null) {
6836            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6837            return;
6838        }
6839
6840        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6841            grantUri.prefix = true;
6842        }
6843        final UriPermission perm = findOrCreateUriPermissionLocked(
6844                pi.packageName, targetPkg, targetUid, grantUri);
6845        perm.grantModes(modeFlags, owner);
6846    }
6847
6848    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6849            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6850        if (targetPkg == null) {
6851            throw new NullPointerException("targetPkg");
6852        }
6853        int targetUid;
6854        final IPackageManager pm = AppGlobals.getPackageManager();
6855        try {
6856            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6857        } catch (RemoteException ex) {
6858            return;
6859        }
6860
6861        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6862                targetUid);
6863        if (targetUid < 0) {
6864            return;
6865        }
6866
6867        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6868                owner);
6869    }
6870
6871    static class NeededUriGrants extends ArrayList<GrantUri> {
6872        final String targetPkg;
6873        final int targetUid;
6874        final int flags;
6875
6876        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6877            this.targetPkg = targetPkg;
6878            this.targetUid = targetUid;
6879            this.flags = flags;
6880        }
6881    }
6882
6883    /**
6884     * Like checkGrantUriPermissionLocked, but takes an Intent.
6885     */
6886    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6887            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6888        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6889                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6890                + " clip=" + (intent != null ? intent.getClipData() : null)
6891                + " from " + intent + "; flags=0x"
6892                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6893
6894        if (targetPkg == null) {
6895            throw new NullPointerException("targetPkg");
6896        }
6897
6898        if (intent == null) {
6899            return null;
6900        }
6901        Uri data = intent.getData();
6902        ClipData clip = intent.getClipData();
6903        if (data == null && clip == null) {
6904            return null;
6905        }
6906        // Default userId for uris in the intent (if they don't specify it themselves)
6907        int contentUserHint = intent.getContentUserHint();
6908        if (contentUserHint == UserHandle.USER_CURRENT) {
6909            contentUserHint = UserHandle.getUserId(callingUid);
6910        }
6911        final IPackageManager pm = AppGlobals.getPackageManager();
6912        int targetUid;
6913        if (needed != null) {
6914            targetUid = needed.targetUid;
6915        } else {
6916            try {
6917                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6918            } catch (RemoteException ex) {
6919                return null;
6920            }
6921            if (targetUid < 0) {
6922                if (DEBUG_URI_PERMISSION) {
6923                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6924                            + " on user " + targetUserId);
6925                }
6926                return null;
6927            }
6928        }
6929        if (data != null) {
6930            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6931            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6932                    targetUid);
6933            if (targetUid > 0) {
6934                if (needed == null) {
6935                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6936                }
6937                needed.add(grantUri);
6938            }
6939        }
6940        if (clip != null) {
6941            for (int i=0; i<clip.getItemCount(); i++) {
6942                Uri uri = clip.getItemAt(i).getUri();
6943                if (uri != null) {
6944                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6945                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6946                            targetUid);
6947                    if (targetUid > 0) {
6948                        if (needed == null) {
6949                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6950                        }
6951                        needed.add(grantUri);
6952                    }
6953                } else {
6954                    Intent clipIntent = clip.getItemAt(i).getIntent();
6955                    if (clipIntent != null) {
6956                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6957                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6958                        if (newNeeded != null) {
6959                            needed = newNeeded;
6960                        }
6961                    }
6962                }
6963            }
6964        }
6965
6966        return needed;
6967    }
6968
6969    /**
6970     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6971     */
6972    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6973            UriPermissionOwner owner) {
6974        if (needed != null) {
6975            for (int i=0; i<needed.size(); i++) {
6976                GrantUri grantUri = needed.get(i);
6977                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6978                        grantUri, needed.flags, owner);
6979            }
6980        }
6981    }
6982
6983    void grantUriPermissionFromIntentLocked(int callingUid,
6984            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6985        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6986                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6987        if (needed == null) {
6988            return;
6989        }
6990
6991        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6992    }
6993
6994    /**
6995     * @param uri This uri must NOT contain an embedded userId.
6996     * @param userId The userId in which the uri is to be resolved.
6997     */
6998    @Override
6999    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7000            final int modeFlags, int userId) {
7001        enforceNotIsolatedCaller("grantUriPermission");
7002        GrantUri grantUri = new GrantUri(userId, uri, false);
7003        synchronized(this) {
7004            final ProcessRecord r = getRecordForAppLocked(caller);
7005            if (r == null) {
7006                throw new SecurityException("Unable to find app for caller "
7007                        + caller
7008                        + " when granting permission to uri " + grantUri);
7009            }
7010            if (targetPkg == null) {
7011                throw new IllegalArgumentException("null target");
7012            }
7013            if (grantUri == null) {
7014                throw new IllegalArgumentException("null uri");
7015            }
7016
7017            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7018                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7019                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7020                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7021
7022            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7023                    UserHandle.getUserId(r.uid));
7024        }
7025    }
7026
7027    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7028        if (perm.modeFlags == 0) {
7029            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7030                    perm.targetUid);
7031            if (perms != null) {
7032                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7033                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7034
7035                perms.remove(perm.uri);
7036                if (perms.isEmpty()) {
7037                    mGrantedUriPermissions.remove(perm.targetUid);
7038                }
7039            }
7040        }
7041    }
7042
7043    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7044        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7045
7046        final IPackageManager pm = AppGlobals.getPackageManager();
7047        final String authority = grantUri.uri.getAuthority();
7048        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7049        if (pi == null) {
7050            Slog.w(TAG, "No content provider found for permission revoke: "
7051                    + grantUri.toSafeString());
7052            return;
7053        }
7054
7055        // Does the caller have this permission on the URI?
7056        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7057            // Right now, if you are not the original owner of the permission,
7058            // you are not allowed to revoke it.
7059            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7060                throw new SecurityException("Uid " + callingUid
7061                        + " does not have permission to uri " + grantUri);
7062            //}
7063        }
7064
7065        boolean persistChanged = false;
7066
7067        // Go through all of the permissions and remove any that match.
7068        int N = mGrantedUriPermissions.size();
7069        for (int i = 0; i < N; i++) {
7070            final int targetUid = mGrantedUriPermissions.keyAt(i);
7071            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7072
7073            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7074                final UriPermission perm = it.next();
7075                if (perm.uri.sourceUserId == grantUri.sourceUserId
7076                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7077                    if (DEBUG_URI_PERMISSION)
7078                        Slog.v(TAG,
7079                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7080                    persistChanged |= perm.revokeModes(
7081                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7082                    if (perm.modeFlags == 0) {
7083                        it.remove();
7084                    }
7085                }
7086            }
7087
7088            if (perms.isEmpty()) {
7089                mGrantedUriPermissions.remove(targetUid);
7090                N--;
7091                i--;
7092            }
7093        }
7094
7095        if (persistChanged) {
7096            schedulePersistUriGrants();
7097        }
7098    }
7099
7100    /**
7101     * @param uri This uri must NOT contain an embedded userId.
7102     * @param userId The userId in which the uri is to be resolved.
7103     */
7104    @Override
7105    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7106            int userId) {
7107        enforceNotIsolatedCaller("revokeUriPermission");
7108        synchronized(this) {
7109            final ProcessRecord r = getRecordForAppLocked(caller);
7110            if (r == null) {
7111                throw new SecurityException("Unable to find app for caller "
7112                        + caller
7113                        + " when revoking permission to uri " + uri);
7114            }
7115            if (uri == null) {
7116                Slog.w(TAG, "revokeUriPermission: null uri");
7117                return;
7118            }
7119
7120            if (!Intent.isAccessUriMode(modeFlags)) {
7121                return;
7122            }
7123
7124            final IPackageManager pm = AppGlobals.getPackageManager();
7125            final String authority = uri.getAuthority();
7126            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7127            if (pi == null) {
7128                Slog.w(TAG, "No content provider found for permission revoke: "
7129                        + uri.toSafeString());
7130                return;
7131            }
7132
7133            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7134        }
7135    }
7136
7137    /**
7138     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7139     * given package.
7140     *
7141     * @param packageName Package name to match, or {@code null} to apply to all
7142     *            packages.
7143     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7144     *            to all users.
7145     * @param persistable If persistable grants should be removed.
7146     */
7147    private void removeUriPermissionsForPackageLocked(
7148            String packageName, int userHandle, boolean persistable) {
7149        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7150            throw new IllegalArgumentException("Must narrow by either package or user");
7151        }
7152
7153        boolean persistChanged = false;
7154
7155        int N = mGrantedUriPermissions.size();
7156        for (int i = 0; i < N; i++) {
7157            final int targetUid = mGrantedUriPermissions.keyAt(i);
7158            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7159
7160            // Only inspect grants matching user
7161            if (userHandle == UserHandle.USER_ALL
7162                    || userHandle == UserHandle.getUserId(targetUid)) {
7163                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7164                    final UriPermission perm = it.next();
7165
7166                    // Only inspect grants matching package
7167                    if (packageName == null || perm.sourcePkg.equals(packageName)
7168                            || perm.targetPkg.equals(packageName)) {
7169                        persistChanged |= perm.revokeModes(
7170                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7171
7172                        // Only remove when no modes remain; any persisted grants
7173                        // will keep this alive.
7174                        if (perm.modeFlags == 0) {
7175                            it.remove();
7176                        }
7177                    }
7178                }
7179
7180                if (perms.isEmpty()) {
7181                    mGrantedUriPermissions.remove(targetUid);
7182                    N--;
7183                    i--;
7184                }
7185            }
7186        }
7187
7188        if (persistChanged) {
7189            schedulePersistUriGrants();
7190        }
7191    }
7192
7193    @Override
7194    public IBinder newUriPermissionOwner(String name) {
7195        enforceNotIsolatedCaller("newUriPermissionOwner");
7196        synchronized(this) {
7197            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7198            return owner.getExternalTokenLocked();
7199        }
7200    }
7201
7202    /**
7203     * @param uri This uri must NOT contain an embedded userId.
7204     * @param sourceUserId The userId in which the uri is to be resolved.
7205     * @param targetUserId The userId of the app that receives the grant.
7206     */
7207    @Override
7208    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7209            final int modeFlags, int sourceUserId, int targetUserId) {
7210        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7211                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7212        synchronized(this) {
7213            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7214            if (owner == null) {
7215                throw new IllegalArgumentException("Unknown owner: " + token);
7216            }
7217            if (fromUid != Binder.getCallingUid()) {
7218                if (Binder.getCallingUid() != Process.myUid()) {
7219                    // Only system code can grant URI permissions on behalf
7220                    // of other users.
7221                    throw new SecurityException("nice try");
7222                }
7223            }
7224            if (targetPkg == null) {
7225                throw new IllegalArgumentException("null target");
7226            }
7227            if (uri == null) {
7228                throw new IllegalArgumentException("null uri");
7229            }
7230
7231            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7232                    modeFlags, owner, targetUserId);
7233        }
7234    }
7235
7236    /**
7237     * @param uri This uri must NOT contain an embedded userId.
7238     * @param userId The userId in which the uri is to be resolved.
7239     */
7240    @Override
7241    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7242        synchronized(this) {
7243            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7244            if (owner == null) {
7245                throw new IllegalArgumentException("Unknown owner: " + token);
7246            }
7247
7248            if (uri == null) {
7249                owner.removeUriPermissionsLocked(mode);
7250            } else {
7251                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7252            }
7253        }
7254    }
7255
7256    private void schedulePersistUriGrants() {
7257        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7258            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7259                    10 * DateUtils.SECOND_IN_MILLIS);
7260        }
7261    }
7262
7263    private void writeGrantedUriPermissions() {
7264        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7265
7266        // Snapshot permissions so we can persist without lock
7267        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7268        synchronized (this) {
7269            final int size = mGrantedUriPermissions.size();
7270            for (int i = 0; i < size; i++) {
7271                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7272                for (UriPermission perm : perms.values()) {
7273                    if (perm.persistedModeFlags != 0) {
7274                        persist.add(perm.snapshot());
7275                    }
7276                }
7277            }
7278        }
7279
7280        FileOutputStream fos = null;
7281        try {
7282            fos = mGrantFile.startWrite();
7283
7284            XmlSerializer out = new FastXmlSerializer();
7285            out.setOutput(fos, "utf-8");
7286            out.startDocument(null, true);
7287            out.startTag(null, TAG_URI_GRANTS);
7288            for (UriPermission.Snapshot perm : persist) {
7289                out.startTag(null, TAG_URI_GRANT);
7290                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7291                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7292                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7293                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7294                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7295                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7296                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7297                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7298                out.endTag(null, TAG_URI_GRANT);
7299            }
7300            out.endTag(null, TAG_URI_GRANTS);
7301            out.endDocument();
7302
7303            mGrantFile.finishWrite(fos);
7304        } catch (IOException e) {
7305            if (fos != null) {
7306                mGrantFile.failWrite(fos);
7307            }
7308        }
7309    }
7310
7311    private void readGrantedUriPermissionsLocked() {
7312        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7313
7314        final long now = System.currentTimeMillis();
7315
7316        FileInputStream fis = null;
7317        try {
7318            fis = mGrantFile.openRead();
7319            final XmlPullParser in = Xml.newPullParser();
7320            in.setInput(fis, null);
7321
7322            int type;
7323            while ((type = in.next()) != END_DOCUMENT) {
7324                final String tag = in.getName();
7325                if (type == START_TAG) {
7326                    if (TAG_URI_GRANT.equals(tag)) {
7327                        final int sourceUserId;
7328                        final int targetUserId;
7329                        final int userHandle = readIntAttribute(in,
7330                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7331                        if (userHandle != UserHandle.USER_NULL) {
7332                            // For backwards compatibility.
7333                            sourceUserId = userHandle;
7334                            targetUserId = userHandle;
7335                        } else {
7336                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7337                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7338                        }
7339                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7340                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7341                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7342                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7343                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7344                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7345
7346                        // Sanity check that provider still belongs to source package
7347                        final ProviderInfo pi = getProviderInfoLocked(
7348                                uri.getAuthority(), sourceUserId);
7349                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7350                            int targetUid = -1;
7351                            try {
7352                                targetUid = AppGlobals.getPackageManager()
7353                                        .getPackageUid(targetPkg, targetUserId);
7354                            } catch (RemoteException e) {
7355                            }
7356                            if (targetUid != -1) {
7357                                final UriPermission perm = findOrCreateUriPermissionLocked(
7358                                        sourcePkg, targetPkg, targetUid,
7359                                        new GrantUri(sourceUserId, uri, prefix));
7360                                perm.initPersistedModes(modeFlags, createdTime);
7361                            }
7362                        } else {
7363                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7364                                    + " but instead found " + pi);
7365                        }
7366                    }
7367                }
7368            }
7369        } catch (FileNotFoundException e) {
7370            // Missing grants is okay
7371        } catch (IOException e) {
7372            Log.wtf(TAG, "Failed reading Uri grants", e);
7373        } catch (XmlPullParserException e) {
7374            Log.wtf(TAG, "Failed reading Uri grants", e);
7375        } finally {
7376            IoUtils.closeQuietly(fis);
7377        }
7378    }
7379
7380    /**
7381     * @param uri This uri must NOT contain an embedded userId.
7382     * @param userId The userId in which the uri is to be resolved.
7383     */
7384    @Override
7385    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7386        enforceNotIsolatedCaller("takePersistableUriPermission");
7387
7388        Preconditions.checkFlagsArgument(modeFlags,
7389                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7390
7391        synchronized (this) {
7392            final int callingUid = Binder.getCallingUid();
7393            boolean persistChanged = false;
7394            GrantUri grantUri = new GrantUri(userId, uri, false);
7395
7396            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7397                    new GrantUri(userId, uri, false));
7398            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7399                    new GrantUri(userId, uri, true));
7400
7401            final boolean exactValid = (exactPerm != null)
7402                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7403            final boolean prefixValid = (prefixPerm != null)
7404                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7405
7406            if (!(exactValid || prefixValid)) {
7407                throw new SecurityException("No persistable permission grants found for UID "
7408                        + callingUid + " and Uri " + grantUri.toSafeString());
7409            }
7410
7411            if (exactValid) {
7412                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7413            }
7414            if (prefixValid) {
7415                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7416            }
7417
7418            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7419
7420            if (persistChanged) {
7421                schedulePersistUriGrants();
7422            }
7423        }
7424    }
7425
7426    /**
7427     * @param uri This uri must NOT contain an embedded userId.
7428     * @param userId The userId in which the uri is to be resolved.
7429     */
7430    @Override
7431    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7432        enforceNotIsolatedCaller("releasePersistableUriPermission");
7433
7434        Preconditions.checkFlagsArgument(modeFlags,
7435                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7436
7437        synchronized (this) {
7438            final int callingUid = Binder.getCallingUid();
7439            boolean persistChanged = false;
7440
7441            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7442                    new GrantUri(userId, uri, false));
7443            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7444                    new GrantUri(userId, uri, true));
7445            if (exactPerm == null && prefixPerm == null) {
7446                throw new SecurityException("No permission grants found for UID " + callingUid
7447                        + " and Uri " + uri.toSafeString());
7448            }
7449
7450            if (exactPerm != null) {
7451                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7452                removeUriPermissionIfNeededLocked(exactPerm);
7453            }
7454            if (prefixPerm != null) {
7455                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7456                removeUriPermissionIfNeededLocked(prefixPerm);
7457            }
7458
7459            if (persistChanged) {
7460                schedulePersistUriGrants();
7461            }
7462        }
7463    }
7464
7465    /**
7466     * Prune any older {@link UriPermission} for the given UID until outstanding
7467     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7468     *
7469     * @return if any mutations occured that require persisting.
7470     */
7471    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7472        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7473        if (perms == null) return false;
7474        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7475
7476        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7477        for (UriPermission perm : perms.values()) {
7478            if (perm.persistedModeFlags != 0) {
7479                persisted.add(perm);
7480            }
7481        }
7482
7483        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7484        if (trimCount <= 0) return false;
7485
7486        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7487        for (int i = 0; i < trimCount; i++) {
7488            final UriPermission perm = persisted.get(i);
7489
7490            if (DEBUG_URI_PERMISSION) {
7491                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7492            }
7493
7494            perm.releasePersistableModes(~0);
7495            removeUriPermissionIfNeededLocked(perm);
7496        }
7497
7498        return true;
7499    }
7500
7501    @Override
7502    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7503            String packageName, boolean incoming) {
7504        enforceNotIsolatedCaller("getPersistedUriPermissions");
7505        Preconditions.checkNotNull(packageName, "packageName");
7506
7507        final int callingUid = Binder.getCallingUid();
7508        final IPackageManager pm = AppGlobals.getPackageManager();
7509        try {
7510            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7511            if (packageUid != callingUid) {
7512                throw new SecurityException(
7513                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7514            }
7515        } catch (RemoteException e) {
7516            throw new SecurityException("Failed to verify package name ownership");
7517        }
7518
7519        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7520        synchronized (this) {
7521            if (incoming) {
7522                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7523                        callingUid);
7524                if (perms == null) {
7525                    Slog.w(TAG, "No permission grants found for " + packageName);
7526                } else {
7527                    for (UriPermission perm : perms.values()) {
7528                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7529                            result.add(perm.buildPersistedPublicApiObject());
7530                        }
7531                    }
7532                }
7533            } else {
7534                final int size = mGrantedUriPermissions.size();
7535                for (int i = 0; i < size; i++) {
7536                    final ArrayMap<GrantUri, UriPermission> perms =
7537                            mGrantedUriPermissions.valueAt(i);
7538                    for (UriPermission perm : perms.values()) {
7539                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7540                            result.add(perm.buildPersistedPublicApiObject());
7541                        }
7542                    }
7543                }
7544            }
7545        }
7546        return new ParceledListSlice<android.content.UriPermission>(result);
7547    }
7548
7549    @Override
7550    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7551        synchronized (this) {
7552            ProcessRecord app =
7553                who != null ? getRecordForAppLocked(who) : null;
7554            if (app == null) return;
7555
7556            Message msg = Message.obtain();
7557            msg.what = WAIT_FOR_DEBUGGER_MSG;
7558            msg.obj = app;
7559            msg.arg1 = waiting ? 1 : 0;
7560            mHandler.sendMessage(msg);
7561        }
7562    }
7563
7564    @Override
7565    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7566        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7567        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7568        outInfo.availMem = Process.getFreeMemory();
7569        outInfo.totalMem = Process.getTotalMemory();
7570        outInfo.threshold = homeAppMem;
7571        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7572        outInfo.hiddenAppThreshold = cachedAppMem;
7573        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7574                ProcessList.SERVICE_ADJ);
7575        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7576                ProcessList.VISIBLE_APP_ADJ);
7577        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7578                ProcessList.FOREGROUND_APP_ADJ);
7579    }
7580
7581    // =========================================================
7582    // TASK MANAGEMENT
7583    // =========================================================
7584
7585    @Override
7586    public List<IAppTask> getAppTasks(String callingPackage) {
7587        int callingUid = Binder.getCallingUid();
7588        long ident = Binder.clearCallingIdentity();
7589
7590        synchronized(this) {
7591            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7592            try {
7593                if (localLOGV) Slog.v(TAG, "getAppTasks");
7594
7595                final int N = mRecentTasks.size();
7596                for (int i = 0; i < N; i++) {
7597                    TaskRecord tr = mRecentTasks.get(i);
7598                    // Skip tasks that do not match the caller.  We don't need to verify
7599                    // callingPackage, because we are also limiting to callingUid and know
7600                    // that will limit to the correct security sandbox.
7601                    if (tr.effectiveUid != callingUid) {
7602                        continue;
7603                    }
7604                    Intent intent = tr.getBaseIntent();
7605                    if (intent == null ||
7606                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7607                        continue;
7608                    }
7609                    ActivityManager.RecentTaskInfo taskInfo =
7610                            createRecentTaskInfoFromTaskRecord(tr);
7611                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7612                    list.add(taskImpl);
7613                }
7614            } finally {
7615                Binder.restoreCallingIdentity(ident);
7616            }
7617            return list;
7618        }
7619    }
7620
7621    @Override
7622    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7623        final int callingUid = Binder.getCallingUid();
7624        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7625
7626        synchronized(this) {
7627            if (localLOGV) Slog.v(
7628                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7629
7630            final boolean allowed = checkCallingPermission(
7631                    android.Manifest.permission.GET_TASKS)
7632                    == PackageManager.PERMISSION_GRANTED;
7633            if (!allowed) {
7634                Slog.w(TAG, "getTasks: caller " + callingUid
7635                        + " does not hold GET_TASKS; limiting output");
7636            }
7637
7638            // TODO: Improve with MRU list from all ActivityStacks.
7639            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7640        }
7641
7642        return list;
7643    }
7644
7645    TaskRecord getMostRecentTask() {
7646        return mRecentTasks.get(0);
7647    }
7648
7649    /**
7650     * Creates a new RecentTaskInfo from a TaskRecord.
7651     */
7652    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7653        // Update the task description to reflect any changes in the task stack
7654        tr.updateTaskDescription();
7655
7656        // Compose the recent task info
7657        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7658        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7659        rti.persistentId = tr.taskId;
7660        rti.baseIntent = new Intent(tr.getBaseIntent());
7661        rti.origActivity = tr.origActivity;
7662        rti.description = tr.lastDescription;
7663        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7664        rti.userId = tr.userId;
7665        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7666        rti.firstActiveTime = tr.firstActiveTime;
7667        rti.lastActiveTime = tr.lastActiveTime;
7668        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7669        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7670        return rti;
7671    }
7672
7673    @Override
7674    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7675        final int callingUid = Binder.getCallingUid();
7676        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7677                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7678
7679        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7680        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7681        synchronized (this) {
7682            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7683                    == PackageManager.PERMISSION_GRANTED;
7684            if (!allowed) {
7685                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7686                        + " does not hold GET_TASKS; limiting output");
7687            }
7688            final boolean detailed = checkCallingPermission(
7689                    android.Manifest.permission.GET_DETAILED_TASKS)
7690                    == PackageManager.PERMISSION_GRANTED;
7691
7692            IPackageManager pm = AppGlobals.getPackageManager();
7693
7694            final int N = mRecentTasks.size();
7695            ArrayList<ActivityManager.RecentTaskInfo> res
7696                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7697                            maxNum < N ? maxNum : N);
7698
7699            final Set<Integer> includedUsers;
7700            if (includeProfiles) {
7701                includedUsers = getProfileIdsLocked(userId);
7702            } else {
7703                includedUsers = new HashSet<Integer>();
7704            }
7705            includedUsers.add(Integer.valueOf(userId));
7706
7707            // Regroup affiliated tasks together.
7708            for (int i = 0; i < N; ) {
7709                TaskRecord task = mRecentTasks.remove(i);
7710                if (mTmpRecents.contains(task)) {
7711                    continue;
7712                }
7713                int affiliatedTaskId = task.mAffiliatedTaskId;
7714                while (true) {
7715                    TaskRecord next = task.mNextAffiliate;
7716                    if (next == null) {
7717                        break;
7718                    }
7719                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7720                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7721                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7722                        task.setNextAffiliate(null);
7723                        if (next.mPrevAffiliate == task) {
7724                            next.setPrevAffiliate(null);
7725                        }
7726                        break;
7727                    }
7728                    if (next.mPrevAffiliate != task) {
7729                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7730                                next.mPrevAffiliate + " task=" + task);
7731                        next.setPrevAffiliate(null);
7732                        break;
7733                    }
7734                    if (!mRecentTasks.contains(next)) {
7735                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7736                        task.setNextAffiliate(null);
7737                        if (next.mPrevAffiliate == task) {
7738                            next.setPrevAffiliate(null);
7739                        }
7740                        break;
7741                    }
7742                    task = next;
7743                }
7744                // task is now the end of the list
7745                do {
7746                    mRecentTasks.remove(task);
7747                    mRecentTasks.add(i++, task);
7748                    mTmpRecents.add(task);
7749                } while ((task = task.mPrevAffiliate) != null);
7750            }
7751            mTmpRecents.clear();
7752            // mRecentTasks is now in sorted, affiliated order.
7753
7754            for (int i=0; i<N && maxNum > 0; i++) {
7755                TaskRecord tr = mRecentTasks.get(i);
7756                // Only add calling user or related users recent tasks
7757                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7758                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7759                    continue;
7760                }
7761
7762                // Return the entry if desired by the caller.  We always return
7763                // the first entry, because callers always expect this to be the
7764                // foreground app.  We may filter others if the caller has
7765                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7766                // we should exclude the entry.
7767
7768                if (i == 0
7769                        || withExcluded
7770                        || (tr.intent == null)
7771                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7772                                == 0)) {
7773                    if (!allowed) {
7774                        // If the caller doesn't have the GET_TASKS permission, then only
7775                        // allow them to see a small subset of tasks -- their own and home.
7776                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7777                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7778                            continue;
7779                        }
7780                    }
7781                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7782                        // Don't include auto remove tasks that are finished or finishing.
7783                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7784                                + tr);
7785                        continue;
7786                    }
7787
7788                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7789                    if (!detailed) {
7790                        rti.baseIntent.replaceExtras((Bundle)null);
7791                    }
7792
7793                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7794                        // Check whether this activity is currently available.
7795                        try {
7796                            if (rti.origActivity != null) {
7797                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7798                                        == null) {
7799                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: "
7800                                            + tr);
7801                                    continue;
7802                                }
7803                            } else if (rti.baseIntent != null) {
7804                                if (pm.queryIntentActivities(rti.baseIntent,
7805                                        null, 0, userId) == null) {
7806                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: "
7807                                            + tr);
7808                                    continue;
7809                                }
7810                            }
7811                        } catch (RemoteException e) {
7812                            // Will never happen.
7813                        }
7814                    }
7815
7816                    res.add(rti);
7817                    maxNum--;
7818                }
7819            }
7820            return res;
7821        }
7822    }
7823
7824    private TaskRecord recentTaskForIdLocked(int id) {
7825        final int N = mRecentTasks.size();
7826            for (int i=0; i<N; i++) {
7827                TaskRecord tr = mRecentTasks.get(i);
7828                if (tr.taskId == id) {
7829                    return tr;
7830                }
7831            }
7832            return null;
7833    }
7834
7835    @Override
7836    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7837        synchronized (this) {
7838            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7839                    "getTaskThumbnail()");
7840            TaskRecord tr = recentTaskForIdLocked(id);
7841            if (tr != null) {
7842                return tr.getTaskThumbnailLocked();
7843            }
7844        }
7845        return null;
7846    }
7847
7848    @Override
7849    public int addAppTask(IBinder activityToken, Intent intent,
7850            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7851        final int callingUid = Binder.getCallingUid();
7852        final long callingIdent = Binder.clearCallingIdentity();
7853
7854        try {
7855            synchronized (this) {
7856                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7857                if (r == null) {
7858                    throw new IllegalArgumentException("Activity does not exist; token="
7859                            + activityToken);
7860                }
7861                ComponentName comp = intent.getComponent();
7862                if (comp == null) {
7863                    throw new IllegalArgumentException("Intent " + intent
7864                            + " must specify explicit component");
7865                }
7866                if (thumbnail.getWidth() != mThumbnailWidth
7867                        || thumbnail.getHeight() != mThumbnailHeight) {
7868                    throw new IllegalArgumentException("Bad thumbnail size: got "
7869                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7870                            + mThumbnailWidth + "x" + mThumbnailHeight);
7871                }
7872                if (intent.getSelector() != null) {
7873                    intent.setSelector(null);
7874                }
7875                if (intent.getSourceBounds() != null) {
7876                    intent.setSourceBounds(null);
7877                }
7878                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7879                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7880                        // The caller has added this as an auto-remove task...  that makes no
7881                        // sense, so turn off auto-remove.
7882                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7883                    }
7884                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7885                    // Must be a new task.
7886                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7887                }
7888                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7889                    mLastAddedTaskActivity = null;
7890                }
7891                ActivityInfo ainfo = mLastAddedTaskActivity;
7892                if (ainfo == null) {
7893                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7894                            comp, 0, UserHandle.getUserId(callingUid));
7895                    if (ainfo.applicationInfo.uid != callingUid) {
7896                        throw new SecurityException(
7897                                "Can't add task for another application: target uid="
7898                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7899                    }
7900                }
7901
7902                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7903                        intent, description);
7904
7905                int trimIdx = trimRecentsForTask(task, false);
7906                if (trimIdx >= 0) {
7907                    // If this would have caused a trim, then we'll abort because that
7908                    // means it would be added at the end of the list but then just removed.
7909                    return -1;
7910                }
7911
7912                final int N = mRecentTasks.size();
7913                if (N >= (MAX_RECENT_TASKS-1)) {
7914                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7915                    tr.disposeThumbnail();
7916                    tr.closeRecentsChain();
7917                }
7918
7919                mRecentTasks.add(task);
7920                r.task.stack.addTask(task, false, false);
7921
7922                task.setLastThumbnail(thumbnail);
7923                task.freeLastThumbnail();
7924
7925                return task.taskId;
7926            }
7927        } finally {
7928            Binder.restoreCallingIdentity(callingIdent);
7929        }
7930    }
7931
7932    @Override
7933    public Point getAppTaskThumbnailSize() {
7934        synchronized (this) {
7935            return new Point(mThumbnailWidth,  mThumbnailHeight);
7936        }
7937    }
7938
7939    @Override
7940    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7941        synchronized (this) {
7942            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7943            if (r != null) {
7944                r.taskDescription = td;
7945                r.task.updateTaskDescription();
7946            }
7947        }
7948    }
7949
7950    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7951        tr.disposeThumbnail();
7952        mRecentTasks.remove(tr);
7953        tr.closeRecentsChain();
7954        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7955        Intent baseIntent = new Intent(
7956                tr.intent != null ? tr.intent : tr.affinityIntent);
7957        ComponentName component = baseIntent.getComponent();
7958        if (component == null) {
7959            Slog.w(TAG, "Now component for base intent of task: " + tr);
7960            return;
7961        }
7962
7963        // Find any running services associated with this app.
7964        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7965
7966        if (killProcesses) {
7967            // Find any running processes associated with this app.
7968            final String pkg = component.getPackageName();
7969            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7970            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7971            for (int i=0; i<pmap.size(); i++) {
7972                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7973                for (int j=0; j<uids.size(); j++) {
7974                    ProcessRecord proc = uids.valueAt(j);
7975                    if (proc.userId != tr.userId) {
7976                        continue;
7977                    }
7978                    if (!proc.pkgList.containsKey(pkg)) {
7979                        continue;
7980                    }
7981                    procs.add(proc);
7982                }
7983            }
7984
7985            // Kill the running processes.
7986            for (int i=0; i<procs.size(); i++) {
7987                ProcessRecord pr = procs.get(i);
7988                if (pr == mHomeProcess) {
7989                    // Don't kill the home process along with tasks from the same package.
7990                    continue;
7991                }
7992                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7993                    pr.kill("remove task", true);
7994                } else {
7995                    pr.waitingToKill = "remove task";
7996                }
7997            }
7998        }
7999    }
8000
8001    /**
8002     * Removes the task with the specified task id.
8003     *
8004     * @param taskId Identifier of the task to be removed.
8005     * @param flags Additional operational flags.  May be 0 or
8006     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8007     * @return Returns true if the given task was found and removed.
8008     */
8009    private boolean removeTaskByIdLocked(int taskId, int flags) {
8010        TaskRecord tr = recentTaskForIdLocked(taskId);
8011        if (tr != null) {
8012            tr.removeTaskActivitiesLocked();
8013            cleanUpRemovedTaskLocked(tr, flags);
8014            if (tr.isPersistable) {
8015                notifyTaskPersisterLocked(null, true);
8016            }
8017            return true;
8018        }
8019        return false;
8020    }
8021
8022    @Override
8023    public boolean removeTask(int taskId, int flags) {
8024        synchronized (this) {
8025            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8026                    "removeTask()");
8027            long ident = Binder.clearCallingIdentity();
8028            try {
8029                return removeTaskByIdLocked(taskId, flags);
8030            } finally {
8031                Binder.restoreCallingIdentity(ident);
8032            }
8033        }
8034    }
8035
8036    /**
8037     * TODO: Add mController hook
8038     */
8039    @Override
8040    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8041        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8042                "moveTaskToFront()");
8043
8044        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8045        synchronized(this) {
8046            moveTaskToFrontLocked(taskId, flags, options);
8047        }
8048    }
8049
8050    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8051        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8052                Binder.getCallingUid(), "Task to front")) {
8053            ActivityOptions.abort(options);
8054            return;
8055        }
8056        final long origId = Binder.clearCallingIdentity();
8057        try {
8058            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8059            if (task == null) {
8060                return;
8061            }
8062            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8063                mStackSupervisor.showLockTaskToast();
8064                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8065                return;
8066            }
8067            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8068            if (prev != null && prev.isRecentsActivity()) {
8069                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8070            }
8071            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8072        } finally {
8073            Binder.restoreCallingIdentity(origId);
8074        }
8075        ActivityOptions.abort(options);
8076    }
8077
8078    @Override
8079    public void moveTaskToBack(int taskId) {
8080        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8081                "moveTaskToBack()");
8082
8083        synchronized(this) {
8084            TaskRecord tr = recentTaskForIdLocked(taskId);
8085            if (tr != null) {
8086                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8087                ActivityStack stack = tr.stack;
8088                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8089                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8090                            Binder.getCallingUid(), "Task to back")) {
8091                        return;
8092                    }
8093                }
8094                final long origId = Binder.clearCallingIdentity();
8095                try {
8096                    stack.moveTaskToBackLocked(taskId, null);
8097                } finally {
8098                    Binder.restoreCallingIdentity(origId);
8099                }
8100            }
8101        }
8102    }
8103
8104    /**
8105     * Moves an activity, and all of the other activities within the same task, to the bottom
8106     * of the history stack.  The activity's order within the task is unchanged.
8107     *
8108     * @param token A reference to the activity we wish to move
8109     * @param nonRoot If false then this only works if the activity is the root
8110     *                of a task; if true it will work for any activity in a task.
8111     * @return Returns true if the move completed, false if not.
8112     */
8113    @Override
8114    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8115        enforceNotIsolatedCaller("moveActivityTaskToBack");
8116        synchronized(this) {
8117            final long origId = Binder.clearCallingIdentity();
8118            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8119            if (taskId >= 0) {
8120                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8121            }
8122            Binder.restoreCallingIdentity(origId);
8123        }
8124        return false;
8125    }
8126
8127    @Override
8128    public void moveTaskBackwards(int task) {
8129        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8130                "moveTaskBackwards()");
8131
8132        synchronized(this) {
8133            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8134                    Binder.getCallingUid(), "Task backwards")) {
8135                return;
8136            }
8137            final long origId = Binder.clearCallingIdentity();
8138            moveTaskBackwardsLocked(task);
8139            Binder.restoreCallingIdentity(origId);
8140        }
8141    }
8142
8143    private final void moveTaskBackwardsLocked(int task) {
8144        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8145    }
8146
8147    @Override
8148    public IBinder getHomeActivityToken() throws RemoteException {
8149        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8150                "getHomeActivityToken()");
8151        synchronized (this) {
8152            return mStackSupervisor.getHomeActivityToken();
8153        }
8154    }
8155
8156    @Override
8157    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8158            IActivityContainerCallback callback) throws RemoteException {
8159        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8160                "createActivityContainer()");
8161        synchronized (this) {
8162            if (parentActivityToken == null) {
8163                throw new IllegalArgumentException("parent token must not be null");
8164            }
8165            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8166            if (r == null) {
8167                return null;
8168            }
8169            if (callback == null) {
8170                throw new IllegalArgumentException("callback must not be null");
8171            }
8172            return mStackSupervisor.createActivityContainer(r, callback);
8173        }
8174    }
8175
8176    @Override
8177    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8178        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8179                "deleteActivityContainer()");
8180        synchronized (this) {
8181            mStackSupervisor.deleteActivityContainer(container);
8182        }
8183    }
8184
8185    @Override
8186    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8187            throws RemoteException {
8188        synchronized (this) {
8189            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8190            if (stack != null) {
8191                return stack.mActivityContainer;
8192            }
8193            return null;
8194        }
8195    }
8196
8197    @Override
8198    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8199        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8200                "moveTaskToStack()");
8201        if (stackId == HOME_STACK_ID) {
8202            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8203                    new RuntimeException("here").fillInStackTrace());
8204        }
8205        synchronized (this) {
8206            long ident = Binder.clearCallingIdentity();
8207            try {
8208                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8209                        + stackId + " toTop=" + toTop);
8210                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8211            } finally {
8212                Binder.restoreCallingIdentity(ident);
8213            }
8214        }
8215    }
8216
8217    @Override
8218    public void resizeStack(int stackBoxId, Rect bounds) {
8219        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8220                "resizeStackBox()");
8221        long ident = Binder.clearCallingIdentity();
8222        try {
8223            mWindowManager.resizeStack(stackBoxId, bounds);
8224        } finally {
8225            Binder.restoreCallingIdentity(ident);
8226        }
8227    }
8228
8229    @Override
8230    public List<StackInfo> getAllStackInfos() {
8231        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8232                "getAllStackInfos()");
8233        long ident = Binder.clearCallingIdentity();
8234        try {
8235            synchronized (this) {
8236                return mStackSupervisor.getAllStackInfosLocked();
8237            }
8238        } finally {
8239            Binder.restoreCallingIdentity(ident);
8240        }
8241    }
8242
8243    @Override
8244    public StackInfo getStackInfo(int stackId) {
8245        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8246                "getStackInfo()");
8247        long ident = Binder.clearCallingIdentity();
8248        try {
8249            synchronized (this) {
8250                return mStackSupervisor.getStackInfoLocked(stackId);
8251            }
8252        } finally {
8253            Binder.restoreCallingIdentity(ident);
8254        }
8255    }
8256
8257    @Override
8258    public boolean isInHomeStack(int taskId) {
8259        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8260                "getStackInfo()");
8261        long ident = Binder.clearCallingIdentity();
8262        try {
8263            synchronized (this) {
8264                TaskRecord tr = recentTaskForIdLocked(taskId);
8265                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8266            }
8267        } finally {
8268            Binder.restoreCallingIdentity(ident);
8269        }
8270    }
8271
8272    @Override
8273    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8274        synchronized(this) {
8275            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8276        }
8277    }
8278
8279    private boolean isLockTaskAuthorized(String pkg) {
8280        final DevicePolicyManager dpm = (DevicePolicyManager)
8281                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8282        try {
8283            int uid = mContext.getPackageManager().getPackageUid(pkg,
8284                    Binder.getCallingUserHandle().getIdentifier());
8285            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8286        } catch (NameNotFoundException e) {
8287            return false;
8288        }
8289    }
8290
8291    void startLockTaskMode(TaskRecord task) {
8292        final String pkg;
8293        synchronized (this) {
8294            pkg = task.intent.getComponent().getPackageName();
8295        }
8296        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8297        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8298            final TaskRecord taskRecord = task;
8299            mHandler.post(new Runnable() {
8300                @Override
8301                public void run() {
8302                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8303                }
8304            });
8305            return;
8306        }
8307        long ident = Binder.clearCallingIdentity();
8308        try {
8309            synchronized (this) {
8310                // Since we lost lock on task, make sure it is still there.
8311                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8312                if (task != null) {
8313                    if (!isSystemInitiated
8314                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8315                        throw new IllegalArgumentException("Invalid task, not in foreground");
8316                    }
8317                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8318                }
8319            }
8320        } finally {
8321            Binder.restoreCallingIdentity(ident);
8322        }
8323    }
8324
8325    @Override
8326    public void startLockTaskMode(int taskId) {
8327        final TaskRecord task;
8328        long ident = Binder.clearCallingIdentity();
8329        try {
8330            synchronized (this) {
8331                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8332            }
8333        } finally {
8334            Binder.restoreCallingIdentity(ident);
8335        }
8336        if (task != null) {
8337            startLockTaskMode(task);
8338        }
8339    }
8340
8341    @Override
8342    public void startLockTaskMode(IBinder token) {
8343        final TaskRecord task;
8344        long ident = Binder.clearCallingIdentity();
8345        try {
8346            synchronized (this) {
8347                final ActivityRecord r = ActivityRecord.forToken(token);
8348                if (r == null) {
8349                    return;
8350                }
8351                task = r.task;
8352            }
8353        } finally {
8354            Binder.restoreCallingIdentity(ident);
8355        }
8356        if (task != null) {
8357            startLockTaskMode(task);
8358        }
8359    }
8360
8361    @Override
8362    public void startLockTaskModeOnCurrent() throws RemoteException {
8363        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8364        ActivityRecord r = null;
8365        synchronized (this) {
8366            r = mStackSupervisor.topRunningActivityLocked();
8367        }
8368        startLockTaskMode(r.task);
8369    }
8370
8371    @Override
8372    public void stopLockTaskMode() {
8373        // Verify that the user matches the package of the intent for the TaskRecord
8374        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8375        // and stopLockTaskMode.
8376        final int callingUid = Binder.getCallingUid();
8377        if (callingUid != Process.SYSTEM_UID) {
8378            try {
8379                String pkg =
8380                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8381                int uid = mContext.getPackageManager().getPackageUid(pkg,
8382                        Binder.getCallingUserHandle().getIdentifier());
8383                if (uid != callingUid) {
8384                    throw new SecurityException("Invalid uid, expected " + uid);
8385                }
8386            } catch (NameNotFoundException e) {
8387                Log.d(TAG, "stopLockTaskMode " + e);
8388                return;
8389            }
8390        }
8391        long ident = Binder.clearCallingIdentity();
8392        try {
8393            Log.d(TAG, "stopLockTaskMode");
8394            // Stop lock task
8395            synchronized (this) {
8396                mStackSupervisor.setLockTaskModeLocked(null, false);
8397            }
8398        } finally {
8399            Binder.restoreCallingIdentity(ident);
8400        }
8401    }
8402
8403    @Override
8404    public void stopLockTaskModeOnCurrent() throws RemoteException {
8405        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8406        long ident = Binder.clearCallingIdentity();
8407        try {
8408            stopLockTaskMode();
8409        } finally {
8410            Binder.restoreCallingIdentity(ident);
8411        }
8412    }
8413
8414    @Override
8415    public boolean isInLockTaskMode() {
8416        synchronized (this) {
8417            return mStackSupervisor.isInLockTaskMode();
8418        }
8419    }
8420
8421    // =========================================================
8422    // CONTENT PROVIDERS
8423    // =========================================================
8424
8425    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8426        List<ProviderInfo> providers = null;
8427        try {
8428            providers = AppGlobals.getPackageManager().
8429                queryContentProviders(app.processName, app.uid,
8430                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8431        } catch (RemoteException ex) {
8432        }
8433        if (DEBUG_MU)
8434            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8435        int userId = app.userId;
8436        if (providers != null) {
8437            int N = providers.size();
8438            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8439            for (int i=0; i<N; i++) {
8440                ProviderInfo cpi =
8441                    (ProviderInfo)providers.get(i);
8442                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8443                        cpi.name, cpi.flags);
8444                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8445                    // This is a singleton provider, but a user besides the
8446                    // default user is asking to initialize a process it runs
8447                    // in...  well, no, it doesn't actually run in this process,
8448                    // it runs in the process of the default user.  Get rid of it.
8449                    providers.remove(i);
8450                    N--;
8451                    i--;
8452                    continue;
8453                }
8454
8455                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8456                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8457                if (cpr == null) {
8458                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8459                    mProviderMap.putProviderByClass(comp, cpr);
8460                }
8461                if (DEBUG_MU)
8462                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8463                app.pubProviders.put(cpi.name, cpr);
8464                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8465                    // Don't add this if it is a platform component that is marked
8466                    // to run in multiple processes, because this is actually
8467                    // part of the framework so doesn't make sense to track as a
8468                    // separate apk in the process.
8469                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8470                            mProcessStats);
8471                }
8472                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8473            }
8474        }
8475        return providers;
8476    }
8477
8478    /**
8479     * Check if {@link ProcessRecord} has a possible chance at accessing the
8480     * given {@link ProviderInfo}. Final permission checking is always done
8481     * in {@link ContentProvider}.
8482     */
8483    private final String checkContentProviderPermissionLocked(
8484            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8485        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8486        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8487        boolean checkedGrants = false;
8488        if (checkUser) {
8489            // Looking for cross-user grants before enforcing the typical cross-users permissions
8490            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8491            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8492                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8493                    return null;
8494                }
8495                checkedGrants = true;
8496            }
8497            userId = handleIncomingUser(callingPid, callingUid, userId,
8498                    false, ALLOW_NON_FULL,
8499                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8500            if (userId != tmpTargetUserId) {
8501                // When we actually went to determine the final targer user ID, this ended
8502                // up different than our initial check for the authority.  This is because
8503                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8504                // SELF.  So we need to re-check the grants again.
8505                checkedGrants = false;
8506            }
8507        }
8508        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8509                cpi.applicationInfo.uid, cpi.exported)
8510                == PackageManager.PERMISSION_GRANTED) {
8511            return null;
8512        }
8513        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8514                cpi.applicationInfo.uid, cpi.exported)
8515                == PackageManager.PERMISSION_GRANTED) {
8516            return null;
8517        }
8518
8519        PathPermission[] pps = cpi.pathPermissions;
8520        if (pps != null) {
8521            int i = pps.length;
8522            while (i > 0) {
8523                i--;
8524                PathPermission pp = pps[i];
8525                String pprperm = pp.getReadPermission();
8526                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8527                        cpi.applicationInfo.uid, cpi.exported)
8528                        == PackageManager.PERMISSION_GRANTED) {
8529                    return null;
8530                }
8531                String ppwperm = pp.getWritePermission();
8532                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8533                        cpi.applicationInfo.uid, cpi.exported)
8534                        == PackageManager.PERMISSION_GRANTED) {
8535                    return null;
8536                }
8537            }
8538        }
8539        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8540            return null;
8541        }
8542
8543        String msg;
8544        if (!cpi.exported) {
8545            msg = "Permission Denial: opening provider " + cpi.name
8546                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8547                    + ", uid=" + callingUid + ") that is not exported from uid "
8548                    + cpi.applicationInfo.uid;
8549        } else {
8550            msg = "Permission Denial: opening provider " + cpi.name
8551                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8552                    + ", uid=" + callingUid + ") requires "
8553                    + cpi.readPermission + " or " + cpi.writePermission;
8554        }
8555        Slog.w(TAG, msg);
8556        return msg;
8557    }
8558
8559    /**
8560     * Returns if the ContentProvider has granted a uri to callingUid
8561     */
8562    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8563        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8564        if (perms != null) {
8565            for (int i=perms.size()-1; i>=0; i--) {
8566                GrantUri grantUri = perms.keyAt(i);
8567                if (grantUri.sourceUserId == userId || !checkUser) {
8568                    if (matchesProvider(grantUri.uri, cpi)) {
8569                        return true;
8570                    }
8571                }
8572            }
8573        }
8574        return false;
8575    }
8576
8577    /**
8578     * Returns true if the uri authority is one of the authorities specified in the provider.
8579     */
8580    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8581        String uriAuth = uri.getAuthority();
8582        String cpiAuth = cpi.authority;
8583        if (cpiAuth.indexOf(';') == -1) {
8584            return cpiAuth.equals(uriAuth);
8585        }
8586        String[] cpiAuths = cpiAuth.split(";");
8587        int length = cpiAuths.length;
8588        for (int i = 0; i < length; i++) {
8589            if (cpiAuths[i].equals(uriAuth)) return true;
8590        }
8591        return false;
8592    }
8593
8594    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8595            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8596        if (r != null) {
8597            for (int i=0; i<r.conProviders.size(); i++) {
8598                ContentProviderConnection conn = r.conProviders.get(i);
8599                if (conn.provider == cpr) {
8600                    if (DEBUG_PROVIDER) Slog.v(TAG,
8601                            "Adding provider requested by "
8602                            + r.processName + " from process "
8603                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8604                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8605                    if (stable) {
8606                        conn.stableCount++;
8607                        conn.numStableIncs++;
8608                    } else {
8609                        conn.unstableCount++;
8610                        conn.numUnstableIncs++;
8611                    }
8612                    return conn;
8613                }
8614            }
8615            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8616            if (stable) {
8617                conn.stableCount = 1;
8618                conn.numStableIncs = 1;
8619            } else {
8620                conn.unstableCount = 1;
8621                conn.numUnstableIncs = 1;
8622            }
8623            cpr.connections.add(conn);
8624            r.conProviders.add(conn);
8625            return conn;
8626        }
8627        cpr.addExternalProcessHandleLocked(externalProcessToken);
8628        return null;
8629    }
8630
8631    boolean decProviderCountLocked(ContentProviderConnection conn,
8632            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8633        if (conn != null) {
8634            cpr = conn.provider;
8635            if (DEBUG_PROVIDER) Slog.v(TAG,
8636                    "Removing provider requested by "
8637                    + conn.client.processName + " from process "
8638                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8639                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8640            if (stable) {
8641                conn.stableCount--;
8642            } else {
8643                conn.unstableCount--;
8644            }
8645            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8646                cpr.connections.remove(conn);
8647                conn.client.conProviders.remove(conn);
8648                return true;
8649            }
8650            return false;
8651        }
8652        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8653        return false;
8654    }
8655
8656    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8657            String name, IBinder token, boolean stable, int userId) {
8658        ContentProviderRecord cpr;
8659        ContentProviderConnection conn = null;
8660        ProviderInfo cpi = null;
8661
8662        synchronized(this) {
8663            ProcessRecord r = null;
8664            if (caller != null) {
8665                r = getRecordForAppLocked(caller);
8666                if (r == null) {
8667                    throw new SecurityException(
8668                            "Unable to find app for caller " + caller
8669                          + " (pid=" + Binder.getCallingPid()
8670                          + ") when getting content provider " + name);
8671                }
8672            }
8673
8674            boolean checkCrossUser = true;
8675
8676            // First check if this content provider has been published...
8677            cpr = mProviderMap.getProviderByName(name, userId);
8678            // If that didn't work, check if it exists for user 0 and then
8679            // verify that it's a singleton provider before using it.
8680            if (cpr == null && userId != UserHandle.USER_OWNER) {
8681                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8682                if (cpr != null) {
8683                    cpi = cpr.info;
8684                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8685                            cpi.name, cpi.flags)
8686                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8687                        userId = UserHandle.USER_OWNER;
8688                        checkCrossUser = false;
8689                    } else {
8690                        cpr = null;
8691                        cpi = null;
8692                    }
8693                }
8694            }
8695
8696            boolean providerRunning = cpr != null;
8697            if (providerRunning) {
8698                cpi = cpr.info;
8699                String msg;
8700                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8701                        != null) {
8702                    throw new SecurityException(msg);
8703                }
8704
8705                if (r != null && cpr.canRunHere(r)) {
8706                    // This provider has been published or is in the process
8707                    // of being published...  but it is also allowed to run
8708                    // in the caller's process, so don't make a connection
8709                    // and just let the caller instantiate its own instance.
8710                    ContentProviderHolder holder = cpr.newHolder(null);
8711                    // don't give caller the provider object, it needs
8712                    // to make its own.
8713                    holder.provider = null;
8714                    return holder;
8715                }
8716
8717                final long origId = Binder.clearCallingIdentity();
8718
8719                // In this case the provider instance already exists, so we can
8720                // return it right away.
8721                conn = incProviderCountLocked(r, cpr, token, stable);
8722                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8723                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8724                        // If this is a perceptible app accessing the provider,
8725                        // make sure to count it as being accessed and thus
8726                        // back up on the LRU list.  This is good because
8727                        // content providers are often expensive to start.
8728                        updateLruProcessLocked(cpr.proc, false, null);
8729                    }
8730                }
8731
8732                if (cpr.proc != null) {
8733                    if (false) {
8734                        if (cpr.name.flattenToShortString().equals(
8735                                "com.android.providers.calendar/.CalendarProvider2")) {
8736                            Slog.v(TAG, "****************** KILLING "
8737                                + cpr.name.flattenToShortString());
8738                            Process.killProcess(cpr.proc.pid);
8739                        }
8740                    }
8741                    boolean success = updateOomAdjLocked(cpr.proc);
8742                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8743                    // NOTE: there is still a race here where a signal could be
8744                    // pending on the process even though we managed to update its
8745                    // adj level.  Not sure what to do about this, but at least
8746                    // the race is now smaller.
8747                    if (!success) {
8748                        // Uh oh...  it looks like the provider's process
8749                        // has been killed on us.  We need to wait for a new
8750                        // process to be started, and make sure its death
8751                        // doesn't kill our process.
8752                        Slog.i(TAG,
8753                                "Existing provider " + cpr.name.flattenToShortString()
8754                                + " is crashing; detaching " + r);
8755                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8756                        appDiedLocked(cpr.proc);
8757                        if (!lastRef) {
8758                            // This wasn't the last ref our process had on
8759                            // the provider...  we have now been killed, bail.
8760                            return null;
8761                        }
8762                        providerRunning = false;
8763                        conn = null;
8764                    }
8765                }
8766
8767                Binder.restoreCallingIdentity(origId);
8768            }
8769
8770            boolean singleton;
8771            if (!providerRunning) {
8772                try {
8773                    cpi = AppGlobals.getPackageManager().
8774                        resolveContentProvider(name,
8775                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8776                } catch (RemoteException ex) {
8777                }
8778                if (cpi == null) {
8779                    return null;
8780                }
8781                // If the provider is a singleton AND
8782                // (it's a call within the same user || the provider is a
8783                // privileged app)
8784                // Then allow connecting to the singleton provider
8785                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8786                        cpi.name, cpi.flags)
8787                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8788                if (singleton) {
8789                    userId = UserHandle.USER_OWNER;
8790                }
8791                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8792
8793                String msg;
8794                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8795                        != null) {
8796                    throw new SecurityException(msg);
8797                }
8798
8799                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8800                        && !cpi.processName.equals("system")) {
8801                    // If this content provider does not run in the system
8802                    // process, and the system is not yet ready to run other
8803                    // processes, then fail fast instead of hanging.
8804                    throw new IllegalArgumentException(
8805                            "Attempt to launch content provider before system ready");
8806                }
8807
8808                // Make sure that the user who owns this provider is started.  If not,
8809                // we don't want to allow it to run.
8810                if (mStartedUsers.get(userId) == null) {
8811                    Slog.w(TAG, "Unable to launch app "
8812                            + cpi.applicationInfo.packageName + "/"
8813                            + cpi.applicationInfo.uid + " for provider "
8814                            + name + ": user " + userId + " is stopped");
8815                    return null;
8816                }
8817
8818                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8819                cpr = mProviderMap.getProviderByClass(comp, userId);
8820                final boolean firstClass = cpr == null;
8821                if (firstClass) {
8822                    try {
8823                        ApplicationInfo ai =
8824                            AppGlobals.getPackageManager().
8825                                getApplicationInfo(
8826                                        cpi.applicationInfo.packageName,
8827                                        STOCK_PM_FLAGS, userId);
8828                        if (ai == null) {
8829                            Slog.w(TAG, "No package info for content provider "
8830                                    + cpi.name);
8831                            return null;
8832                        }
8833                        ai = getAppInfoForUser(ai, userId);
8834                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8835                    } catch (RemoteException ex) {
8836                        // pm is in same process, this will never happen.
8837                    }
8838                }
8839
8840                if (r != null && cpr.canRunHere(r)) {
8841                    // If this is a multiprocess provider, then just return its
8842                    // info and allow the caller to instantiate it.  Only do
8843                    // this if the provider is the same user as the caller's
8844                    // process, or can run as root (so can be in any process).
8845                    return cpr.newHolder(null);
8846                }
8847
8848                if (DEBUG_PROVIDER) {
8849                    RuntimeException e = new RuntimeException("here");
8850                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8851                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8852                }
8853
8854                // This is single process, and our app is now connecting to it.
8855                // See if we are already in the process of launching this
8856                // provider.
8857                final int N = mLaunchingProviders.size();
8858                int i;
8859                for (i=0; i<N; i++) {
8860                    if (mLaunchingProviders.get(i) == cpr) {
8861                        break;
8862                    }
8863                }
8864
8865                // If the provider is not already being launched, then get it
8866                // started.
8867                if (i >= N) {
8868                    final long origId = Binder.clearCallingIdentity();
8869
8870                    try {
8871                        // Content provider is now in use, its package can't be stopped.
8872                        try {
8873                            AppGlobals.getPackageManager().setPackageStoppedState(
8874                                    cpr.appInfo.packageName, false, userId);
8875                        } catch (RemoteException e) {
8876                        } catch (IllegalArgumentException e) {
8877                            Slog.w(TAG, "Failed trying to unstop package "
8878                                    + cpr.appInfo.packageName + ": " + e);
8879                        }
8880
8881                        // Use existing process if already started
8882                        ProcessRecord proc = getProcessRecordLocked(
8883                                cpi.processName, cpr.appInfo.uid, false);
8884                        if (proc != null && proc.thread != null) {
8885                            if (DEBUG_PROVIDER) {
8886                                Slog.d(TAG, "Installing in existing process " + proc);
8887                            }
8888                            proc.pubProviders.put(cpi.name, cpr);
8889                            try {
8890                                proc.thread.scheduleInstallProvider(cpi);
8891                            } catch (RemoteException e) {
8892                            }
8893                        } else {
8894                            proc = startProcessLocked(cpi.processName,
8895                                    cpr.appInfo, false, 0, "content provider",
8896                                    new ComponentName(cpi.applicationInfo.packageName,
8897                                            cpi.name), false, false, false);
8898                            if (proc == null) {
8899                                Slog.w(TAG, "Unable to launch app "
8900                                        + cpi.applicationInfo.packageName + "/"
8901                                        + cpi.applicationInfo.uid + " for provider "
8902                                        + name + ": process is bad");
8903                                return null;
8904                            }
8905                        }
8906                        cpr.launchingApp = proc;
8907                        mLaunchingProviders.add(cpr);
8908                    } finally {
8909                        Binder.restoreCallingIdentity(origId);
8910                    }
8911                }
8912
8913                // Make sure the provider is published (the same provider class
8914                // may be published under multiple names).
8915                if (firstClass) {
8916                    mProviderMap.putProviderByClass(comp, cpr);
8917                }
8918
8919                mProviderMap.putProviderByName(name, cpr);
8920                conn = incProviderCountLocked(r, cpr, token, stable);
8921                if (conn != null) {
8922                    conn.waiting = true;
8923                }
8924            }
8925        }
8926
8927        // Wait for the provider to be published...
8928        synchronized (cpr) {
8929            while (cpr.provider == null) {
8930                if (cpr.launchingApp == null) {
8931                    Slog.w(TAG, "Unable to launch app "
8932                            + cpi.applicationInfo.packageName + "/"
8933                            + cpi.applicationInfo.uid + " for provider "
8934                            + name + ": launching app became null");
8935                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8936                            UserHandle.getUserId(cpi.applicationInfo.uid),
8937                            cpi.applicationInfo.packageName,
8938                            cpi.applicationInfo.uid, name);
8939                    return null;
8940                }
8941                try {
8942                    if (DEBUG_MU) {
8943                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8944                                + cpr.launchingApp);
8945                    }
8946                    if (conn != null) {
8947                        conn.waiting = true;
8948                    }
8949                    cpr.wait();
8950                } catch (InterruptedException ex) {
8951                } finally {
8952                    if (conn != null) {
8953                        conn.waiting = false;
8954                    }
8955                }
8956            }
8957        }
8958        return cpr != null ? cpr.newHolder(conn) : null;
8959    }
8960
8961    @Override
8962    public final ContentProviderHolder getContentProvider(
8963            IApplicationThread caller, String name, int userId, boolean stable) {
8964        enforceNotIsolatedCaller("getContentProvider");
8965        if (caller == null) {
8966            String msg = "null IApplicationThread when getting content provider "
8967                    + name;
8968            Slog.w(TAG, msg);
8969            throw new SecurityException(msg);
8970        }
8971        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8972        // with cross-user grant.
8973        return getContentProviderImpl(caller, name, null, stable, userId);
8974    }
8975
8976    public ContentProviderHolder getContentProviderExternal(
8977            String name, int userId, IBinder token) {
8978        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8979            "Do not have permission in call getContentProviderExternal()");
8980        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8981                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8982        return getContentProviderExternalUnchecked(name, token, userId);
8983    }
8984
8985    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8986            IBinder token, int userId) {
8987        return getContentProviderImpl(null, name, token, true, userId);
8988    }
8989
8990    /**
8991     * Drop a content provider from a ProcessRecord's bookkeeping
8992     */
8993    public void removeContentProvider(IBinder connection, boolean stable) {
8994        enforceNotIsolatedCaller("removeContentProvider");
8995        long ident = Binder.clearCallingIdentity();
8996        try {
8997            synchronized (this) {
8998                ContentProviderConnection conn;
8999                try {
9000                    conn = (ContentProviderConnection)connection;
9001                } catch (ClassCastException e) {
9002                    String msg ="removeContentProvider: " + connection
9003                            + " not a ContentProviderConnection";
9004                    Slog.w(TAG, msg);
9005                    throw new IllegalArgumentException(msg);
9006                }
9007                if (conn == null) {
9008                    throw new NullPointerException("connection is null");
9009                }
9010                if (decProviderCountLocked(conn, null, null, stable)) {
9011                    updateOomAdjLocked();
9012                }
9013            }
9014        } finally {
9015            Binder.restoreCallingIdentity(ident);
9016        }
9017    }
9018
9019    public void removeContentProviderExternal(String name, IBinder token) {
9020        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9021            "Do not have permission in call removeContentProviderExternal()");
9022        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9023    }
9024
9025    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9026        synchronized (this) {
9027            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9028            if(cpr == null) {
9029                //remove from mProvidersByClass
9030                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9031                return;
9032            }
9033
9034            //update content provider record entry info
9035            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9036            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9037            if (localCpr.hasExternalProcessHandles()) {
9038                if (localCpr.removeExternalProcessHandleLocked(token)) {
9039                    updateOomAdjLocked();
9040                } else {
9041                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9042                            + " with no external reference for token: "
9043                            + token + ".");
9044                }
9045            } else {
9046                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9047                        + " with no external references.");
9048            }
9049        }
9050    }
9051
9052    public final void publishContentProviders(IApplicationThread caller,
9053            List<ContentProviderHolder> providers) {
9054        if (providers == null) {
9055            return;
9056        }
9057
9058        enforceNotIsolatedCaller("publishContentProviders");
9059        synchronized (this) {
9060            final ProcessRecord r = getRecordForAppLocked(caller);
9061            if (DEBUG_MU)
9062                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9063            if (r == null) {
9064                throw new SecurityException(
9065                        "Unable to find app for caller " + caller
9066                      + " (pid=" + Binder.getCallingPid()
9067                      + ") when publishing content providers");
9068            }
9069
9070            final long origId = Binder.clearCallingIdentity();
9071
9072            final int N = providers.size();
9073            for (int i=0; i<N; i++) {
9074                ContentProviderHolder src = providers.get(i);
9075                if (src == null || src.info == null || src.provider == null) {
9076                    continue;
9077                }
9078                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9079                if (DEBUG_MU)
9080                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9081                if (dst != null) {
9082                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9083                    mProviderMap.putProviderByClass(comp, dst);
9084                    String names[] = dst.info.authority.split(";");
9085                    for (int j = 0; j < names.length; j++) {
9086                        mProviderMap.putProviderByName(names[j], dst);
9087                    }
9088
9089                    int NL = mLaunchingProviders.size();
9090                    int j;
9091                    for (j=0; j<NL; j++) {
9092                        if (mLaunchingProviders.get(j) == dst) {
9093                            mLaunchingProviders.remove(j);
9094                            j--;
9095                            NL--;
9096                        }
9097                    }
9098                    synchronized (dst) {
9099                        dst.provider = src.provider;
9100                        dst.proc = r;
9101                        dst.notifyAll();
9102                    }
9103                    updateOomAdjLocked(r);
9104                }
9105            }
9106
9107            Binder.restoreCallingIdentity(origId);
9108        }
9109    }
9110
9111    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9112        ContentProviderConnection conn;
9113        try {
9114            conn = (ContentProviderConnection)connection;
9115        } catch (ClassCastException e) {
9116            String msg ="refContentProvider: " + connection
9117                    + " not a ContentProviderConnection";
9118            Slog.w(TAG, msg);
9119            throw new IllegalArgumentException(msg);
9120        }
9121        if (conn == null) {
9122            throw new NullPointerException("connection is null");
9123        }
9124
9125        synchronized (this) {
9126            if (stable > 0) {
9127                conn.numStableIncs += stable;
9128            }
9129            stable = conn.stableCount + stable;
9130            if (stable < 0) {
9131                throw new IllegalStateException("stableCount < 0: " + stable);
9132            }
9133
9134            if (unstable > 0) {
9135                conn.numUnstableIncs += unstable;
9136            }
9137            unstable = conn.unstableCount + unstable;
9138            if (unstable < 0) {
9139                throw new IllegalStateException("unstableCount < 0: " + unstable);
9140            }
9141
9142            if ((stable+unstable) <= 0) {
9143                throw new IllegalStateException("ref counts can't go to zero here: stable="
9144                        + stable + " unstable=" + unstable);
9145            }
9146            conn.stableCount = stable;
9147            conn.unstableCount = unstable;
9148            return !conn.dead;
9149        }
9150    }
9151
9152    public void unstableProviderDied(IBinder connection) {
9153        ContentProviderConnection conn;
9154        try {
9155            conn = (ContentProviderConnection)connection;
9156        } catch (ClassCastException e) {
9157            String msg ="refContentProvider: " + connection
9158                    + " not a ContentProviderConnection";
9159            Slog.w(TAG, msg);
9160            throw new IllegalArgumentException(msg);
9161        }
9162        if (conn == null) {
9163            throw new NullPointerException("connection is null");
9164        }
9165
9166        // Safely retrieve the content provider associated with the connection.
9167        IContentProvider provider;
9168        synchronized (this) {
9169            provider = conn.provider.provider;
9170        }
9171
9172        if (provider == null) {
9173            // Um, yeah, we're way ahead of you.
9174            return;
9175        }
9176
9177        // Make sure the caller is being honest with us.
9178        if (provider.asBinder().pingBinder()) {
9179            // Er, no, still looks good to us.
9180            synchronized (this) {
9181                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9182                        + " says " + conn + " died, but we don't agree");
9183                return;
9184            }
9185        }
9186
9187        // Well look at that!  It's dead!
9188        synchronized (this) {
9189            if (conn.provider.provider != provider) {
9190                // But something changed...  good enough.
9191                return;
9192            }
9193
9194            ProcessRecord proc = conn.provider.proc;
9195            if (proc == null || proc.thread == null) {
9196                // Seems like the process is already cleaned up.
9197                return;
9198            }
9199
9200            // As far as we're concerned, this is just like receiving a
9201            // death notification...  just a bit prematurely.
9202            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9203                    + ") early provider death");
9204            final long ident = Binder.clearCallingIdentity();
9205            try {
9206                appDiedLocked(proc);
9207            } finally {
9208                Binder.restoreCallingIdentity(ident);
9209            }
9210        }
9211    }
9212
9213    @Override
9214    public void appNotRespondingViaProvider(IBinder connection) {
9215        enforceCallingPermission(
9216                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9217
9218        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9219        if (conn == null) {
9220            Slog.w(TAG, "ContentProviderConnection is null");
9221            return;
9222        }
9223
9224        final ProcessRecord host = conn.provider.proc;
9225        if (host == null) {
9226            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9227            return;
9228        }
9229
9230        final long token = Binder.clearCallingIdentity();
9231        try {
9232            appNotResponding(host, null, null, false, "ContentProvider not responding");
9233        } finally {
9234            Binder.restoreCallingIdentity(token);
9235        }
9236    }
9237
9238    public final void installSystemProviders() {
9239        List<ProviderInfo> providers;
9240        synchronized (this) {
9241            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9242            providers = generateApplicationProvidersLocked(app);
9243            if (providers != null) {
9244                for (int i=providers.size()-1; i>=0; i--) {
9245                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9246                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9247                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9248                                + ": not system .apk");
9249                        providers.remove(i);
9250                    }
9251                }
9252            }
9253        }
9254        if (providers != null) {
9255            mSystemThread.installSystemProviders(providers);
9256        }
9257
9258        mCoreSettingsObserver = new CoreSettingsObserver(this);
9259
9260        //mUsageStatsService.monitorPackages();
9261    }
9262
9263    /**
9264     * Allows apps to retrieve the MIME type of a URI.
9265     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9266     * users, then it does not need permission to access the ContentProvider.
9267     * Either, it needs cross-user uri grants.
9268     *
9269     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9270     *
9271     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9272     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9273     */
9274    public String getProviderMimeType(Uri uri, int userId) {
9275        enforceNotIsolatedCaller("getProviderMimeType");
9276        final String name = uri.getAuthority();
9277        int callingUid = Binder.getCallingUid();
9278        int callingPid = Binder.getCallingPid();
9279        long ident = 0;
9280        boolean clearedIdentity = false;
9281        userId = unsafeConvertIncomingUser(userId);
9282        if (UserHandle.getUserId(callingUid) != userId) {
9283            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9284                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9285                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9286                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9287                clearedIdentity = true;
9288                ident = Binder.clearCallingIdentity();
9289            }
9290        }
9291        ContentProviderHolder holder = null;
9292        try {
9293            holder = getContentProviderExternalUnchecked(name, null, userId);
9294            if (holder != null) {
9295                return holder.provider.getType(uri);
9296            }
9297        } catch (RemoteException e) {
9298            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9299            return null;
9300        } finally {
9301            // We need to clear the identity to call removeContentProviderExternalUnchecked
9302            if (!clearedIdentity) {
9303                ident = Binder.clearCallingIdentity();
9304            }
9305            try {
9306                if (holder != null) {
9307                    removeContentProviderExternalUnchecked(name, null, userId);
9308                }
9309            } finally {
9310                Binder.restoreCallingIdentity(ident);
9311            }
9312        }
9313
9314        return null;
9315    }
9316
9317    // =========================================================
9318    // GLOBAL MANAGEMENT
9319    // =========================================================
9320
9321    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9322            boolean isolated, int isolatedUid) {
9323        String proc = customProcess != null ? customProcess : info.processName;
9324        BatteryStatsImpl.Uid.Proc ps = null;
9325        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9326        int uid = info.uid;
9327        if (isolated) {
9328            if (isolatedUid == 0) {
9329                int userId = UserHandle.getUserId(uid);
9330                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9331                while (true) {
9332                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9333                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9334                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9335                    }
9336                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9337                    mNextIsolatedProcessUid++;
9338                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9339                        // No process for this uid, use it.
9340                        break;
9341                    }
9342                    stepsLeft--;
9343                    if (stepsLeft <= 0) {
9344                        return null;
9345                    }
9346                }
9347            } else {
9348                // Special case for startIsolatedProcess (internal only), where
9349                // the uid of the isolated process is specified by the caller.
9350                uid = isolatedUid;
9351            }
9352        }
9353        return new ProcessRecord(stats, info, proc, uid);
9354    }
9355
9356    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9357            String abiOverride) {
9358        ProcessRecord app;
9359        if (!isolated) {
9360            app = getProcessRecordLocked(info.processName, info.uid, true);
9361        } else {
9362            app = null;
9363        }
9364
9365        if (app == null) {
9366            app = newProcessRecordLocked(info, null, isolated, 0);
9367            mProcessNames.put(info.processName, app.uid, app);
9368            if (isolated) {
9369                mIsolatedProcesses.put(app.uid, app);
9370            }
9371            updateLruProcessLocked(app, false, null);
9372            updateOomAdjLocked();
9373        }
9374
9375        // This package really, really can not be stopped.
9376        try {
9377            AppGlobals.getPackageManager().setPackageStoppedState(
9378                    info.packageName, false, UserHandle.getUserId(app.uid));
9379        } catch (RemoteException e) {
9380        } catch (IllegalArgumentException e) {
9381            Slog.w(TAG, "Failed trying to unstop package "
9382                    + info.packageName + ": " + e);
9383        }
9384
9385        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9386                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9387            app.persistent = true;
9388            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9389        }
9390        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9391            mPersistentStartingProcesses.add(app);
9392            startProcessLocked(app, "added application", app.processName, abiOverride,
9393                    null /* entryPoint */, null /* entryPointArgs */);
9394        }
9395
9396        return app;
9397    }
9398
9399    public void unhandledBack() {
9400        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9401                "unhandledBack()");
9402
9403        synchronized(this) {
9404            final long origId = Binder.clearCallingIdentity();
9405            try {
9406                getFocusedStack().unhandledBackLocked();
9407            } finally {
9408                Binder.restoreCallingIdentity(origId);
9409            }
9410        }
9411    }
9412
9413    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9414        enforceNotIsolatedCaller("openContentUri");
9415        final int userId = UserHandle.getCallingUserId();
9416        String name = uri.getAuthority();
9417        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9418        ParcelFileDescriptor pfd = null;
9419        if (cph != null) {
9420            // We record the binder invoker's uid in thread-local storage before
9421            // going to the content provider to open the file.  Later, in the code
9422            // that handles all permissions checks, we look for this uid and use
9423            // that rather than the Activity Manager's own uid.  The effect is that
9424            // we do the check against the caller's permissions even though it looks
9425            // to the content provider like the Activity Manager itself is making
9426            // the request.
9427            sCallerIdentity.set(new Identity(
9428                    Binder.getCallingPid(), Binder.getCallingUid()));
9429            try {
9430                pfd = cph.provider.openFile(null, uri, "r", null);
9431            } catch (FileNotFoundException e) {
9432                // do nothing; pfd will be returned null
9433            } finally {
9434                // Ensure that whatever happens, we clean up the identity state
9435                sCallerIdentity.remove();
9436            }
9437
9438            // We've got the fd now, so we're done with the provider.
9439            removeContentProviderExternalUnchecked(name, null, userId);
9440        } else {
9441            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9442        }
9443        return pfd;
9444    }
9445
9446    // Actually is sleeping or shutting down or whatever else in the future
9447    // is an inactive state.
9448    public boolean isSleepingOrShuttingDown() {
9449        return mSleeping || mShuttingDown;
9450    }
9451
9452    public boolean isSleeping() {
9453        return mSleeping;
9454    }
9455
9456    void goingToSleep() {
9457        synchronized(this) {
9458            mWentToSleep = true;
9459            updateEventDispatchingLocked();
9460            goToSleepIfNeededLocked();
9461        }
9462    }
9463
9464    void finishRunningVoiceLocked() {
9465        if (mRunningVoice) {
9466            mRunningVoice = false;
9467            goToSleepIfNeededLocked();
9468        }
9469    }
9470
9471    void goToSleepIfNeededLocked() {
9472        if (mWentToSleep && !mRunningVoice) {
9473            if (!mSleeping) {
9474                mSleeping = true;
9475                mStackSupervisor.goingToSleepLocked();
9476
9477                // Initialize the wake times of all processes.
9478                checkExcessivePowerUsageLocked(false);
9479                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9480                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9481                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9482            }
9483        }
9484    }
9485
9486    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9487        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9488            // Never persist the home stack.
9489            return;
9490        }
9491        mTaskPersister.wakeup(task, flush);
9492    }
9493
9494    @Override
9495    public boolean shutdown(int timeout) {
9496        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9497                != PackageManager.PERMISSION_GRANTED) {
9498            throw new SecurityException("Requires permission "
9499                    + android.Manifest.permission.SHUTDOWN);
9500        }
9501
9502        boolean timedout = false;
9503
9504        synchronized(this) {
9505            mShuttingDown = true;
9506            updateEventDispatchingLocked();
9507            timedout = mStackSupervisor.shutdownLocked(timeout);
9508        }
9509
9510        mAppOpsService.shutdown();
9511        if (mUsageStatsService != null) {
9512            mUsageStatsService.prepareShutdown();
9513        }
9514        mBatteryStatsService.shutdown();
9515        synchronized (this) {
9516            mProcessStats.shutdownLocked();
9517        }
9518        notifyTaskPersisterLocked(null, true);
9519
9520        return timedout;
9521    }
9522
9523    public final void activitySlept(IBinder token) {
9524        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9525
9526        final long origId = Binder.clearCallingIdentity();
9527
9528        synchronized (this) {
9529            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9530            if (r != null) {
9531                mStackSupervisor.activitySleptLocked(r);
9532            }
9533        }
9534
9535        Binder.restoreCallingIdentity(origId);
9536    }
9537
9538    void logLockScreen(String msg) {
9539        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9540                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9541                mWentToSleep + " mSleeping=" + mSleeping);
9542    }
9543
9544    private void comeOutOfSleepIfNeededLocked() {
9545        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9546            if (mSleeping) {
9547                mSleeping = false;
9548                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9549            }
9550        }
9551    }
9552
9553    void wakingUp() {
9554        synchronized(this) {
9555            mWentToSleep = false;
9556            updateEventDispatchingLocked();
9557            comeOutOfSleepIfNeededLocked();
9558        }
9559    }
9560
9561    void startRunningVoiceLocked() {
9562        if (!mRunningVoice) {
9563            mRunningVoice = true;
9564            comeOutOfSleepIfNeededLocked();
9565        }
9566    }
9567
9568    private void updateEventDispatchingLocked() {
9569        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9570    }
9571
9572    public void setLockScreenShown(boolean shown) {
9573        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9574                != PackageManager.PERMISSION_GRANTED) {
9575            throw new SecurityException("Requires permission "
9576                    + android.Manifest.permission.DEVICE_POWER);
9577        }
9578
9579        synchronized(this) {
9580            long ident = Binder.clearCallingIdentity();
9581            try {
9582                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9583                mLockScreenShown = shown;
9584                comeOutOfSleepIfNeededLocked();
9585            } finally {
9586                Binder.restoreCallingIdentity(ident);
9587            }
9588        }
9589    }
9590
9591    @Override
9592    public void stopAppSwitches() {
9593        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9594                != PackageManager.PERMISSION_GRANTED) {
9595            throw new SecurityException("Requires permission "
9596                    + android.Manifest.permission.STOP_APP_SWITCHES);
9597        }
9598
9599        synchronized(this) {
9600            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9601                    + APP_SWITCH_DELAY_TIME;
9602            mDidAppSwitch = false;
9603            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9604            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9605            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9606        }
9607    }
9608
9609    public void resumeAppSwitches() {
9610        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9611                != PackageManager.PERMISSION_GRANTED) {
9612            throw new SecurityException("Requires permission "
9613                    + android.Manifest.permission.STOP_APP_SWITCHES);
9614        }
9615
9616        synchronized(this) {
9617            // Note that we don't execute any pending app switches... we will
9618            // let those wait until either the timeout, or the next start
9619            // activity request.
9620            mAppSwitchesAllowedTime = 0;
9621        }
9622    }
9623
9624    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9625            String name) {
9626        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9627            return true;
9628        }
9629
9630        final int perm = checkComponentPermission(
9631                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9632                callingUid, -1, true);
9633        if (perm == PackageManager.PERMISSION_GRANTED) {
9634            return true;
9635        }
9636
9637        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9638        return false;
9639    }
9640
9641    public void setDebugApp(String packageName, boolean waitForDebugger,
9642            boolean persistent) {
9643        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9644                "setDebugApp()");
9645
9646        long ident = Binder.clearCallingIdentity();
9647        try {
9648            // Note that this is not really thread safe if there are multiple
9649            // callers into it at the same time, but that's not a situation we
9650            // care about.
9651            if (persistent) {
9652                final ContentResolver resolver = mContext.getContentResolver();
9653                Settings.Global.putString(
9654                    resolver, Settings.Global.DEBUG_APP,
9655                    packageName);
9656                Settings.Global.putInt(
9657                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9658                    waitForDebugger ? 1 : 0);
9659            }
9660
9661            synchronized (this) {
9662                if (!persistent) {
9663                    mOrigDebugApp = mDebugApp;
9664                    mOrigWaitForDebugger = mWaitForDebugger;
9665                }
9666                mDebugApp = packageName;
9667                mWaitForDebugger = waitForDebugger;
9668                mDebugTransient = !persistent;
9669                if (packageName != null) {
9670                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9671                            false, UserHandle.USER_ALL, "set debug app");
9672                }
9673            }
9674        } finally {
9675            Binder.restoreCallingIdentity(ident);
9676        }
9677    }
9678
9679    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9680        synchronized (this) {
9681            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9682            if (!isDebuggable) {
9683                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9684                    throw new SecurityException("Process not debuggable: " + app.packageName);
9685                }
9686            }
9687
9688            mOpenGlTraceApp = processName;
9689        }
9690    }
9691
9692    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9693            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9694        synchronized (this) {
9695            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9696            if (!isDebuggable) {
9697                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9698                    throw new SecurityException("Process not debuggable: " + app.packageName);
9699                }
9700            }
9701            mProfileApp = processName;
9702            mProfileFile = profileFile;
9703            if (mProfileFd != null) {
9704                try {
9705                    mProfileFd.close();
9706                } catch (IOException e) {
9707                }
9708                mProfileFd = null;
9709            }
9710            mProfileFd = profileFd;
9711            mProfileType = 0;
9712            mAutoStopProfiler = autoStopProfiler;
9713        }
9714    }
9715
9716    @Override
9717    public void setAlwaysFinish(boolean enabled) {
9718        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9719                "setAlwaysFinish()");
9720
9721        Settings.Global.putInt(
9722                mContext.getContentResolver(),
9723                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9724
9725        synchronized (this) {
9726            mAlwaysFinishActivities = enabled;
9727        }
9728    }
9729
9730    @Override
9731    public void setActivityController(IActivityController controller) {
9732        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9733                "setActivityController()");
9734        synchronized (this) {
9735            mController = controller;
9736            Watchdog.getInstance().setActivityController(controller);
9737        }
9738    }
9739
9740    @Override
9741    public void setUserIsMonkey(boolean userIsMonkey) {
9742        synchronized (this) {
9743            synchronized (mPidsSelfLocked) {
9744                final int callingPid = Binder.getCallingPid();
9745                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9746                if (precessRecord == null) {
9747                    throw new SecurityException("Unknown process: " + callingPid);
9748                }
9749                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9750                    throw new SecurityException("Only an instrumentation process "
9751                            + "with a UiAutomation can call setUserIsMonkey");
9752                }
9753            }
9754            mUserIsMonkey = userIsMonkey;
9755        }
9756    }
9757
9758    @Override
9759    public boolean isUserAMonkey() {
9760        synchronized (this) {
9761            // If there is a controller also implies the user is a monkey.
9762            return (mUserIsMonkey || mController != null);
9763        }
9764    }
9765
9766    public void requestBugReport() {
9767        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9768        SystemProperties.set("ctl.start", "bugreport");
9769    }
9770
9771    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9772        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9773    }
9774
9775    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9776        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9777            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9778        }
9779        return KEY_DISPATCHING_TIMEOUT;
9780    }
9781
9782    @Override
9783    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9784        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9785                != PackageManager.PERMISSION_GRANTED) {
9786            throw new SecurityException("Requires permission "
9787                    + android.Manifest.permission.FILTER_EVENTS);
9788        }
9789        ProcessRecord proc;
9790        long timeout;
9791        synchronized (this) {
9792            synchronized (mPidsSelfLocked) {
9793                proc = mPidsSelfLocked.get(pid);
9794            }
9795            timeout = getInputDispatchingTimeoutLocked(proc);
9796        }
9797
9798        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9799            return -1;
9800        }
9801
9802        return timeout;
9803    }
9804
9805    /**
9806     * Handle input dispatching timeouts.
9807     * Returns whether input dispatching should be aborted or not.
9808     */
9809    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9810            final ActivityRecord activity, final ActivityRecord parent,
9811            final boolean aboveSystem, String reason) {
9812        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9813                != PackageManager.PERMISSION_GRANTED) {
9814            throw new SecurityException("Requires permission "
9815                    + android.Manifest.permission.FILTER_EVENTS);
9816        }
9817
9818        final String annotation;
9819        if (reason == null) {
9820            annotation = "Input dispatching timed out";
9821        } else {
9822            annotation = "Input dispatching timed out (" + reason + ")";
9823        }
9824
9825        if (proc != null) {
9826            synchronized (this) {
9827                if (proc.debugging) {
9828                    return false;
9829                }
9830
9831                if (mDidDexOpt) {
9832                    // Give more time since we were dexopting.
9833                    mDidDexOpt = false;
9834                    return false;
9835                }
9836
9837                if (proc.instrumentationClass != null) {
9838                    Bundle info = new Bundle();
9839                    info.putString("shortMsg", "keyDispatchingTimedOut");
9840                    info.putString("longMsg", annotation);
9841                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9842                    return true;
9843                }
9844            }
9845            mHandler.post(new Runnable() {
9846                @Override
9847                public void run() {
9848                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9849                }
9850            });
9851        }
9852
9853        return true;
9854    }
9855
9856    public Bundle getAssistContextExtras(int requestType) {
9857        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9858                "getAssistContextExtras()");
9859        PendingAssistExtras pae;
9860        Bundle extras = new Bundle();
9861        synchronized (this) {
9862            ActivityRecord activity = getFocusedStack().mResumedActivity;
9863            if (activity == null) {
9864                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9865                return null;
9866            }
9867            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9868            if (activity.app == null || activity.app.thread == null) {
9869                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9870                return extras;
9871            }
9872            if (activity.app.pid == Binder.getCallingPid()) {
9873                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9874                return extras;
9875            }
9876            pae = new PendingAssistExtras(activity);
9877            try {
9878                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9879                        requestType);
9880                mPendingAssistExtras.add(pae);
9881                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9882            } catch (RemoteException e) {
9883                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9884                return extras;
9885            }
9886        }
9887        synchronized (pae) {
9888            while (!pae.haveResult) {
9889                try {
9890                    pae.wait();
9891                } catch (InterruptedException e) {
9892                }
9893            }
9894            if (pae.result != null) {
9895                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9896            }
9897        }
9898        synchronized (this) {
9899            mPendingAssistExtras.remove(pae);
9900            mHandler.removeCallbacks(pae);
9901        }
9902        return extras;
9903    }
9904
9905    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9906        PendingAssistExtras pae = (PendingAssistExtras)token;
9907        synchronized (pae) {
9908            pae.result = extras;
9909            pae.haveResult = true;
9910            pae.notifyAll();
9911        }
9912    }
9913
9914    public void registerProcessObserver(IProcessObserver observer) {
9915        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9916                "registerProcessObserver()");
9917        synchronized (this) {
9918            mProcessObservers.register(observer);
9919        }
9920    }
9921
9922    @Override
9923    public void unregisterProcessObserver(IProcessObserver observer) {
9924        synchronized (this) {
9925            mProcessObservers.unregister(observer);
9926        }
9927    }
9928
9929    @Override
9930    public boolean convertFromTranslucent(IBinder token) {
9931        final long origId = Binder.clearCallingIdentity();
9932        try {
9933            synchronized (this) {
9934                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9935                if (r == null) {
9936                    return false;
9937                }
9938                if (r.changeWindowTranslucency(true)) {
9939                    mWindowManager.setAppFullscreen(token, true);
9940                    r.task.stack.releaseBackgroundResources();
9941                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9942                    return true;
9943                }
9944                return false;
9945            }
9946        } finally {
9947            Binder.restoreCallingIdentity(origId);
9948        }
9949    }
9950
9951    @Override
9952    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9953        final long origId = Binder.clearCallingIdentity();
9954        try {
9955            synchronized (this) {
9956                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9957                if (r == null) {
9958                    return false;
9959                }
9960                int index = r.task.mActivities.lastIndexOf(r);
9961                if (index > 0) {
9962                    ActivityRecord under = r.task.mActivities.get(index - 1);
9963                    under.returningOptions = options;
9964                }
9965                if (r.changeWindowTranslucency(false)) {
9966                    r.task.stack.convertToTranslucent(r);
9967                    mWindowManager.setAppFullscreen(token, false);
9968                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9969                    return true;
9970                } else {
9971                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9972                    return false;
9973                }
9974            }
9975        } finally {
9976            Binder.restoreCallingIdentity(origId);
9977        }
9978    }
9979
9980    @Override
9981    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9982        final long origId = Binder.clearCallingIdentity();
9983        try {
9984            synchronized (this) {
9985                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9986                if (r != null) {
9987                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9988                }
9989            }
9990            return false;
9991        } finally {
9992            Binder.restoreCallingIdentity(origId);
9993        }
9994    }
9995
9996    @Override
9997    public boolean isBackgroundVisibleBehind(IBinder token) {
9998        final long origId = Binder.clearCallingIdentity();
9999        try {
10000            synchronized (this) {
10001                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10002                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10003                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10004                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10005                return visible;
10006            }
10007        } finally {
10008            Binder.restoreCallingIdentity(origId);
10009        }
10010    }
10011
10012    @Override
10013    public ActivityOptions getActivityOptions(IBinder token) {
10014        final long origId = Binder.clearCallingIdentity();
10015        try {
10016            synchronized (this) {
10017                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10018                if (r != null) {
10019                    final ActivityOptions activityOptions = r.pendingOptions;
10020                    r.pendingOptions = null;
10021                    return activityOptions;
10022                }
10023                return null;
10024            }
10025        } finally {
10026            Binder.restoreCallingIdentity(origId);
10027        }
10028    }
10029
10030    @Override
10031    public void setImmersive(IBinder token, boolean immersive) {
10032        synchronized(this) {
10033            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10034            if (r == null) {
10035                throw new IllegalArgumentException();
10036            }
10037            r.immersive = immersive;
10038
10039            // update associated state if we're frontmost
10040            if (r == mFocusedActivity) {
10041                if (DEBUG_IMMERSIVE) {
10042                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10043                }
10044                applyUpdateLockStateLocked(r);
10045            }
10046        }
10047    }
10048
10049    @Override
10050    public boolean isImmersive(IBinder token) {
10051        synchronized (this) {
10052            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10053            if (r == null) {
10054                throw new IllegalArgumentException();
10055            }
10056            return r.immersive;
10057        }
10058    }
10059
10060    public boolean isTopActivityImmersive() {
10061        enforceNotIsolatedCaller("startActivity");
10062        synchronized (this) {
10063            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10064            return (r != null) ? r.immersive : false;
10065        }
10066    }
10067
10068    @Override
10069    public boolean isTopOfTask(IBinder token) {
10070        synchronized (this) {
10071            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10072            if (r == null) {
10073                throw new IllegalArgumentException();
10074            }
10075            return r.task.getTopActivity() == r;
10076        }
10077    }
10078
10079    public final void enterSafeMode() {
10080        synchronized(this) {
10081            // It only makes sense to do this before the system is ready
10082            // and started launching other packages.
10083            if (!mSystemReady) {
10084                try {
10085                    AppGlobals.getPackageManager().enterSafeMode();
10086                } catch (RemoteException e) {
10087                }
10088            }
10089
10090            mSafeMode = true;
10091        }
10092    }
10093
10094    public final void showSafeModeOverlay() {
10095        View v = LayoutInflater.from(mContext).inflate(
10096                com.android.internal.R.layout.safe_mode, null);
10097        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10098        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10099        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10100        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10101        lp.gravity = Gravity.BOTTOM | Gravity.START;
10102        lp.format = v.getBackground().getOpacity();
10103        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10104                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10105        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10106        ((WindowManager)mContext.getSystemService(
10107                Context.WINDOW_SERVICE)).addView(v, lp);
10108    }
10109
10110    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10111        if (!(sender instanceof PendingIntentRecord)) {
10112            return;
10113        }
10114        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10115        synchronized (stats) {
10116            if (mBatteryStatsService.isOnBattery()) {
10117                mBatteryStatsService.enforceCallingPermission();
10118                PendingIntentRecord rec = (PendingIntentRecord)sender;
10119                int MY_UID = Binder.getCallingUid();
10120                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10121                BatteryStatsImpl.Uid.Pkg pkg =
10122                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10123                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10124                pkg.incWakeupsLocked();
10125            }
10126        }
10127    }
10128
10129    public boolean killPids(int[] pids, String pReason, boolean secure) {
10130        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10131            throw new SecurityException("killPids only available to the system");
10132        }
10133        String reason = (pReason == null) ? "Unknown" : pReason;
10134        // XXX Note: don't acquire main activity lock here, because the window
10135        // manager calls in with its locks held.
10136
10137        boolean killed = false;
10138        synchronized (mPidsSelfLocked) {
10139            int[] types = new int[pids.length];
10140            int worstType = 0;
10141            for (int i=0; i<pids.length; i++) {
10142                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10143                if (proc != null) {
10144                    int type = proc.setAdj;
10145                    types[i] = type;
10146                    if (type > worstType) {
10147                        worstType = type;
10148                    }
10149                }
10150            }
10151
10152            // If the worst oom_adj is somewhere in the cached proc LRU range,
10153            // then constrain it so we will kill all cached procs.
10154            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10155                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10156                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10157            }
10158
10159            // If this is not a secure call, don't let it kill processes that
10160            // are important.
10161            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10162                worstType = ProcessList.SERVICE_ADJ;
10163            }
10164
10165            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10166            for (int i=0; i<pids.length; i++) {
10167                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10168                if (proc == null) {
10169                    continue;
10170                }
10171                int adj = proc.setAdj;
10172                if (adj >= worstType && !proc.killedByAm) {
10173                    proc.kill(reason, true);
10174                    killed = true;
10175                }
10176            }
10177        }
10178        return killed;
10179    }
10180
10181    @Override
10182    public void killUid(int uid, String reason) {
10183        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10184            throw new SecurityException("killUid only available to the system");
10185        }
10186        synchronized (this) {
10187            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10188                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10189                    reason != null ? reason : "kill uid");
10190        }
10191    }
10192
10193    @Override
10194    public boolean killProcessesBelowForeground(String reason) {
10195        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10196            throw new SecurityException("killProcessesBelowForeground() only available to system");
10197        }
10198
10199        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10200    }
10201
10202    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10203        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10204            throw new SecurityException("killProcessesBelowAdj() only available to system");
10205        }
10206
10207        boolean killed = false;
10208        synchronized (mPidsSelfLocked) {
10209            final int size = mPidsSelfLocked.size();
10210            for (int i = 0; i < size; i++) {
10211                final int pid = mPidsSelfLocked.keyAt(i);
10212                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10213                if (proc == null) continue;
10214
10215                final int adj = proc.setAdj;
10216                if (adj > belowAdj && !proc.killedByAm) {
10217                    proc.kill(reason, true);
10218                    killed = true;
10219                }
10220            }
10221        }
10222        return killed;
10223    }
10224
10225    @Override
10226    public void hang(final IBinder who, boolean allowRestart) {
10227        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10228                != PackageManager.PERMISSION_GRANTED) {
10229            throw new SecurityException("Requires permission "
10230                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10231        }
10232
10233        final IBinder.DeathRecipient death = new DeathRecipient() {
10234            @Override
10235            public void binderDied() {
10236                synchronized (this) {
10237                    notifyAll();
10238                }
10239            }
10240        };
10241
10242        try {
10243            who.linkToDeath(death, 0);
10244        } catch (RemoteException e) {
10245            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10246            return;
10247        }
10248
10249        synchronized (this) {
10250            Watchdog.getInstance().setAllowRestart(allowRestart);
10251            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10252            synchronized (death) {
10253                while (who.isBinderAlive()) {
10254                    try {
10255                        death.wait();
10256                    } catch (InterruptedException e) {
10257                    }
10258                }
10259            }
10260            Watchdog.getInstance().setAllowRestart(true);
10261        }
10262    }
10263
10264    @Override
10265    public void restart() {
10266        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10267                != PackageManager.PERMISSION_GRANTED) {
10268            throw new SecurityException("Requires permission "
10269                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10270        }
10271
10272        Log.i(TAG, "Sending shutdown broadcast...");
10273
10274        BroadcastReceiver br = new BroadcastReceiver() {
10275            @Override public void onReceive(Context context, Intent intent) {
10276                // Now the broadcast is done, finish up the low-level shutdown.
10277                Log.i(TAG, "Shutting down activity manager...");
10278                shutdown(10000);
10279                Log.i(TAG, "Shutdown complete, restarting!");
10280                Process.killProcess(Process.myPid());
10281                System.exit(10);
10282            }
10283        };
10284
10285        // First send the high-level shut down broadcast.
10286        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10287        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10288        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10289        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10290        mContext.sendOrderedBroadcastAsUser(intent,
10291                UserHandle.ALL, null, br, mHandler, 0, null, null);
10292        */
10293        br.onReceive(mContext, intent);
10294    }
10295
10296    private long getLowRamTimeSinceIdle(long now) {
10297        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10298    }
10299
10300    @Override
10301    public void performIdleMaintenance() {
10302        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10303                != PackageManager.PERMISSION_GRANTED) {
10304            throw new SecurityException("Requires permission "
10305                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10306        }
10307
10308        synchronized (this) {
10309            final long now = SystemClock.uptimeMillis();
10310            final long timeSinceLastIdle = now - mLastIdleTime;
10311            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10312            mLastIdleTime = now;
10313            mLowRamTimeSinceLastIdle = 0;
10314            if (mLowRamStartTime != 0) {
10315                mLowRamStartTime = now;
10316            }
10317
10318            StringBuilder sb = new StringBuilder(128);
10319            sb.append("Idle maintenance over ");
10320            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10321            sb.append(" low RAM for ");
10322            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10323            Slog.i(TAG, sb.toString());
10324
10325            // If at least 1/3 of our time since the last idle period has been spent
10326            // with RAM low, then we want to kill processes.
10327            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10328
10329            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10330                ProcessRecord proc = mLruProcesses.get(i);
10331                if (proc.notCachedSinceIdle) {
10332                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10333                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10334                        if (doKilling && proc.initialIdlePss != 0
10335                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10336                            proc.kill("idle maint (pss " + proc.lastPss
10337                                    + " from " + proc.initialIdlePss + ")", true);
10338                        }
10339                    }
10340                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10341                    proc.notCachedSinceIdle = true;
10342                    proc.initialIdlePss = 0;
10343                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10344                            isSleeping(), now);
10345                }
10346            }
10347
10348            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10349            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10350        }
10351    }
10352
10353    private void retrieveSettings() {
10354        final ContentResolver resolver = mContext.getContentResolver();
10355        String debugApp = Settings.Global.getString(
10356            resolver, Settings.Global.DEBUG_APP);
10357        boolean waitForDebugger = Settings.Global.getInt(
10358            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10359        boolean alwaysFinishActivities = Settings.Global.getInt(
10360            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10361        boolean forceRtl = Settings.Global.getInt(
10362                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10363        // Transfer any global setting for forcing RTL layout, into a System Property
10364        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10365
10366        Configuration configuration = new Configuration();
10367        Settings.System.getConfiguration(resolver, configuration);
10368        if (forceRtl) {
10369            // This will take care of setting the correct layout direction flags
10370            configuration.setLayoutDirection(configuration.locale);
10371        }
10372
10373        synchronized (this) {
10374            mDebugApp = mOrigDebugApp = debugApp;
10375            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10376            mAlwaysFinishActivities = alwaysFinishActivities;
10377            // This happens before any activities are started, so we can
10378            // change mConfiguration in-place.
10379            updateConfigurationLocked(configuration, null, false, true);
10380            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10381        }
10382    }
10383
10384    public boolean testIsSystemReady() {
10385        // no need to synchronize(this) just to read & return the value
10386        return mSystemReady;
10387    }
10388
10389    private static File getCalledPreBootReceiversFile() {
10390        File dataDir = Environment.getDataDirectory();
10391        File systemDir = new File(dataDir, "system");
10392        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10393        return fname;
10394    }
10395
10396    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10397        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10398        File file = getCalledPreBootReceiversFile();
10399        FileInputStream fis = null;
10400        try {
10401            fis = new FileInputStream(file);
10402            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10403            int fvers = dis.readInt();
10404            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10405                String vers = dis.readUTF();
10406                String codename = dis.readUTF();
10407                String build = dis.readUTF();
10408                if (android.os.Build.VERSION.RELEASE.equals(vers)
10409                        && android.os.Build.VERSION.CODENAME.equals(codename)
10410                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10411                    int num = dis.readInt();
10412                    while (num > 0) {
10413                        num--;
10414                        String pkg = dis.readUTF();
10415                        String cls = dis.readUTF();
10416                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10417                    }
10418                }
10419            }
10420        } catch (FileNotFoundException e) {
10421        } catch (IOException e) {
10422            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10423        } finally {
10424            if (fis != null) {
10425                try {
10426                    fis.close();
10427                } catch (IOException e) {
10428                }
10429            }
10430        }
10431        return lastDoneReceivers;
10432    }
10433
10434    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10435        File file = getCalledPreBootReceiversFile();
10436        FileOutputStream fos = null;
10437        DataOutputStream dos = null;
10438        try {
10439            fos = new FileOutputStream(file);
10440            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10441            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10442            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10443            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10444            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10445            dos.writeInt(list.size());
10446            for (int i=0; i<list.size(); i++) {
10447                dos.writeUTF(list.get(i).getPackageName());
10448                dos.writeUTF(list.get(i).getClassName());
10449            }
10450        } catch (IOException e) {
10451            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10452            file.delete();
10453        } finally {
10454            FileUtils.sync(fos);
10455            if (dos != null) {
10456                try {
10457                    dos.close();
10458                } catch (IOException e) {
10459                    // TODO Auto-generated catch block
10460                    e.printStackTrace();
10461                }
10462            }
10463        }
10464    }
10465
10466    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10467            ArrayList<ComponentName> doneReceivers, int userId) {
10468        boolean waitingUpdate = false;
10469        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10470        List<ResolveInfo> ris = null;
10471        try {
10472            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10473                    intent, null, 0, userId);
10474        } catch (RemoteException e) {
10475        }
10476        if (ris != null) {
10477            for (int i=ris.size()-1; i>=0; i--) {
10478                if ((ris.get(i).activityInfo.applicationInfo.flags
10479                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10480                    ris.remove(i);
10481                }
10482            }
10483            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10484
10485            // For User 0, load the version number. When delivering to a new user, deliver
10486            // to all receivers.
10487            if (userId == UserHandle.USER_OWNER) {
10488                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10489                for (int i=0; i<ris.size(); i++) {
10490                    ActivityInfo ai = ris.get(i).activityInfo;
10491                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10492                    if (lastDoneReceivers.contains(comp)) {
10493                        // We already did the pre boot receiver for this app with the current
10494                        // platform version, so don't do it again...
10495                        ris.remove(i);
10496                        i--;
10497                        // ...however, do keep it as one that has been done, so we don't
10498                        // forget about it when rewriting the file of last done receivers.
10499                        doneReceivers.add(comp);
10500                    }
10501                }
10502            }
10503
10504            // If primary user, send broadcast to all available users, else just to userId
10505            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10506                    : new int[] { userId };
10507            for (int i = 0; i < ris.size(); i++) {
10508                ActivityInfo ai = ris.get(i).activityInfo;
10509                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10510                doneReceivers.add(comp);
10511                intent.setComponent(comp);
10512                for (int j=0; j<users.length; j++) {
10513                    IIntentReceiver finisher = null;
10514                    // On last receiver and user, set up a completion callback
10515                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10516                        finisher = new IIntentReceiver.Stub() {
10517                            public void performReceive(Intent intent, int resultCode,
10518                                    String data, Bundle extras, boolean ordered,
10519                                    boolean sticky, int sendingUser) {
10520                                // The raw IIntentReceiver interface is called
10521                                // with the AM lock held, so redispatch to
10522                                // execute our code without the lock.
10523                                mHandler.post(onFinishCallback);
10524                            }
10525                        };
10526                    }
10527                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10528                            + " for user " + users[j]);
10529                    broadcastIntentLocked(null, null, intent, null, finisher,
10530                            0, null, null, null, AppOpsManager.OP_NONE,
10531                            true, false, MY_PID, Process.SYSTEM_UID,
10532                            users[j]);
10533                    if (finisher != null) {
10534                        waitingUpdate = true;
10535                    }
10536                }
10537            }
10538        }
10539
10540        return waitingUpdate;
10541    }
10542
10543    public void systemReady(final Runnable goingCallback) {
10544        synchronized(this) {
10545            if (mSystemReady) {
10546                // If we're done calling all the receivers, run the next "boot phase" passed in
10547                // by the SystemServer
10548                if (goingCallback != null) {
10549                    goingCallback.run();
10550                }
10551                return;
10552            }
10553
10554            // Make sure we have the current profile info, since it is needed for
10555            // security checks.
10556            updateCurrentProfileIdsLocked();
10557
10558            if (mRecentTasks == null) {
10559                mRecentTasks = mTaskPersister.restoreTasksLocked();
10560                if (!mRecentTasks.isEmpty()) {
10561                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10562                }
10563                mTaskPersister.startPersisting();
10564            }
10565
10566            // Check to see if there are any update receivers to run.
10567            if (!mDidUpdate) {
10568                if (mWaitingUpdate) {
10569                    return;
10570                }
10571                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10572                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10573                    public void run() {
10574                        synchronized (ActivityManagerService.this) {
10575                            mDidUpdate = true;
10576                        }
10577                        writeLastDonePreBootReceivers(doneReceivers);
10578                        showBootMessage(mContext.getText(
10579                                R.string.android_upgrading_complete),
10580                                false);
10581                        systemReady(goingCallback);
10582                    }
10583                }, doneReceivers, UserHandle.USER_OWNER);
10584
10585                if (mWaitingUpdate) {
10586                    return;
10587                }
10588                mDidUpdate = true;
10589            }
10590
10591            mAppOpsService.systemReady();
10592            mSystemReady = true;
10593        }
10594
10595        ArrayList<ProcessRecord> procsToKill = null;
10596        synchronized(mPidsSelfLocked) {
10597            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10598                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10599                if (!isAllowedWhileBooting(proc.info)){
10600                    if (procsToKill == null) {
10601                        procsToKill = new ArrayList<ProcessRecord>();
10602                    }
10603                    procsToKill.add(proc);
10604                }
10605            }
10606        }
10607
10608        synchronized(this) {
10609            if (procsToKill != null) {
10610                for (int i=procsToKill.size()-1; i>=0; i--) {
10611                    ProcessRecord proc = procsToKill.get(i);
10612                    Slog.i(TAG, "Removing system update proc: " + proc);
10613                    removeProcessLocked(proc, true, false, "system update done");
10614                }
10615            }
10616
10617            // Now that we have cleaned up any update processes, we
10618            // are ready to start launching real processes and know that
10619            // we won't trample on them any more.
10620            mProcessesReady = true;
10621        }
10622
10623        Slog.i(TAG, "System now ready");
10624        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10625            SystemClock.uptimeMillis());
10626
10627        synchronized(this) {
10628            // Make sure we have no pre-ready processes sitting around.
10629
10630            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10631                ResolveInfo ri = mContext.getPackageManager()
10632                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10633                                STOCK_PM_FLAGS);
10634                CharSequence errorMsg = null;
10635                if (ri != null) {
10636                    ActivityInfo ai = ri.activityInfo;
10637                    ApplicationInfo app = ai.applicationInfo;
10638                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10639                        mTopAction = Intent.ACTION_FACTORY_TEST;
10640                        mTopData = null;
10641                        mTopComponent = new ComponentName(app.packageName,
10642                                ai.name);
10643                    } else {
10644                        errorMsg = mContext.getResources().getText(
10645                                com.android.internal.R.string.factorytest_not_system);
10646                    }
10647                } else {
10648                    errorMsg = mContext.getResources().getText(
10649                            com.android.internal.R.string.factorytest_no_action);
10650                }
10651                if (errorMsg != null) {
10652                    mTopAction = null;
10653                    mTopData = null;
10654                    mTopComponent = null;
10655                    Message msg = Message.obtain();
10656                    msg.what = SHOW_FACTORY_ERROR_MSG;
10657                    msg.getData().putCharSequence("msg", errorMsg);
10658                    mHandler.sendMessage(msg);
10659                }
10660            }
10661        }
10662
10663        retrieveSettings();
10664
10665        synchronized (this) {
10666            readGrantedUriPermissionsLocked();
10667        }
10668
10669        if (goingCallback != null) goingCallback.run();
10670
10671        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10672                Integer.toString(mCurrentUserId), mCurrentUserId);
10673        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10674                Integer.toString(mCurrentUserId), mCurrentUserId);
10675        mSystemServiceManager.startUser(mCurrentUserId);
10676
10677        synchronized (this) {
10678            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10679                try {
10680                    List apps = AppGlobals.getPackageManager().
10681                        getPersistentApplications(STOCK_PM_FLAGS);
10682                    if (apps != null) {
10683                        int N = apps.size();
10684                        int i;
10685                        for (i=0; i<N; i++) {
10686                            ApplicationInfo info
10687                                = (ApplicationInfo)apps.get(i);
10688                            if (info != null &&
10689                                    !info.packageName.equals("android")) {
10690                                addAppLocked(info, false, null /* ABI override */);
10691                            }
10692                        }
10693                    }
10694                } catch (RemoteException ex) {
10695                    // pm is in same process, this will never happen.
10696                }
10697            }
10698
10699            // Start up initial activity.
10700            mBooting = true;
10701
10702            try {
10703                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10704                    Message msg = Message.obtain();
10705                    msg.what = SHOW_UID_ERROR_MSG;
10706                    mHandler.sendMessage(msg);
10707                }
10708            } catch (RemoteException e) {
10709            }
10710
10711            long ident = Binder.clearCallingIdentity();
10712            try {
10713                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10714                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10715                        | Intent.FLAG_RECEIVER_FOREGROUND);
10716                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10717                broadcastIntentLocked(null, null, intent,
10718                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10719                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10720                intent = new Intent(Intent.ACTION_USER_STARTING);
10721                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10722                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10723                broadcastIntentLocked(null, null, intent,
10724                        null, new IIntentReceiver.Stub() {
10725                            @Override
10726                            public void performReceive(Intent intent, int resultCode, String data,
10727                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10728                                    throws RemoteException {
10729                            }
10730                        }, 0, null, null,
10731                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10732                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10733            } catch (Throwable t) {
10734                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10735            } finally {
10736                Binder.restoreCallingIdentity(ident);
10737            }
10738            mStackSupervisor.resumeTopActivitiesLocked();
10739            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10740        }
10741    }
10742
10743    private boolean makeAppCrashingLocked(ProcessRecord app,
10744            String shortMsg, String longMsg, String stackTrace) {
10745        app.crashing = true;
10746        app.crashingReport = generateProcessError(app,
10747                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10748        startAppProblemLocked(app);
10749        app.stopFreezingAllLocked();
10750        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10751    }
10752
10753    private void makeAppNotRespondingLocked(ProcessRecord app,
10754            String activity, String shortMsg, String longMsg) {
10755        app.notResponding = true;
10756        app.notRespondingReport = generateProcessError(app,
10757                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10758                activity, shortMsg, longMsg, null);
10759        startAppProblemLocked(app);
10760        app.stopFreezingAllLocked();
10761    }
10762
10763    /**
10764     * Generate a process error record, suitable for attachment to a ProcessRecord.
10765     *
10766     * @param app The ProcessRecord in which the error occurred.
10767     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10768     *                      ActivityManager.AppErrorStateInfo
10769     * @param activity The activity associated with the crash, if known.
10770     * @param shortMsg Short message describing the crash.
10771     * @param longMsg Long message describing the crash.
10772     * @param stackTrace Full crash stack trace, may be null.
10773     *
10774     * @return Returns a fully-formed AppErrorStateInfo record.
10775     */
10776    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10777            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10778        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10779
10780        report.condition = condition;
10781        report.processName = app.processName;
10782        report.pid = app.pid;
10783        report.uid = app.info.uid;
10784        report.tag = activity;
10785        report.shortMsg = shortMsg;
10786        report.longMsg = longMsg;
10787        report.stackTrace = stackTrace;
10788
10789        return report;
10790    }
10791
10792    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10793        synchronized (this) {
10794            app.crashing = false;
10795            app.crashingReport = null;
10796            app.notResponding = false;
10797            app.notRespondingReport = null;
10798            if (app.anrDialog == fromDialog) {
10799                app.anrDialog = null;
10800            }
10801            if (app.waitDialog == fromDialog) {
10802                app.waitDialog = null;
10803            }
10804            if (app.pid > 0 && app.pid != MY_PID) {
10805                handleAppCrashLocked(app, null, null, null);
10806                app.kill("user request after error", true);
10807            }
10808        }
10809    }
10810
10811    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10812            String stackTrace) {
10813        long now = SystemClock.uptimeMillis();
10814
10815        Long crashTime;
10816        if (!app.isolated) {
10817            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10818        } else {
10819            crashTime = null;
10820        }
10821        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10822            // This process loses!
10823            Slog.w(TAG, "Process " + app.info.processName
10824                    + " has crashed too many times: killing!");
10825            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10826                    app.userId, app.info.processName, app.uid);
10827            mStackSupervisor.handleAppCrashLocked(app);
10828            if (!app.persistent) {
10829                // We don't want to start this process again until the user
10830                // explicitly does so...  but for persistent process, we really
10831                // need to keep it running.  If a persistent process is actually
10832                // repeatedly crashing, then badness for everyone.
10833                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10834                        app.info.processName);
10835                if (!app.isolated) {
10836                    // XXX We don't have a way to mark isolated processes
10837                    // as bad, since they don't have a peristent identity.
10838                    mBadProcesses.put(app.info.processName, app.uid,
10839                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10840                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10841                }
10842                app.bad = true;
10843                app.removed = true;
10844                // Don't let services in this process be restarted and potentially
10845                // annoy the user repeatedly.  Unless it is persistent, since those
10846                // processes run critical code.
10847                removeProcessLocked(app, false, false, "crash");
10848                mStackSupervisor.resumeTopActivitiesLocked();
10849                return false;
10850            }
10851            mStackSupervisor.resumeTopActivitiesLocked();
10852        } else {
10853            mStackSupervisor.finishTopRunningActivityLocked(app);
10854        }
10855
10856        // Bump up the crash count of any services currently running in the proc.
10857        for (int i=app.services.size()-1; i>=0; i--) {
10858            // Any services running in the application need to be placed
10859            // back in the pending list.
10860            ServiceRecord sr = app.services.valueAt(i);
10861            sr.crashCount++;
10862        }
10863
10864        // If the crashing process is what we consider to be the "home process" and it has been
10865        // replaced by a third-party app, clear the package preferred activities from packages
10866        // with a home activity running in the process to prevent a repeatedly crashing app
10867        // from blocking the user to manually clear the list.
10868        final ArrayList<ActivityRecord> activities = app.activities;
10869        if (app == mHomeProcess && activities.size() > 0
10870                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10871            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10872                final ActivityRecord r = activities.get(activityNdx);
10873                if (r.isHomeActivity()) {
10874                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10875                    try {
10876                        ActivityThread.getPackageManager()
10877                                .clearPackagePreferredActivities(r.packageName);
10878                    } catch (RemoteException c) {
10879                        // pm is in same process, this will never happen.
10880                    }
10881                }
10882            }
10883        }
10884
10885        if (!app.isolated) {
10886            // XXX Can't keep track of crash times for isolated processes,
10887            // because they don't have a perisistent identity.
10888            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10889        }
10890
10891        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10892        return true;
10893    }
10894
10895    void startAppProblemLocked(ProcessRecord app) {
10896        // If this app is not running under the current user, then we
10897        // can't give it a report button because that would require
10898        // launching the report UI under a different user.
10899        app.errorReportReceiver = null;
10900
10901        for (int userId : mCurrentProfileIds) {
10902            if (app.userId == userId) {
10903                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10904                        mContext, app.info.packageName, app.info.flags);
10905            }
10906        }
10907        skipCurrentReceiverLocked(app);
10908    }
10909
10910    void skipCurrentReceiverLocked(ProcessRecord app) {
10911        for (BroadcastQueue queue : mBroadcastQueues) {
10912            queue.skipCurrentReceiverLocked(app);
10913        }
10914    }
10915
10916    /**
10917     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10918     * The application process will exit immediately after this call returns.
10919     * @param app object of the crashing app, null for the system server
10920     * @param crashInfo describing the exception
10921     */
10922    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10923        ProcessRecord r = findAppProcess(app, "Crash");
10924        final String processName = app == null ? "system_server"
10925                : (r == null ? "unknown" : r.processName);
10926
10927        handleApplicationCrashInner("crash", r, processName, crashInfo);
10928    }
10929
10930    /* Native crash reporting uses this inner version because it needs to be somewhat
10931     * decoupled from the AM-managed cleanup lifecycle
10932     */
10933    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10934            ApplicationErrorReport.CrashInfo crashInfo) {
10935        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10936                UserHandle.getUserId(Binder.getCallingUid()), processName,
10937                r == null ? -1 : r.info.flags,
10938                crashInfo.exceptionClassName,
10939                crashInfo.exceptionMessage,
10940                crashInfo.throwFileName,
10941                crashInfo.throwLineNumber);
10942
10943        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10944
10945        crashApplication(r, crashInfo);
10946    }
10947
10948    public void handleApplicationStrictModeViolation(
10949            IBinder app,
10950            int violationMask,
10951            StrictMode.ViolationInfo info) {
10952        ProcessRecord r = findAppProcess(app, "StrictMode");
10953        if (r == null) {
10954            return;
10955        }
10956
10957        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10958            Integer stackFingerprint = info.hashCode();
10959            boolean logIt = true;
10960            synchronized (mAlreadyLoggedViolatedStacks) {
10961                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10962                    logIt = false;
10963                    // TODO: sub-sample into EventLog for these, with
10964                    // the info.durationMillis?  Then we'd get
10965                    // the relative pain numbers, without logging all
10966                    // the stack traces repeatedly.  We'd want to do
10967                    // likewise in the client code, which also does
10968                    // dup suppression, before the Binder call.
10969                } else {
10970                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10971                        mAlreadyLoggedViolatedStacks.clear();
10972                    }
10973                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10974                }
10975            }
10976            if (logIt) {
10977                logStrictModeViolationToDropBox(r, info);
10978            }
10979        }
10980
10981        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10982            AppErrorResult result = new AppErrorResult();
10983            synchronized (this) {
10984                final long origId = Binder.clearCallingIdentity();
10985
10986                Message msg = Message.obtain();
10987                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10988                HashMap<String, Object> data = new HashMap<String, Object>();
10989                data.put("result", result);
10990                data.put("app", r);
10991                data.put("violationMask", violationMask);
10992                data.put("info", info);
10993                msg.obj = data;
10994                mHandler.sendMessage(msg);
10995
10996                Binder.restoreCallingIdentity(origId);
10997            }
10998            int res = result.get();
10999            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11000        }
11001    }
11002
11003    // Depending on the policy in effect, there could be a bunch of
11004    // these in quick succession so we try to batch these together to
11005    // minimize disk writes, number of dropbox entries, and maximize
11006    // compression, by having more fewer, larger records.
11007    private void logStrictModeViolationToDropBox(
11008            ProcessRecord process,
11009            StrictMode.ViolationInfo info) {
11010        if (info == null) {
11011            return;
11012        }
11013        final boolean isSystemApp = process == null ||
11014                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11015                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11016        final String processName = process == null ? "unknown" : process.processName;
11017        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11018        final DropBoxManager dbox = (DropBoxManager)
11019                mContext.getSystemService(Context.DROPBOX_SERVICE);
11020
11021        // Exit early if the dropbox isn't configured to accept this report type.
11022        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11023
11024        boolean bufferWasEmpty;
11025        boolean needsFlush;
11026        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11027        synchronized (sb) {
11028            bufferWasEmpty = sb.length() == 0;
11029            appendDropBoxProcessHeaders(process, processName, sb);
11030            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11031            sb.append("System-App: ").append(isSystemApp).append("\n");
11032            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11033            if (info.violationNumThisLoop != 0) {
11034                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11035            }
11036            if (info.numAnimationsRunning != 0) {
11037                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11038            }
11039            if (info.broadcastIntentAction != null) {
11040                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11041            }
11042            if (info.durationMillis != -1) {
11043                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11044            }
11045            if (info.numInstances != -1) {
11046                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11047            }
11048            if (info.tags != null) {
11049                for (String tag : info.tags) {
11050                    sb.append("Span-Tag: ").append(tag).append("\n");
11051                }
11052            }
11053            sb.append("\n");
11054            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11055                sb.append(info.crashInfo.stackTrace);
11056            }
11057            sb.append("\n");
11058
11059            // Only buffer up to ~64k.  Various logging bits truncate
11060            // things at 128k.
11061            needsFlush = (sb.length() > 64 * 1024);
11062        }
11063
11064        // Flush immediately if the buffer's grown too large, or this
11065        // is a non-system app.  Non-system apps are isolated with a
11066        // different tag & policy and not batched.
11067        //
11068        // Batching is useful during internal testing with
11069        // StrictMode settings turned up high.  Without batching,
11070        // thousands of separate files could be created on boot.
11071        if (!isSystemApp || needsFlush) {
11072            new Thread("Error dump: " + dropboxTag) {
11073                @Override
11074                public void run() {
11075                    String report;
11076                    synchronized (sb) {
11077                        report = sb.toString();
11078                        sb.delete(0, sb.length());
11079                        sb.trimToSize();
11080                    }
11081                    if (report.length() != 0) {
11082                        dbox.addText(dropboxTag, report);
11083                    }
11084                }
11085            }.start();
11086            return;
11087        }
11088
11089        // System app batching:
11090        if (!bufferWasEmpty) {
11091            // An existing dropbox-writing thread is outstanding, so
11092            // we don't need to start it up.  The existing thread will
11093            // catch the buffer appends we just did.
11094            return;
11095        }
11096
11097        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11098        // (After this point, we shouldn't access AMS internal data structures.)
11099        new Thread("Error dump: " + dropboxTag) {
11100            @Override
11101            public void run() {
11102                // 5 second sleep to let stacks arrive and be batched together
11103                try {
11104                    Thread.sleep(5000);  // 5 seconds
11105                } catch (InterruptedException e) {}
11106
11107                String errorReport;
11108                synchronized (mStrictModeBuffer) {
11109                    errorReport = mStrictModeBuffer.toString();
11110                    if (errorReport.length() == 0) {
11111                        return;
11112                    }
11113                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11114                    mStrictModeBuffer.trimToSize();
11115                }
11116                dbox.addText(dropboxTag, errorReport);
11117            }
11118        }.start();
11119    }
11120
11121    /**
11122     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11123     * @param app object of the crashing app, null for the system server
11124     * @param tag reported by the caller
11125     * @param crashInfo describing the context of the error
11126     * @return true if the process should exit immediately (WTF is fatal)
11127     */
11128    public boolean handleApplicationWtf(IBinder app, String tag,
11129            ApplicationErrorReport.CrashInfo crashInfo) {
11130        ProcessRecord r = findAppProcess(app, "WTF");
11131        final String processName = app == null ? "system_server"
11132                : (r == null ? "unknown" : r.processName);
11133
11134        EventLog.writeEvent(EventLogTags.AM_WTF,
11135                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11136                processName,
11137                r == null ? -1 : r.info.flags,
11138                tag, crashInfo.exceptionMessage);
11139
11140        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11141
11142        if (r != null && r.pid != Process.myPid() &&
11143                Settings.Global.getInt(mContext.getContentResolver(),
11144                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11145            crashApplication(r, crashInfo);
11146            return true;
11147        } else {
11148            return false;
11149        }
11150    }
11151
11152    /**
11153     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11154     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11155     */
11156    private ProcessRecord findAppProcess(IBinder app, String reason) {
11157        if (app == null) {
11158            return null;
11159        }
11160
11161        synchronized (this) {
11162            final int NP = mProcessNames.getMap().size();
11163            for (int ip=0; ip<NP; ip++) {
11164                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11165                final int NA = apps.size();
11166                for (int ia=0; ia<NA; ia++) {
11167                    ProcessRecord p = apps.valueAt(ia);
11168                    if (p.thread != null && p.thread.asBinder() == app) {
11169                        return p;
11170                    }
11171                }
11172            }
11173
11174            Slog.w(TAG, "Can't find mystery application for " + reason
11175                    + " from pid=" + Binder.getCallingPid()
11176                    + " uid=" + Binder.getCallingUid() + ": " + app);
11177            return null;
11178        }
11179    }
11180
11181    /**
11182     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11183     * to append various headers to the dropbox log text.
11184     */
11185    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11186            StringBuilder sb) {
11187        // Watchdog thread ends up invoking this function (with
11188        // a null ProcessRecord) to add the stack file to dropbox.
11189        // Do not acquire a lock on this (am) in such cases, as it
11190        // could cause a potential deadlock, if and when watchdog
11191        // is invoked due to unavailability of lock on am and it
11192        // would prevent watchdog from killing system_server.
11193        if (process == null) {
11194            sb.append("Process: ").append(processName).append("\n");
11195            return;
11196        }
11197        // Note: ProcessRecord 'process' is guarded by the service
11198        // instance.  (notably process.pkgList, which could otherwise change
11199        // concurrently during execution of this method)
11200        synchronized (this) {
11201            sb.append("Process: ").append(processName).append("\n");
11202            int flags = process.info.flags;
11203            IPackageManager pm = AppGlobals.getPackageManager();
11204            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11205            for (int ip=0; ip<process.pkgList.size(); ip++) {
11206                String pkg = process.pkgList.keyAt(ip);
11207                sb.append("Package: ").append(pkg);
11208                try {
11209                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11210                    if (pi != null) {
11211                        sb.append(" v").append(pi.versionCode);
11212                        if (pi.versionName != null) {
11213                            sb.append(" (").append(pi.versionName).append(")");
11214                        }
11215                    }
11216                } catch (RemoteException e) {
11217                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11218                }
11219                sb.append("\n");
11220            }
11221        }
11222    }
11223
11224    private static String processClass(ProcessRecord process) {
11225        if (process == null || process.pid == MY_PID) {
11226            return "system_server";
11227        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11228            return "system_app";
11229        } else {
11230            return "data_app";
11231        }
11232    }
11233
11234    /**
11235     * Write a description of an error (crash, WTF, ANR) to the drop box.
11236     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11237     * @param process which caused the error, null means the system server
11238     * @param activity which triggered the error, null if unknown
11239     * @param parent activity related to the error, null if unknown
11240     * @param subject line related to the error, null if absent
11241     * @param report in long form describing the error, null if absent
11242     * @param logFile to include in the report, null if none
11243     * @param crashInfo giving an application stack trace, null if absent
11244     */
11245    public void addErrorToDropBox(String eventType,
11246            ProcessRecord process, String processName, ActivityRecord activity,
11247            ActivityRecord parent, String subject,
11248            final String report, final File logFile,
11249            final ApplicationErrorReport.CrashInfo crashInfo) {
11250        // NOTE -- this must never acquire the ActivityManagerService lock,
11251        // otherwise the watchdog may be prevented from resetting the system.
11252
11253        final String dropboxTag = processClass(process) + "_" + eventType;
11254        final DropBoxManager dbox = (DropBoxManager)
11255                mContext.getSystemService(Context.DROPBOX_SERVICE);
11256
11257        // Exit early if the dropbox isn't configured to accept this report type.
11258        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11259
11260        final StringBuilder sb = new StringBuilder(1024);
11261        appendDropBoxProcessHeaders(process, processName, sb);
11262        if (activity != null) {
11263            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11264        }
11265        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11266            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11267        }
11268        if (parent != null && parent != activity) {
11269            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11270        }
11271        if (subject != null) {
11272            sb.append("Subject: ").append(subject).append("\n");
11273        }
11274        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11275        if (Debug.isDebuggerConnected()) {
11276            sb.append("Debugger: Connected\n");
11277        }
11278        sb.append("\n");
11279
11280        // Do the rest in a worker thread to avoid blocking the caller on I/O
11281        // (After this point, we shouldn't access AMS internal data structures.)
11282        Thread worker = new Thread("Error dump: " + dropboxTag) {
11283            @Override
11284            public void run() {
11285                if (report != null) {
11286                    sb.append(report);
11287                }
11288                if (logFile != null) {
11289                    try {
11290                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11291                                    "\n\n[[TRUNCATED]]"));
11292                    } catch (IOException e) {
11293                        Slog.e(TAG, "Error reading " + logFile, e);
11294                    }
11295                }
11296                if (crashInfo != null && crashInfo.stackTrace != null) {
11297                    sb.append(crashInfo.stackTrace);
11298                }
11299
11300                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11301                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11302                if (lines > 0) {
11303                    sb.append("\n");
11304
11305                    // Merge several logcat streams, and take the last N lines
11306                    InputStreamReader input = null;
11307                    try {
11308                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11309                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11310                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11311
11312                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11313                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11314                        input = new InputStreamReader(logcat.getInputStream());
11315
11316                        int num;
11317                        char[] buf = new char[8192];
11318                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11319                    } catch (IOException e) {
11320                        Slog.e(TAG, "Error running logcat", e);
11321                    } finally {
11322                        if (input != null) try { input.close(); } catch (IOException e) {}
11323                    }
11324                }
11325
11326                dbox.addText(dropboxTag, sb.toString());
11327            }
11328        };
11329
11330        if (process == null) {
11331            // If process is null, we are being called from some internal code
11332            // and may be about to die -- run this synchronously.
11333            worker.run();
11334        } else {
11335            worker.start();
11336        }
11337    }
11338
11339    /**
11340     * Bring up the "unexpected error" dialog box for a crashing app.
11341     * Deal with edge cases (intercepts from instrumented applications,
11342     * ActivityController, error intent receivers, that sort of thing).
11343     * @param r the application crashing
11344     * @param crashInfo describing the failure
11345     */
11346    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11347        long timeMillis = System.currentTimeMillis();
11348        String shortMsg = crashInfo.exceptionClassName;
11349        String longMsg = crashInfo.exceptionMessage;
11350        String stackTrace = crashInfo.stackTrace;
11351        if (shortMsg != null && longMsg != null) {
11352            longMsg = shortMsg + ": " + longMsg;
11353        } else if (shortMsg != null) {
11354            longMsg = shortMsg;
11355        }
11356
11357        AppErrorResult result = new AppErrorResult();
11358        synchronized (this) {
11359            if (mController != null) {
11360                try {
11361                    String name = r != null ? r.processName : null;
11362                    int pid = r != null ? r.pid : Binder.getCallingPid();
11363                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11364                    if (!mController.appCrashed(name, pid,
11365                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11366                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11367                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11368                            Slog.w(TAG, "Skip killing native crashed app " + name
11369                                    + "(" + pid + ") during testing");
11370                        } else {
11371                            Slog.w(TAG, "Force-killing crashed app " + name
11372                                    + " at watcher's request");
11373                            if (r != null) {
11374                                r.kill("crash", true);
11375                            } else {
11376                                // Huh.
11377                                Process.killProcess(pid);
11378                                Process.killProcessGroup(uid, pid);
11379                            }
11380                        }
11381                        return;
11382                    }
11383                } catch (RemoteException e) {
11384                    mController = null;
11385                    Watchdog.getInstance().setActivityController(null);
11386                }
11387            }
11388
11389            final long origId = Binder.clearCallingIdentity();
11390
11391            // If this process is running instrumentation, finish it.
11392            if (r != null && r.instrumentationClass != null) {
11393                Slog.w(TAG, "Error in app " + r.processName
11394                      + " running instrumentation " + r.instrumentationClass + ":");
11395                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11396                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11397                Bundle info = new Bundle();
11398                info.putString("shortMsg", shortMsg);
11399                info.putString("longMsg", longMsg);
11400                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11401                Binder.restoreCallingIdentity(origId);
11402                return;
11403            }
11404
11405            // If we can't identify the process or it's already exceeded its crash quota,
11406            // quit right away without showing a crash dialog.
11407            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11408                Binder.restoreCallingIdentity(origId);
11409                return;
11410            }
11411
11412            Message msg = Message.obtain();
11413            msg.what = SHOW_ERROR_MSG;
11414            HashMap data = new HashMap();
11415            data.put("result", result);
11416            data.put("app", r);
11417            msg.obj = data;
11418            mHandler.sendMessage(msg);
11419
11420            Binder.restoreCallingIdentity(origId);
11421        }
11422
11423        int res = result.get();
11424
11425        Intent appErrorIntent = null;
11426        synchronized (this) {
11427            if (r != null && !r.isolated) {
11428                // XXX Can't keep track of crash time for isolated processes,
11429                // since they don't have a persistent identity.
11430                mProcessCrashTimes.put(r.info.processName, r.uid,
11431                        SystemClock.uptimeMillis());
11432            }
11433            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11434                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11435            }
11436        }
11437
11438        if (appErrorIntent != null) {
11439            try {
11440                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11441            } catch (ActivityNotFoundException e) {
11442                Slog.w(TAG, "bug report receiver dissappeared", e);
11443            }
11444        }
11445    }
11446
11447    Intent createAppErrorIntentLocked(ProcessRecord r,
11448            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11449        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11450        if (report == null) {
11451            return null;
11452        }
11453        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11454        result.setComponent(r.errorReportReceiver);
11455        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11456        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11457        return result;
11458    }
11459
11460    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11461            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11462        if (r.errorReportReceiver == null) {
11463            return null;
11464        }
11465
11466        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11467            return null;
11468        }
11469
11470        ApplicationErrorReport report = new ApplicationErrorReport();
11471        report.packageName = r.info.packageName;
11472        report.installerPackageName = r.errorReportReceiver.getPackageName();
11473        report.processName = r.processName;
11474        report.time = timeMillis;
11475        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11476
11477        if (r.crashing || r.forceCrashReport) {
11478            report.type = ApplicationErrorReport.TYPE_CRASH;
11479            report.crashInfo = crashInfo;
11480        } else if (r.notResponding) {
11481            report.type = ApplicationErrorReport.TYPE_ANR;
11482            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11483
11484            report.anrInfo.activity = r.notRespondingReport.tag;
11485            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11486            report.anrInfo.info = r.notRespondingReport.longMsg;
11487        }
11488
11489        return report;
11490    }
11491
11492    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11493        enforceNotIsolatedCaller("getProcessesInErrorState");
11494        // assume our apps are happy - lazy create the list
11495        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11496
11497        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11498                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11499        int userId = UserHandle.getUserId(Binder.getCallingUid());
11500
11501        synchronized (this) {
11502
11503            // iterate across all processes
11504            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11505                ProcessRecord app = mLruProcesses.get(i);
11506                if (!allUsers && app.userId != userId) {
11507                    continue;
11508                }
11509                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11510                    // This one's in trouble, so we'll generate a report for it
11511                    // crashes are higher priority (in case there's a crash *and* an anr)
11512                    ActivityManager.ProcessErrorStateInfo report = null;
11513                    if (app.crashing) {
11514                        report = app.crashingReport;
11515                    } else if (app.notResponding) {
11516                        report = app.notRespondingReport;
11517                    }
11518
11519                    if (report != null) {
11520                        if (errList == null) {
11521                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11522                        }
11523                        errList.add(report);
11524                    } else {
11525                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11526                                " crashing = " + app.crashing +
11527                                " notResponding = " + app.notResponding);
11528                    }
11529                }
11530            }
11531        }
11532
11533        return errList;
11534    }
11535
11536    static int procStateToImportance(int procState, int memAdj,
11537            ActivityManager.RunningAppProcessInfo currApp) {
11538        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11539        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11540            currApp.lru = memAdj;
11541        } else {
11542            currApp.lru = 0;
11543        }
11544        return imp;
11545    }
11546
11547    private void fillInProcMemInfo(ProcessRecord app,
11548            ActivityManager.RunningAppProcessInfo outInfo) {
11549        outInfo.pid = app.pid;
11550        outInfo.uid = app.info.uid;
11551        if (mHeavyWeightProcess == app) {
11552            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11553        }
11554        if (app.persistent) {
11555            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11556        }
11557        if (app.activities.size() > 0) {
11558            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11559        }
11560        outInfo.lastTrimLevel = app.trimMemoryLevel;
11561        int adj = app.curAdj;
11562        int procState = app.curProcState;
11563        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11564        outInfo.importanceReasonCode = app.adjTypeCode;
11565        outInfo.processState = app.curProcState;
11566    }
11567
11568    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11569        enforceNotIsolatedCaller("getRunningAppProcesses");
11570        // Lazy instantiation of list
11571        List<ActivityManager.RunningAppProcessInfo> runList = null;
11572        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11573                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11574        int userId = UserHandle.getUserId(Binder.getCallingUid());
11575        synchronized (this) {
11576            // Iterate across all processes
11577            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11578                ProcessRecord app = mLruProcesses.get(i);
11579                if (!allUsers && app.userId != userId) {
11580                    continue;
11581                }
11582                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11583                    // Generate process state info for running application
11584                    ActivityManager.RunningAppProcessInfo currApp =
11585                        new ActivityManager.RunningAppProcessInfo(app.processName,
11586                                app.pid, app.getPackageList());
11587                    fillInProcMemInfo(app, currApp);
11588                    if (app.adjSource instanceof ProcessRecord) {
11589                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11590                        currApp.importanceReasonImportance =
11591                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11592                                        app.adjSourceProcState);
11593                    } else if (app.adjSource instanceof ActivityRecord) {
11594                        ActivityRecord r = (ActivityRecord)app.adjSource;
11595                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11596                    }
11597                    if (app.adjTarget instanceof ComponentName) {
11598                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11599                    }
11600                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11601                    //        + " lru=" + currApp.lru);
11602                    if (runList == null) {
11603                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11604                    }
11605                    runList.add(currApp);
11606                }
11607            }
11608        }
11609        return runList;
11610    }
11611
11612    public List<ApplicationInfo> getRunningExternalApplications() {
11613        enforceNotIsolatedCaller("getRunningExternalApplications");
11614        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11615        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11616        if (runningApps != null && runningApps.size() > 0) {
11617            Set<String> extList = new HashSet<String>();
11618            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11619                if (app.pkgList != null) {
11620                    for (String pkg : app.pkgList) {
11621                        extList.add(pkg);
11622                    }
11623                }
11624            }
11625            IPackageManager pm = AppGlobals.getPackageManager();
11626            for (String pkg : extList) {
11627                try {
11628                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11629                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11630                        retList.add(info);
11631                    }
11632                } catch (RemoteException e) {
11633                }
11634            }
11635        }
11636        return retList;
11637    }
11638
11639    @Override
11640    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11641        enforceNotIsolatedCaller("getMyMemoryState");
11642        synchronized (this) {
11643            ProcessRecord proc;
11644            synchronized (mPidsSelfLocked) {
11645                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11646            }
11647            fillInProcMemInfo(proc, outInfo);
11648        }
11649    }
11650
11651    @Override
11652    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11653        if (checkCallingPermission(android.Manifest.permission.DUMP)
11654                != PackageManager.PERMISSION_GRANTED) {
11655            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11656                    + Binder.getCallingPid()
11657                    + ", uid=" + Binder.getCallingUid()
11658                    + " without permission "
11659                    + android.Manifest.permission.DUMP);
11660            return;
11661        }
11662
11663        boolean dumpAll = false;
11664        boolean dumpClient = false;
11665        String dumpPackage = null;
11666
11667        int opti = 0;
11668        while (opti < args.length) {
11669            String opt = args[opti];
11670            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11671                break;
11672            }
11673            opti++;
11674            if ("-a".equals(opt)) {
11675                dumpAll = true;
11676            } else if ("-c".equals(opt)) {
11677                dumpClient = true;
11678            } else if ("-h".equals(opt)) {
11679                pw.println("Activity manager dump options:");
11680                pw.println("  [-a] [-c] [-h] [cmd] ...");
11681                pw.println("  cmd may be one of:");
11682                pw.println("    a[ctivities]: activity stack state");
11683                pw.println("    r[recents]: recent activities state");
11684                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11685                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11686                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11687                pw.println("    o[om]: out of memory management");
11688                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11689                pw.println("    provider [COMP_SPEC]: provider client-side state");
11690                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11691                pw.println("    service [COMP_SPEC]: service client-side state");
11692                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11693                pw.println("    all: dump all activities");
11694                pw.println("    top: dump the top activity");
11695                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11696                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11697                pw.println("    a partial substring in a component name, a");
11698                pw.println("    hex object identifier.");
11699                pw.println("  -a: include all available server state.");
11700                pw.println("  -c: include client state.");
11701                return;
11702            } else {
11703                pw.println("Unknown argument: " + opt + "; use -h for help");
11704            }
11705        }
11706
11707        long origId = Binder.clearCallingIdentity();
11708        boolean more = false;
11709        // Is the caller requesting to dump a particular piece of data?
11710        if (opti < args.length) {
11711            String cmd = args[opti];
11712            opti++;
11713            if ("activities".equals(cmd) || "a".equals(cmd)) {
11714                synchronized (this) {
11715                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11716                }
11717            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11718                synchronized (this) {
11719                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11720                }
11721            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11722                String[] newArgs;
11723                String name;
11724                if (opti >= args.length) {
11725                    name = null;
11726                    newArgs = EMPTY_STRING_ARRAY;
11727                } else {
11728                    name = args[opti];
11729                    opti++;
11730                    newArgs = new String[args.length - opti];
11731                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11732                            args.length - opti);
11733                }
11734                synchronized (this) {
11735                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11736                }
11737            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11738                String[] newArgs;
11739                String name;
11740                if (opti >= args.length) {
11741                    name = null;
11742                    newArgs = EMPTY_STRING_ARRAY;
11743                } else {
11744                    name = args[opti];
11745                    opti++;
11746                    newArgs = new String[args.length - opti];
11747                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11748                            args.length - opti);
11749                }
11750                synchronized (this) {
11751                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11752                }
11753            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11754                String[] newArgs;
11755                String name;
11756                if (opti >= args.length) {
11757                    name = null;
11758                    newArgs = EMPTY_STRING_ARRAY;
11759                } else {
11760                    name = args[opti];
11761                    opti++;
11762                    newArgs = new String[args.length - opti];
11763                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11764                            args.length - opti);
11765                }
11766                synchronized (this) {
11767                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11768                }
11769            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11770                synchronized (this) {
11771                    dumpOomLocked(fd, pw, args, opti, true);
11772                }
11773            } else if ("provider".equals(cmd)) {
11774                String[] newArgs;
11775                String name;
11776                if (opti >= args.length) {
11777                    name = null;
11778                    newArgs = EMPTY_STRING_ARRAY;
11779                } else {
11780                    name = args[opti];
11781                    opti++;
11782                    newArgs = new String[args.length - opti];
11783                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11784                }
11785                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11786                    pw.println("No providers match: " + name);
11787                    pw.println("Use -h for help.");
11788                }
11789            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11790                synchronized (this) {
11791                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11792                }
11793            } else if ("service".equals(cmd)) {
11794                String[] newArgs;
11795                String name;
11796                if (opti >= args.length) {
11797                    name = null;
11798                    newArgs = EMPTY_STRING_ARRAY;
11799                } else {
11800                    name = args[opti];
11801                    opti++;
11802                    newArgs = new String[args.length - opti];
11803                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11804                            args.length - opti);
11805                }
11806                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11807                    pw.println("No services match: " + name);
11808                    pw.println("Use -h for help.");
11809                }
11810            } else if ("package".equals(cmd)) {
11811                String[] newArgs;
11812                if (opti >= args.length) {
11813                    pw.println("package: no package name specified");
11814                    pw.println("Use -h for help.");
11815                } else {
11816                    dumpPackage = args[opti];
11817                    opti++;
11818                    newArgs = new String[args.length - opti];
11819                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11820                            args.length - opti);
11821                    args = newArgs;
11822                    opti = 0;
11823                    more = true;
11824                }
11825            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11826                synchronized (this) {
11827                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11828                }
11829            } else {
11830                // Dumping a single activity?
11831                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11832                    pw.println("Bad activity command, or no activities match: " + cmd);
11833                    pw.println("Use -h for help.");
11834                }
11835            }
11836            if (!more) {
11837                Binder.restoreCallingIdentity(origId);
11838                return;
11839            }
11840        }
11841
11842        // No piece of data specified, dump everything.
11843        synchronized (this) {
11844            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11845            pw.println();
11846            if (dumpAll) {
11847                pw.println("-------------------------------------------------------------------------------");
11848            }
11849            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11850            pw.println();
11851            if (dumpAll) {
11852                pw.println("-------------------------------------------------------------------------------");
11853            }
11854            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11855            pw.println();
11856            if (dumpAll) {
11857                pw.println("-------------------------------------------------------------------------------");
11858            }
11859            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11860            pw.println();
11861            if (dumpAll) {
11862                pw.println("-------------------------------------------------------------------------------");
11863            }
11864            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11865            pw.println();
11866            if (dumpAll) {
11867                pw.println("-------------------------------------------------------------------------------");
11868            }
11869            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11870            pw.println();
11871            if (dumpAll) {
11872                pw.println("-------------------------------------------------------------------------------");
11873            }
11874            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11875        }
11876        Binder.restoreCallingIdentity(origId);
11877    }
11878
11879    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11880            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11881        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11882
11883        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11884                dumpPackage);
11885        boolean needSep = printedAnything;
11886
11887        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11888                dumpPackage, needSep, "  mFocusedActivity: ");
11889        if (printed) {
11890            printedAnything = true;
11891            needSep = false;
11892        }
11893
11894        if (dumpPackage == null) {
11895            if (needSep) {
11896                pw.println();
11897            }
11898            needSep = true;
11899            printedAnything = true;
11900            mStackSupervisor.dump(pw, "  ");
11901        }
11902
11903        if (!printedAnything) {
11904            pw.println("  (nothing)");
11905        }
11906    }
11907
11908    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11909            int opti, boolean dumpAll, String dumpPackage) {
11910        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11911
11912        boolean printedAnything = false;
11913
11914        if (mRecentTasks.size() > 0) {
11915            boolean printedHeader = false;
11916
11917            final int N = mRecentTasks.size();
11918            for (int i=0; i<N; i++) {
11919                TaskRecord tr = mRecentTasks.get(i);
11920                if (dumpPackage != null) {
11921                    if (tr.realActivity == null ||
11922                            !dumpPackage.equals(tr.realActivity)) {
11923                        continue;
11924                    }
11925                }
11926                if (!printedHeader) {
11927                    pw.println("  Recent tasks:");
11928                    printedHeader = true;
11929                    printedAnything = true;
11930                }
11931                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11932                        pw.println(tr);
11933                if (dumpAll) {
11934                    mRecentTasks.get(i).dump(pw, "    ");
11935                }
11936            }
11937        }
11938
11939        if (!printedAnything) {
11940            pw.println("  (nothing)");
11941        }
11942    }
11943
11944    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11945            int opti, boolean dumpAll, String dumpPackage) {
11946        boolean needSep = false;
11947        boolean printedAnything = false;
11948        int numPers = 0;
11949
11950        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11951
11952        if (dumpAll) {
11953            final int NP = mProcessNames.getMap().size();
11954            for (int ip=0; ip<NP; ip++) {
11955                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11956                final int NA = procs.size();
11957                for (int ia=0; ia<NA; ia++) {
11958                    ProcessRecord r = procs.valueAt(ia);
11959                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11960                        continue;
11961                    }
11962                    if (!needSep) {
11963                        pw.println("  All known processes:");
11964                        needSep = true;
11965                        printedAnything = true;
11966                    }
11967                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11968                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11969                        pw.print(" "); pw.println(r);
11970                    r.dump(pw, "    ");
11971                    if (r.persistent) {
11972                        numPers++;
11973                    }
11974                }
11975            }
11976        }
11977
11978        if (mIsolatedProcesses.size() > 0) {
11979            boolean printed = false;
11980            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11981                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11982                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11983                    continue;
11984                }
11985                if (!printed) {
11986                    if (needSep) {
11987                        pw.println();
11988                    }
11989                    pw.println("  Isolated process list (sorted by uid):");
11990                    printedAnything = true;
11991                    printed = true;
11992                    needSep = true;
11993                }
11994                pw.println(String.format("%sIsolated #%2d: %s",
11995                        "    ", i, r.toString()));
11996            }
11997        }
11998
11999        if (mLruProcesses.size() > 0) {
12000            if (needSep) {
12001                pw.println();
12002            }
12003            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12004                    pw.print(" total, non-act at ");
12005                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12006                    pw.print(", non-svc at ");
12007                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12008                    pw.println("):");
12009            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12010            needSep = true;
12011            printedAnything = true;
12012        }
12013
12014        if (dumpAll || dumpPackage != null) {
12015            synchronized (mPidsSelfLocked) {
12016                boolean printed = false;
12017                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12018                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12019                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12020                        continue;
12021                    }
12022                    if (!printed) {
12023                        if (needSep) pw.println();
12024                        needSep = true;
12025                        pw.println("  PID mappings:");
12026                        printed = true;
12027                        printedAnything = true;
12028                    }
12029                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12030                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12031                }
12032            }
12033        }
12034
12035        if (mForegroundProcesses.size() > 0) {
12036            synchronized (mPidsSelfLocked) {
12037                boolean printed = false;
12038                for (int i=0; i<mForegroundProcesses.size(); i++) {
12039                    ProcessRecord r = mPidsSelfLocked.get(
12040                            mForegroundProcesses.valueAt(i).pid);
12041                    if (dumpPackage != null && (r == null
12042                            || !r.pkgList.containsKey(dumpPackage))) {
12043                        continue;
12044                    }
12045                    if (!printed) {
12046                        if (needSep) pw.println();
12047                        needSep = true;
12048                        pw.println("  Foreground Processes:");
12049                        printed = true;
12050                        printedAnything = true;
12051                    }
12052                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12053                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12054                }
12055            }
12056        }
12057
12058        if (mPersistentStartingProcesses.size() > 0) {
12059            if (needSep) pw.println();
12060            needSep = true;
12061            printedAnything = true;
12062            pw.println("  Persisent processes that are starting:");
12063            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12064                    "Starting Norm", "Restarting PERS", dumpPackage);
12065        }
12066
12067        if (mRemovedProcesses.size() > 0) {
12068            if (needSep) pw.println();
12069            needSep = true;
12070            printedAnything = true;
12071            pw.println("  Processes that are being removed:");
12072            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12073                    "Removed Norm", "Removed PERS", dumpPackage);
12074        }
12075
12076        if (mProcessesOnHold.size() > 0) {
12077            if (needSep) pw.println();
12078            needSep = true;
12079            printedAnything = true;
12080            pw.println("  Processes that are on old until the system is ready:");
12081            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12082                    "OnHold Norm", "OnHold PERS", dumpPackage);
12083        }
12084
12085        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12086
12087        if (mProcessCrashTimes.getMap().size() > 0) {
12088            boolean printed = false;
12089            long now = SystemClock.uptimeMillis();
12090            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12091            final int NP = pmap.size();
12092            for (int ip=0; ip<NP; ip++) {
12093                String pname = pmap.keyAt(ip);
12094                SparseArray<Long> uids = pmap.valueAt(ip);
12095                final int N = uids.size();
12096                for (int i=0; i<N; i++) {
12097                    int puid = uids.keyAt(i);
12098                    ProcessRecord r = mProcessNames.get(pname, puid);
12099                    if (dumpPackage != null && (r == null
12100                            || !r.pkgList.containsKey(dumpPackage))) {
12101                        continue;
12102                    }
12103                    if (!printed) {
12104                        if (needSep) pw.println();
12105                        needSep = true;
12106                        pw.println("  Time since processes crashed:");
12107                        printed = true;
12108                        printedAnything = true;
12109                    }
12110                    pw.print("    Process "); pw.print(pname);
12111                            pw.print(" uid "); pw.print(puid);
12112                            pw.print(": last crashed ");
12113                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12114                            pw.println(" ago");
12115                }
12116            }
12117        }
12118
12119        if (mBadProcesses.getMap().size() > 0) {
12120            boolean printed = false;
12121            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12122            final int NP = pmap.size();
12123            for (int ip=0; ip<NP; ip++) {
12124                String pname = pmap.keyAt(ip);
12125                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12126                final int N = uids.size();
12127                for (int i=0; i<N; i++) {
12128                    int puid = uids.keyAt(i);
12129                    ProcessRecord r = mProcessNames.get(pname, puid);
12130                    if (dumpPackage != null && (r == null
12131                            || !r.pkgList.containsKey(dumpPackage))) {
12132                        continue;
12133                    }
12134                    if (!printed) {
12135                        if (needSep) pw.println();
12136                        needSep = true;
12137                        pw.println("  Bad processes:");
12138                        printedAnything = true;
12139                    }
12140                    BadProcessInfo info = uids.valueAt(i);
12141                    pw.print("    Bad process "); pw.print(pname);
12142                            pw.print(" uid "); pw.print(puid);
12143                            pw.print(": crashed at time "); pw.println(info.time);
12144                    if (info.shortMsg != null) {
12145                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12146                    }
12147                    if (info.longMsg != null) {
12148                        pw.print("      Long msg: "); pw.println(info.longMsg);
12149                    }
12150                    if (info.stack != null) {
12151                        pw.println("      Stack:");
12152                        int lastPos = 0;
12153                        for (int pos=0; pos<info.stack.length(); pos++) {
12154                            if (info.stack.charAt(pos) == '\n') {
12155                                pw.print("        ");
12156                                pw.write(info.stack, lastPos, pos-lastPos);
12157                                pw.println();
12158                                lastPos = pos+1;
12159                            }
12160                        }
12161                        if (lastPos < info.stack.length()) {
12162                            pw.print("        ");
12163                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12164                            pw.println();
12165                        }
12166                    }
12167                }
12168            }
12169        }
12170
12171        if (dumpPackage == null) {
12172            pw.println();
12173            needSep = false;
12174            pw.println("  mStartedUsers:");
12175            for (int i=0; i<mStartedUsers.size(); i++) {
12176                UserStartedState uss = mStartedUsers.valueAt(i);
12177                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12178                        pw.print(": "); uss.dump("", pw);
12179            }
12180            pw.print("  mStartedUserArray: [");
12181            for (int i=0; i<mStartedUserArray.length; i++) {
12182                if (i > 0) pw.print(", ");
12183                pw.print(mStartedUserArray[i]);
12184            }
12185            pw.println("]");
12186            pw.print("  mUserLru: [");
12187            for (int i=0; i<mUserLru.size(); i++) {
12188                if (i > 0) pw.print(", ");
12189                pw.print(mUserLru.get(i));
12190            }
12191            pw.println("]");
12192            if (dumpAll) {
12193                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12194            }
12195            synchronized (mUserProfileGroupIdsSelfLocked) {
12196                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12197                    pw.println("  mUserProfileGroupIds:");
12198                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12199                        pw.print("    User #");
12200                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12201                        pw.print(" -> profile #");
12202                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12203                    }
12204                }
12205            }
12206        }
12207        if (mHomeProcess != null && (dumpPackage == null
12208                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12209            if (needSep) {
12210                pw.println();
12211                needSep = false;
12212            }
12213            pw.println("  mHomeProcess: " + mHomeProcess);
12214        }
12215        if (mPreviousProcess != null && (dumpPackage == null
12216                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12217            if (needSep) {
12218                pw.println();
12219                needSep = false;
12220            }
12221            pw.println("  mPreviousProcess: " + mPreviousProcess);
12222        }
12223        if (dumpAll) {
12224            StringBuilder sb = new StringBuilder(128);
12225            sb.append("  mPreviousProcessVisibleTime: ");
12226            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12227            pw.println(sb);
12228        }
12229        if (mHeavyWeightProcess != null && (dumpPackage == null
12230                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12231            if (needSep) {
12232                pw.println();
12233                needSep = false;
12234            }
12235            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12236        }
12237        if (dumpPackage == null) {
12238            pw.println("  mConfiguration: " + mConfiguration);
12239        }
12240        if (dumpAll) {
12241            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12242            if (mCompatModePackages.getPackages().size() > 0) {
12243                boolean printed = false;
12244                for (Map.Entry<String, Integer> entry
12245                        : mCompatModePackages.getPackages().entrySet()) {
12246                    String pkg = entry.getKey();
12247                    int mode = entry.getValue();
12248                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12249                        continue;
12250                    }
12251                    if (!printed) {
12252                        pw.println("  mScreenCompatPackages:");
12253                        printed = true;
12254                    }
12255                    pw.print("    "); pw.print(pkg); pw.print(": ");
12256                            pw.print(mode); pw.println();
12257                }
12258            }
12259        }
12260        if (dumpPackage == null) {
12261            if (mSleeping || mWentToSleep || mLockScreenShown) {
12262                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12263                        + " mLockScreenShown " + mLockScreenShown);
12264            }
12265            if (mShuttingDown || mRunningVoice) {
12266                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12267            }
12268        }
12269        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12270                || mOrigWaitForDebugger) {
12271            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12272                    || dumpPackage.equals(mOrigDebugApp)) {
12273                if (needSep) {
12274                    pw.println();
12275                    needSep = false;
12276                }
12277                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12278                        + " mDebugTransient=" + mDebugTransient
12279                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12280            }
12281        }
12282        if (mOpenGlTraceApp != null) {
12283            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12284                if (needSep) {
12285                    pw.println();
12286                    needSep = false;
12287                }
12288                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12289            }
12290        }
12291        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12292                || mProfileFd != null) {
12293            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12294                if (needSep) {
12295                    pw.println();
12296                    needSep = false;
12297                }
12298                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12299                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12300                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12301                        + mAutoStopProfiler);
12302            }
12303        }
12304        if (dumpPackage == null) {
12305            if (mAlwaysFinishActivities || mController != null) {
12306                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12307                        + " mController=" + mController);
12308            }
12309            if (dumpAll) {
12310                pw.println("  Total persistent processes: " + numPers);
12311                pw.println("  mProcessesReady=" + mProcessesReady
12312                        + " mSystemReady=" + mSystemReady);
12313                pw.println("  mBooting=" + mBooting
12314                        + " mBooted=" + mBooted
12315                        + " mFactoryTest=" + mFactoryTest);
12316                pw.print("  mLastPowerCheckRealtime=");
12317                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12318                        pw.println("");
12319                pw.print("  mLastPowerCheckUptime=");
12320                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12321                        pw.println("");
12322                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12323                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12324                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12325                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12326                        + " (" + mLruProcesses.size() + " total)"
12327                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12328                        + " mNumServiceProcs=" + mNumServiceProcs
12329                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12330                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12331                        + " mLastMemoryLevel" + mLastMemoryLevel
12332                        + " mLastNumProcesses" + mLastNumProcesses);
12333                long now = SystemClock.uptimeMillis();
12334                pw.print("  mLastIdleTime=");
12335                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12336                        pw.print(" mLowRamSinceLastIdle=");
12337                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12338                        pw.println();
12339            }
12340        }
12341
12342        if (!printedAnything) {
12343            pw.println("  (nothing)");
12344        }
12345    }
12346
12347    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12348            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12349        if (mProcessesToGc.size() > 0) {
12350            boolean printed = false;
12351            long now = SystemClock.uptimeMillis();
12352            for (int i=0; i<mProcessesToGc.size(); i++) {
12353                ProcessRecord proc = mProcessesToGc.get(i);
12354                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12355                    continue;
12356                }
12357                if (!printed) {
12358                    if (needSep) pw.println();
12359                    needSep = true;
12360                    pw.println("  Processes that are waiting to GC:");
12361                    printed = true;
12362                }
12363                pw.print("    Process "); pw.println(proc);
12364                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12365                        pw.print(", last gced=");
12366                        pw.print(now-proc.lastRequestedGc);
12367                        pw.print(" ms ago, last lowMem=");
12368                        pw.print(now-proc.lastLowMemory);
12369                        pw.println(" ms ago");
12370
12371            }
12372        }
12373        return needSep;
12374    }
12375
12376    void printOomLevel(PrintWriter pw, String name, int adj) {
12377        pw.print("    ");
12378        if (adj >= 0) {
12379            pw.print(' ');
12380            if (adj < 10) pw.print(' ');
12381        } else {
12382            if (adj > -10) pw.print(' ');
12383        }
12384        pw.print(adj);
12385        pw.print(": ");
12386        pw.print(name);
12387        pw.print(" (");
12388        pw.print(mProcessList.getMemLevel(adj)/1024);
12389        pw.println(" kB)");
12390    }
12391
12392    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12393            int opti, boolean dumpAll) {
12394        boolean needSep = false;
12395
12396        if (mLruProcesses.size() > 0) {
12397            if (needSep) pw.println();
12398            needSep = true;
12399            pw.println("  OOM levels:");
12400            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12401            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12402            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12403            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12404            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12405            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12406            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12407            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12408            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12409            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12410            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12411            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12412            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12413
12414            if (needSep) pw.println();
12415            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12416                    pw.print(" total, non-act at ");
12417                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12418                    pw.print(", non-svc at ");
12419                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12420                    pw.println("):");
12421            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12422            needSep = true;
12423        }
12424
12425        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12426
12427        pw.println();
12428        pw.println("  mHomeProcess: " + mHomeProcess);
12429        pw.println("  mPreviousProcess: " + mPreviousProcess);
12430        if (mHeavyWeightProcess != null) {
12431            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12432        }
12433
12434        return true;
12435    }
12436
12437    /**
12438     * There are three ways to call this:
12439     *  - no provider specified: dump all the providers
12440     *  - a flattened component name that matched an existing provider was specified as the
12441     *    first arg: dump that one provider
12442     *  - the first arg isn't the flattened component name of an existing provider:
12443     *    dump all providers whose component contains the first arg as a substring
12444     */
12445    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12446            int opti, boolean dumpAll) {
12447        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12448    }
12449
12450    static class ItemMatcher {
12451        ArrayList<ComponentName> components;
12452        ArrayList<String> strings;
12453        ArrayList<Integer> objects;
12454        boolean all;
12455
12456        ItemMatcher() {
12457            all = true;
12458        }
12459
12460        void build(String name) {
12461            ComponentName componentName = ComponentName.unflattenFromString(name);
12462            if (componentName != null) {
12463                if (components == null) {
12464                    components = new ArrayList<ComponentName>();
12465                }
12466                components.add(componentName);
12467                all = false;
12468            } else {
12469                int objectId = 0;
12470                // Not a '/' separated full component name; maybe an object ID?
12471                try {
12472                    objectId = Integer.parseInt(name, 16);
12473                    if (objects == null) {
12474                        objects = new ArrayList<Integer>();
12475                    }
12476                    objects.add(objectId);
12477                    all = false;
12478                } catch (RuntimeException e) {
12479                    // Not an integer; just do string match.
12480                    if (strings == null) {
12481                        strings = new ArrayList<String>();
12482                    }
12483                    strings.add(name);
12484                    all = false;
12485                }
12486            }
12487        }
12488
12489        int build(String[] args, int opti) {
12490            for (; opti<args.length; opti++) {
12491                String name = args[opti];
12492                if ("--".equals(name)) {
12493                    return opti+1;
12494                }
12495                build(name);
12496            }
12497            return opti;
12498        }
12499
12500        boolean match(Object object, ComponentName comp) {
12501            if (all) {
12502                return true;
12503            }
12504            if (components != null) {
12505                for (int i=0; i<components.size(); i++) {
12506                    if (components.get(i).equals(comp)) {
12507                        return true;
12508                    }
12509                }
12510            }
12511            if (objects != null) {
12512                for (int i=0; i<objects.size(); i++) {
12513                    if (System.identityHashCode(object) == objects.get(i)) {
12514                        return true;
12515                    }
12516                }
12517            }
12518            if (strings != null) {
12519                String flat = comp.flattenToString();
12520                for (int i=0; i<strings.size(); i++) {
12521                    if (flat.contains(strings.get(i))) {
12522                        return true;
12523                    }
12524                }
12525            }
12526            return false;
12527        }
12528    }
12529
12530    /**
12531     * There are three things that cmd can be:
12532     *  - a flattened component name that matches an existing activity
12533     *  - the cmd arg isn't the flattened component name of an existing activity:
12534     *    dump all activity whose component contains the cmd as a substring
12535     *  - A hex number of the ActivityRecord object instance.
12536     */
12537    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12538            int opti, boolean dumpAll) {
12539        ArrayList<ActivityRecord> activities;
12540
12541        synchronized (this) {
12542            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12543        }
12544
12545        if (activities.size() <= 0) {
12546            return false;
12547        }
12548
12549        String[] newArgs = new String[args.length - opti];
12550        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12551
12552        TaskRecord lastTask = null;
12553        boolean needSep = false;
12554        for (int i=activities.size()-1; i>=0; i--) {
12555            ActivityRecord r = activities.get(i);
12556            if (needSep) {
12557                pw.println();
12558            }
12559            needSep = true;
12560            synchronized (this) {
12561                if (lastTask != r.task) {
12562                    lastTask = r.task;
12563                    pw.print("TASK "); pw.print(lastTask.affinity);
12564                            pw.print(" id="); pw.println(lastTask.taskId);
12565                    if (dumpAll) {
12566                        lastTask.dump(pw, "  ");
12567                    }
12568                }
12569            }
12570            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12571        }
12572        return true;
12573    }
12574
12575    /**
12576     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12577     * there is a thread associated with the activity.
12578     */
12579    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12580            final ActivityRecord r, String[] args, boolean dumpAll) {
12581        String innerPrefix = prefix + "  ";
12582        synchronized (this) {
12583            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12584                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12585                    pw.print(" pid=");
12586                    if (r.app != null) pw.println(r.app.pid);
12587                    else pw.println("(not running)");
12588            if (dumpAll) {
12589                r.dump(pw, innerPrefix);
12590            }
12591        }
12592        if (r.app != null && r.app.thread != null) {
12593            // flush anything that is already in the PrintWriter since the thread is going
12594            // to write to the file descriptor directly
12595            pw.flush();
12596            try {
12597                TransferPipe tp = new TransferPipe();
12598                try {
12599                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12600                            r.appToken, innerPrefix, args);
12601                    tp.go(fd);
12602                } finally {
12603                    tp.kill();
12604                }
12605            } catch (IOException e) {
12606                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12607            } catch (RemoteException e) {
12608                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12609            }
12610        }
12611    }
12612
12613    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12614            int opti, boolean dumpAll, String dumpPackage) {
12615        boolean needSep = false;
12616        boolean onlyHistory = false;
12617        boolean printedAnything = false;
12618
12619        if ("history".equals(dumpPackage)) {
12620            if (opti < args.length && "-s".equals(args[opti])) {
12621                dumpAll = false;
12622            }
12623            onlyHistory = true;
12624            dumpPackage = null;
12625        }
12626
12627        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12628        if (!onlyHistory && dumpAll) {
12629            if (mRegisteredReceivers.size() > 0) {
12630                boolean printed = false;
12631                Iterator it = mRegisteredReceivers.values().iterator();
12632                while (it.hasNext()) {
12633                    ReceiverList r = (ReceiverList)it.next();
12634                    if (dumpPackage != null && (r.app == null ||
12635                            !dumpPackage.equals(r.app.info.packageName))) {
12636                        continue;
12637                    }
12638                    if (!printed) {
12639                        pw.println("  Registered Receivers:");
12640                        needSep = true;
12641                        printed = true;
12642                        printedAnything = true;
12643                    }
12644                    pw.print("  * "); pw.println(r);
12645                    r.dump(pw, "    ");
12646                }
12647            }
12648
12649            if (mReceiverResolver.dump(pw, needSep ?
12650                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12651                    "    ", dumpPackage, false)) {
12652                needSep = true;
12653                printedAnything = true;
12654            }
12655        }
12656
12657        for (BroadcastQueue q : mBroadcastQueues) {
12658            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12659            printedAnything |= needSep;
12660        }
12661
12662        needSep = true;
12663
12664        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12665            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12666                if (needSep) {
12667                    pw.println();
12668                }
12669                needSep = true;
12670                printedAnything = true;
12671                pw.print("  Sticky broadcasts for user ");
12672                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12673                StringBuilder sb = new StringBuilder(128);
12674                for (Map.Entry<String, ArrayList<Intent>> ent
12675                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12676                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12677                    if (dumpAll) {
12678                        pw.println(":");
12679                        ArrayList<Intent> intents = ent.getValue();
12680                        final int N = intents.size();
12681                        for (int i=0; i<N; i++) {
12682                            sb.setLength(0);
12683                            sb.append("    Intent: ");
12684                            intents.get(i).toShortString(sb, false, true, false, false);
12685                            pw.println(sb.toString());
12686                            Bundle bundle = intents.get(i).getExtras();
12687                            if (bundle != null) {
12688                                pw.print("      ");
12689                                pw.println(bundle.toString());
12690                            }
12691                        }
12692                    } else {
12693                        pw.println("");
12694                    }
12695                }
12696            }
12697        }
12698
12699        if (!onlyHistory && dumpAll) {
12700            pw.println();
12701            for (BroadcastQueue queue : mBroadcastQueues) {
12702                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12703                        + queue.mBroadcastsScheduled);
12704            }
12705            pw.println("  mHandler:");
12706            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12707            needSep = true;
12708            printedAnything = true;
12709        }
12710
12711        if (!printedAnything) {
12712            pw.println("  (nothing)");
12713        }
12714    }
12715
12716    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12717            int opti, boolean dumpAll, String dumpPackage) {
12718        boolean needSep;
12719        boolean printedAnything = false;
12720
12721        ItemMatcher matcher = new ItemMatcher();
12722        matcher.build(args, opti);
12723
12724        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12725
12726        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12727        printedAnything |= needSep;
12728
12729        if (mLaunchingProviders.size() > 0) {
12730            boolean printed = false;
12731            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12732                ContentProviderRecord r = mLaunchingProviders.get(i);
12733                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12734                    continue;
12735                }
12736                if (!printed) {
12737                    if (needSep) pw.println();
12738                    needSep = true;
12739                    pw.println("  Launching content providers:");
12740                    printed = true;
12741                    printedAnything = true;
12742                }
12743                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12744                        pw.println(r);
12745            }
12746        }
12747
12748        if (mGrantedUriPermissions.size() > 0) {
12749            boolean printed = false;
12750            int dumpUid = -2;
12751            if (dumpPackage != null) {
12752                try {
12753                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12754                } catch (NameNotFoundException e) {
12755                    dumpUid = -1;
12756                }
12757            }
12758            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12759                int uid = mGrantedUriPermissions.keyAt(i);
12760                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12761                    continue;
12762                }
12763                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12764                if (!printed) {
12765                    if (needSep) pw.println();
12766                    needSep = true;
12767                    pw.println("  Granted Uri Permissions:");
12768                    printed = true;
12769                    printedAnything = true;
12770                }
12771                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12772                for (UriPermission perm : perms.values()) {
12773                    pw.print("    "); pw.println(perm);
12774                    if (dumpAll) {
12775                        perm.dump(pw, "      ");
12776                    }
12777                }
12778            }
12779        }
12780
12781        if (!printedAnything) {
12782            pw.println("  (nothing)");
12783        }
12784    }
12785
12786    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12787            int opti, boolean dumpAll, String dumpPackage) {
12788        boolean printed = false;
12789
12790        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12791
12792        if (mIntentSenderRecords.size() > 0) {
12793            Iterator<WeakReference<PendingIntentRecord>> it
12794                    = mIntentSenderRecords.values().iterator();
12795            while (it.hasNext()) {
12796                WeakReference<PendingIntentRecord> ref = it.next();
12797                PendingIntentRecord rec = ref != null ? ref.get(): null;
12798                if (dumpPackage != null && (rec == null
12799                        || !dumpPackage.equals(rec.key.packageName))) {
12800                    continue;
12801                }
12802                printed = true;
12803                if (rec != null) {
12804                    pw.print("  * "); pw.println(rec);
12805                    if (dumpAll) {
12806                        rec.dump(pw, "    ");
12807                    }
12808                } else {
12809                    pw.print("  * "); pw.println(ref);
12810                }
12811            }
12812        }
12813
12814        if (!printed) {
12815            pw.println("  (nothing)");
12816        }
12817    }
12818
12819    private static final int dumpProcessList(PrintWriter pw,
12820            ActivityManagerService service, List list,
12821            String prefix, String normalLabel, String persistentLabel,
12822            String dumpPackage) {
12823        int numPers = 0;
12824        final int N = list.size()-1;
12825        for (int i=N; i>=0; i--) {
12826            ProcessRecord r = (ProcessRecord)list.get(i);
12827            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12828                continue;
12829            }
12830            pw.println(String.format("%s%s #%2d: %s",
12831                    prefix, (r.persistent ? persistentLabel : normalLabel),
12832                    i, r.toString()));
12833            if (r.persistent) {
12834                numPers++;
12835            }
12836        }
12837        return numPers;
12838    }
12839
12840    private static final boolean dumpProcessOomList(PrintWriter pw,
12841            ActivityManagerService service, List<ProcessRecord> origList,
12842            String prefix, String normalLabel, String persistentLabel,
12843            boolean inclDetails, String dumpPackage) {
12844
12845        ArrayList<Pair<ProcessRecord, Integer>> list
12846                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12847        for (int i=0; i<origList.size(); i++) {
12848            ProcessRecord r = origList.get(i);
12849            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12850                continue;
12851            }
12852            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12853        }
12854
12855        if (list.size() <= 0) {
12856            return false;
12857        }
12858
12859        Comparator<Pair<ProcessRecord, Integer>> comparator
12860                = new Comparator<Pair<ProcessRecord, Integer>>() {
12861            @Override
12862            public int compare(Pair<ProcessRecord, Integer> object1,
12863                    Pair<ProcessRecord, Integer> object2) {
12864                if (object1.first.setAdj != object2.first.setAdj) {
12865                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12866                }
12867                if (object1.second.intValue() != object2.second.intValue()) {
12868                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12869                }
12870                return 0;
12871            }
12872        };
12873
12874        Collections.sort(list, comparator);
12875
12876        final long curRealtime = SystemClock.elapsedRealtime();
12877        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12878        final long curUptime = SystemClock.uptimeMillis();
12879        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12880
12881        for (int i=list.size()-1; i>=0; i--) {
12882            ProcessRecord r = list.get(i).first;
12883            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12884            char schedGroup;
12885            switch (r.setSchedGroup) {
12886                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12887                    schedGroup = 'B';
12888                    break;
12889                case Process.THREAD_GROUP_DEFAULT:
12890                    schedGroup = 'F';
12891                    break;
12892                default:
12893                    schedGroup = '?';
12894                    break;
12895            }
12896            char foreground;
12897            if (r.foregroundActivities) {
12898                foreground = 'A';
12899            } else if (r.foregroundServices) {
12900                foreground = 'S';
12901            } else {
12902                foreground = ' ';
12903            }
12904            String procState = ProcessList.makeProcStateString(r.curProcState);
12905            pw.print(prefix);
12906            pw.print(r.persistent ? persistentLabel : normalLabel);
12907            pw.print(" #");
12908            int num = (origList.size()-1)-list.get(i).second;
12909            if (num < 10) pw.print(' ');
12910            pw.print(num);
12911            pw.print(": ");
12912            pw.print(oomAdj);
12913            pw.print(' ');
12914            pw.print(schedGroup);
12915            pw.print('/');
12916            pw.print(foreground);
12917            pw.print('/');
12918            pw.print(procState);
12919            pw.print(" trm:");
12920            if (r.trimMemoryLevel < 10) pw.print(' ');
12921            pw.print(r.trimMemoryLevel);
12922            pw.print(' ');
12923            pw.print(r.toShortString());
12924            pw.print(" (");
12925            pw.print(r.adjType);
12926            pw.println(')');
12927            if (r.adjSource != null || r.adjTarget != null) {
12928                pw.print(prefix);
12929                pw.print("    ");
12930                if (r.adjTarget instanceof ComponentName) {
12931                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12932                } else if (r.adjTarget != null) {
12933                    pw.print(r.adjTarget.toString());
12934                } else {
12935                    pw.print("{null}");
12936                }
12937                pw.print("<=");
12938                if (r.adjSource instanceof ProcessRecord) {
12939                    pw.print("Proc{");
12940                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12941                    pw.println("}");
12942                } else if (r.adjSource != null) {
12943                    pw.println(r.adjSource.toString());
12944                } else {
12945                    pw.println("{null}");
12946                }
12947            }
12948            if (inclDetails) {
12949                pw.print(prefix);
12950                pw.print("    ");
12951                pw.print("oom: max="); pw.print(r.maxAdj);
12952                pw.print(" curRaw="); pw.print(r.curRawAdj);
12953                pw.print(" setRaw="); pw.print(r.setRawAdj);
12954                pw.print(" cur="); pw.print(r.curAdj);
12955                pw.print(" set="); pw.println(r.setAdj);
12956                pw.print(prefix);
12957                pw.print("    ");
12958                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12959                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12960                pw.print(" lastPss="); pw.print(r.lastPss);
12961                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12962                pw.print(prefix);
12963                pw.print("    ");
12964                pw.print("cached="); pw.print(r.cached);
12965                pw.print(" empty="); pw.print(r.empty);
12966                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12967
12968                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12969                    if (r.lastWakeTime != 0) {
12970                        long wtime;
12971                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12972                        synchronized (stats) {
12973                            wtime = stats.getProcessWakeTime(r.info.uid,
12974                                    r.pid, curRealtime);
12975                        }
12976                        long timeUsed = wtime - r.lastWakeTime;
12977                        pw.print(prefix);
12978                        pw.print("    ");
12979                        pw.print("keep awake over ");
12980                        TimeUtils.formatDuration(realtimeSince, pw);
12981                        pw.print(" used ");
12982                        TimeUtils.formatDuration(timeUsed, pw);
12983                        pw.print(" (");
12984                        pw.print((timeUsed*100)/realtimeSince);
12985                        pw.println("%)");
12986                    }
12987                    if (r.lastCpuTime != 0) {
12988                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12989                        pw.print(prefix);
12990                        pw.print("    ");
12991                        pw.print("run cpu over ");
12992                        TimeUtils.formatDuration(uptimeSince, pw);
12993                        pw.print(" used ");
12994                        TimeUtils.formatDuration(timeUsed, pw);
12995                        pw.print(" (");
12996                        pw.print((timeUsed*100)/uptimeSince);
12997                        pw.println("%)");
12998                    }
12999                }
13000            }
13001        }
13002        return true;
13003    }
13004
13005    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13006        ArrayList<ProcessRecord> procs;
13007        synchronized (this) {
13008            if (args != null && args.length > start
13009                    && args[start].charAt(0) != '-') {
13010                procs = new ArrayList<ProcessRecord>();
13011                int pid = -1;
13012                try {
13013                    pid = Integer.parseInt(args[start]);
13014                } catch (NumberFormatException e) {
13015                }
13016                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13017                    ProcessRecord proc = mLruProcesses.get(i);
13018                    if (proc.pid == pid) {
13019                        procs.add(proc);
13020                    } else if (proc.processName.equals(args[start])) {
13021                        procs.add(proc);
13022                    }
13023                }
13024                if (procs.size() <= 0) {
13025                    return null;
13026                }
13027            } else {
13028                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13029            }
13030        }
13031        return procs;
13032    }
13033
13034    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13035            PrintWriter pw, String[] args) {
13036        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13037        if (procs == null) {
13038            pw.println("No process found for: " + args[0]);
13039            return;
13040        }
13041
13042        long uptime = SystemClock.uptimeMillis();
13043        long realtime = SystemClock.elapsedRealtime();
13044        pw.println("Applications Graphics Acceleration Info:");
13045        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13046
13047        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13048            ProcessRecord r = procs.get(i);
13049            if (r.thread != null) {
13050                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13051                pw.flush();
13052                try {
13053                    TransferPipe tp = new TransferPipe();
13054                    try {
13055                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13056                        tp.go(fd);
13057                    } finally {
13058                        tp.kill();
13059                    }
13060                } catch (IOException e) {
13061                    pw.println("Failure while dumping the app: " + r);
13062                    pw.flush();
13063                } catch (RemoteException e) {
13064                    pw.println("Got a RemoteException while dumping the app " + r);
13065                    pw.flush();
13066                }
13067            }
13068        }
13069    }
13070
13071    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13072        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13073        if (procs == null) {
13074            pw.println("No process found for: " + args[0]);
13075            return;
13076        }
13077
13078        pw.println("Applications Database Info:");
13079
13080        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13081            ProcessRecord r = procs.get(i);
13082            if (r.thread != null) {
13083                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13084                pw.flush();
13085                try {
13086                    TransferPipe tp = new TransferPipe();
13087                    try {
13088                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13089                        tp.go(fd);
13090                    } finally {
13091                        tp.kill();
13092                    }
13093                } catch (IOException e) {
13094                    pw.println("Failure while dumping the app: " + r);
13095                    pw.flush();
13096                } catch (RemoteException e) {
13097                    pw.println("Got a RemoteException while dumping the app " + r);
13098                    pw.flush();
13099                }
13100            }
13101        }
13102    }
13103
13104    final static class MemItem {
13105        final boolean isProc;
13106        final String label;
13107        final String shortLabel;
13108        final long pss;
13109        final int id;
13110        final boolean hasActivities;
13111        ArrayList<MemItem> subitems;
13112
13113        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13114                boolean _hasActivities) {
13115            isProc = true;
13116            label = _label;
13117            shortLabel = _shortLabel;
13118            pss = _pss;
13119            id = _id;
13120            hasActivities = _hasActivities;
13121        }
13122
13123        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13124            isProc = false;
13125            label = _label;
13126            shortLabel = _shortLabel;
13127            pss = _pss;
13128            id = _id;
13129            hasActivities = false;
13130        }
13131    }
13132
13133    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13134            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13135        if (sort && !isCompact) {
13136            Collections.sort(items, new Comparator<MemItem>() {
13137                @Override
13138                public int compare(MemItem lhs, MemItem rhs) {
13139                    if (lhs.pss < rhs.pss) {
13140                        return 1;
13141                    } else if (lhs.pss > rhs.pss) {
13142                        return -1;
13143                    }
13144                    return 0;
13145                }
13146            });
13147        }
13148
13149        for (int i=0; i<items.size(); i++) {
13150            MemItem mi = items.get(i);
13151            if (!isCompact) {
13152                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13153            } else if (mi.isProc) {
13154                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13155                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13156                pw.println(mi.hasActivities ? ",a" : ",e");
13157            } else {
13158                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13159                pw.println(mi.pss);
13160            }
13161            if (mi.subitems != null) {
13162                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13163                        true, isCompact);
13164            }
13165        }
13166    }
13167
13168    // These are in KB.
13169    static final long[] DUMP_MEM_BUCKETS = new long[] {
13170        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13171        120*1024, 160*1024, 200*1024,
13172        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13173        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13174    };
13175
13176    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13177            boolean stackLike) {
13178        int start = label.lastIndexOf('.');
13179        if (start >= 0) start++;
13180        else start = 0;
13181        int end = label.length();
13182        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13183            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13184                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13185                out.append(bucket);
13186                out.append(stackLike ? "MB." : "MB ");
13187                out.append(label, start, end);
13188                return;
13189            }
13190        }
13191        out.append(memKB/1024);
13192        out.append(stackLike ? "MB." : "MB ");
13193        out.append(label, start, end);
13194    }
13195
13196    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13197            ProcessList.NATIVE_ADJ,
13198            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13199            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13200            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13201            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13202            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13203    };
13204    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13205            "Native",
13206            "System", "Persistent", "Foreground",
13207            "Visible", "Perceptible",
13208            "Heavy Weight", "Backup",
13209            "A Services", "Home",
13210            "Previous", "B Services", "Cached"
13211    };
13212    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13213            "native",
13214            "sys", "pers", "fore",
13215            "vis", "percept",
13216            "heavy", "backup",
13217            "servicea", "home",
13218            "prev", "serviceb", "cached"
13219    };
13220
13221    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13222            long realtime, boolean isCheckinRequest, boolean isCompact) {
13223        if (isCheckinRequest || isCompact) {
13224            // short checkin version
13225            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13226        } else {
13227            pw.println("Applications Memory Usage (kB):");
13228            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13229        }
13230    }
13231
13232    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13233            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13234        boolean dumpDetails = false;
13235        boolean dumpFullDetails = false;
13236        boolean dumpDalvik = false;
13237        boolean oomOnly = false;
13238        boolean isCompact = false;
13239        boolean localOnly = false;
13240
13241        int opti = 0;
13242        while (opti < args.length) {
13243            String opt = args[opti];
13244            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13245                break;
13246            }
13247            opti++;
13248            if ("-a".equals(opt)) {
13249                dumpDetails = true;
13250                dumpFullDetails = true;
13251                dumpDalvik = true;
13252            } else if ("-d".equals(opt)) {
13253                dumpDalvik = true;
13254            } else if ("-c".equals(opt)) {
13255                isCompact = true;
13256            } else if ("--oom".equals(opt)) {
13257                oomOnly = true;
13258            } else if ("--local".equals(opt)) {
13259                localOnly = true;
13260            } else if ("-h".equals(opt)) {
13261                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13262                pw.println("  -a: include all available information for each process.");
13263                pw.println("  -d: include dalvik details when dumping process details.");
13264                pw.println("  -c: dump in a compact machine-parseable representation.");
13265                pw.println("  --oom: only show processes organized by oom adj.");
13266                pw.println("  --local: only collect details locally, don't call process.");
13267                pw.println("If [process] is specified it can be the name or ");
13268                pw.println("pid of a specific process to dump.");
13269                return;
13270            } else {
13271                pw.println("Unknown argument: " + opt + "; use -h for help");
13272            }
13273        }
13274
13275        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13276        long uptime = SystemClock.uptimeMillis();
13277        long realtime = SystemClock.elapsedRealtime();
13278        final long[] tmpLong = new long[1];
13279
13280        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13281        if (procs == null) {
13282            // No Java processes.  Maybe they want to print a native process.
13283            if (args != null && args.length > opti
13284                    && args[opti].charAt(0) != '-') {
13285                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13286                        = new ArrayList<ProcessCpuTracker.Stats>();
13287                updateCpuStatsNow();
13288                int findPid = -1;
13289                try {
13290                    findPid = Integer.parseInt(args[opti]);
13291                } catch (NumberFormatException e) {
13292                }
13293                synchronized (mProcessCpuThread) {
13294                    final int N = mProcessCpuTracker.countStats();
13295                    for (int i=0; i<N; i++) {
13296                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13297                        if (st.pid == findPid || (st.baseName != null
13298                                && st.baseName.equals(args[opti]))) {
13299                            nativeProcs.add(st);
13300                        }
13301                    }
13302                }
13303                if (nativeProcs.size() > 0) {
13304                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13305                            isCompact);
13306                    Debug.MemoryInfo mi = null;
13307                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13308                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13309                        final int pid = r.pid;
13310                        if (!isCheckinRequest && dumpDetails) {
13311                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13312                        }
13313                        if (mi == null) {
13314                            mi = new Debug.MemoryInfo();
13315                        }
13316                        if (dumpDetails || (!brief && !oomOnly)) {
13317                            Debug.getMemoryInfo(pid, mi);
13318                        } else {
13319                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13320                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13321                        }
13322                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13323                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13324                        if (isCheckinRequest) {
13325                            pw.println();
13326                        }
13327                    }
13328                    return;
13329                }
13330            }
13331            pw.println("No process found for: " + args[opti]);
13332            return;
13333        }
13334
13335        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13336            dumpDetails = true;
13337        }
13338
13339        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13340
13341        String[] innerArgs = new String[args.length-opti];
13342        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13343
13344        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13345        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13346        long nativePss=0, dalvikPss=0, otherPss=0;
13347        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13348
13349        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13350        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13351                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13352
13353        long totalPss = 0;
13354        long cachedPss = 0;
13355
13356        Debug.MemoryInfo mi = null;
13357        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13358            final ProcessRecord r = procs.get(i);
13359            final IApplicationThread thread;
13360            final int pid;
13361            final int oomAdj;
13362            final boolean hasActivities;
13363            synchronized (this) {
13364                thread = r.thread;
13365                pid = r.pid;
13366                oomAdj = r.getSetAdjWithServices();
13367                hasActivities = r.activities.size() > 0;
13368            }
13369            if (thread != null) {
13370                if (!isCheckinRequest && dumpDetails) {
13371                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13372                }
13373                if (mi == null) {
13374                    mi = new Debug.MemoryInfo();
13375                }
13376                if (dumpDetails || (!brief && !oomOnly)) {
13377                    Debug.getMemoryInfo(pid, mi);
13378                } else {
13379                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13380                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13381                }
13382                if (dumpDetails) {
13383                    if (localOnly) {
13384                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13385                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13386                        if (isCheckinRequest) {
13387                            pw.println();
13388                        }
13389                    } else {
13390                        try {
13391                            pw.flush();
13392                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13393                                    dumpDalvik, innerArgs);
13394                        } catch (RemoteException e) {
13395                            if (!isCheckinRequest) {
13396                                pw.println("Got RemoteException!");
13397                                pw.flush();
13398                            }
13399                        }
13400                    }
13401                }
13402
13403                final long myTotalPss = mi.getTotalPss();
13404                final long myTotalUss = mi.getTotalUss();
13405
13406                synchronized (this) {
13407                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13408                        // Record this for posterity if the process has been stable.
13409                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13410                    }
13411                }
13412
13413                if (!isCheckinRequest && mi != null) {
13414                    totalPss += myTotalPss;
13415                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13416                            (hasActivities ? " / activities)" : ")"),
13417                            r.processName, myTotalPss, pid, hasActivities);
13418                    procMems.add(pssItem);
13419                    procMemsMap.put(pid, pssItem);
13420
13421                    nativePss += mi.nativePss;
13422                    dalvikPss += mi.dalvikPss;
13423                    otherPss += mi.otherPss;
13424                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13425                        long mem = mi.getOtherPss(j);
13426                        miscPss[j] += mem;
13427                        otherPss -= mem;
13428                    }
13429
13430                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13431                        cachedPss += myTotalPss;
13432                    }
13433
13434                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13435                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13436                                || oomIndex == (oomPss.length-1)) {
13437                            oomPss[oomIndex] += myTotalPss;
13438                            if (oomProcs[oomIndex] == null) {
13439                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13440                            }
13441                            oomProcs[oomIndex].add(pssItem);
13442                            break;
13443                        }
13444                    }
13445                }
13446            }
13447        }
13448
13449        long nativeProcTotalPss = 0;
13450
13451        if (!isCheckinRequest && procs.size() > 1) {
13452            // If we are showing aggregations, also look for native processes to
13453            // include so that our aggregations are more accurate.
13454            updateCpuStatsNow();
13455            synchronized (mProcessCpuThread) {
13456                final int N = mProcessCpuTracker.countStats();
13457                for (int i=0; i<N; i++) {
13458                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13459                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13460                        if (mi == null) {
13461                            mi = new Debug.MemoryInfo();
13462                        }
13463                        if (!brief && !oomOnly) {
13464                            Debug.getMemoryInfo(st.pid, mi);
13465                        } else {
13466                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13467                            mi.nativePrivateDirty = (int)tmpLong[0];
13468                        }
13469
13470                        final long myTotalPss = mi.getTotalPss();
13471                        totalPss += myTotalPss;
13472                        nativeProcTotalPss += myTotalPss;
13473
13474                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13475                                st.name, myTotalPss, st.pid, false);
13476                        procMems.add(pssItem);
13477
13478                        nativePss += mi.nativePss;
13479                        dalvikPss += mi.dalvikPss;
13480                        otherPss += mi.otherPss;
13481                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13482                            long mem = mi.getOtherPss(j);
13483                            miscPss[j] += mem;
13484                            otherPss -= mem;
13485                        }
13486                        oomPss[0] += myTotalPss;
13487                        if (oomProcs[0] == null) {
13488                            oomProcs[0] = new ArrayList<MemItem>();
13489                        }
13490                        oomProcs[0].add(pssItem);
13491                    }
13492                }
13493            }
13494
13495            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13496
13497            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13498            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13499            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13500            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13501                String label = Debug.MemoryInfo.getOtherLabel(j);
13502                catMems.add(new MemItem(label, label, miscPss[j], j));
13503            }
13504
13505            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13506            for (int j=0; j<oomPss.length; j++) {
13507                if (oomPss[j] != 0) {
13508                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13509                            : DUMP_MEM_OOM_LABEL[j];
13510                    MemItem item = new MemItem(label, label, oomPss[j],
13511                            DUMP_MEM_OOM_ADJ[j]);
13512                    item.subitems = oomProcs[j];
13513                    oomMems.add(item);
13514                }
13515            }
13516
13517            if (!brief && !oomOnly && !isCompact) {
13518                pw.println();
13519                pw.println("Total PSS by process:");
13520                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13521                pw.println();
13522            }
13523            if (!isCompact) {
13524                pw.println("Total PSS by OOM adjustment:");
13525            }
13526            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13527            if (!brief && !oomOnly) {
13528                PrintWriter out = categoryPw != null ? categoryPw : pw;
13529                if (!isCompact) {
13530                    out.println();
13531                    out.println("Total PSS by category:");
13532                }
13533                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13534            }
13535            if (!isCompact) {
13536                pw.println();
13537            }
13538            MemInfoReader memInfo = new MemInfoReader();
13539            memInfo.readMemInfo();
13540            if (nativeProcTotalPss > 0) {
13541                synchronized (this) {
13542                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13543                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13544                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13545                            nativeProcTotalPss);
13546                }
13547            }
13548            if (!brief) {
13549                if (!isCompact) {
13550                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13551                    pw.print(" kB (status ");
13552                    switch (mLastMemoryLevel) {
13553                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13554                            pw.println("normal)");
13555                            break;
13556                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13557                            pw.println("moderate)");
13558                            break;
13559                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13560                            pw.println("low)");
13561                            break;
13562                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13563                            pw.println("critical)");
13564                            break;
13565                        default:
13566                            pw.print(mLastMemoryLevel);
13567                            pw.println(")");
13568                            break;
13569                    }
13570                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13571                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13572                            pw.print(cachedPss); pw.print(" cached pss + ");
13573                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13574                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13575                } else {
13576                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13577                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13578                            + memInfo.getFreeSizeKb()); pw.print(",");
13579                    pw.println(totalPss - cachedPss);
13580                }
13581            }
13582            if (!isCompact) {
13583                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13584                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13585                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13586                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13587                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13588                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13589                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13590                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13591                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13592                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13593                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13594            }
13595            if (!brief) {
13596                if (memInfo.getZramTotalSizeKb() != 0) {
13597                    if (!isCompact) {
13598                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13599                                pw.print(" kB physical used for ");
13600                                pw.print(memInfo.getSwapTotalSizeKb()
13601                                        - memInfo.getSwapFreeSizeKb());
13602                                pw.print(" kB in swap (");
13603                                pw.print(memInfo.getSwapTotalSizeKb());
13604                                pw.println(" kB total swap)");
13605                    } else {
13606                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13607                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13608                                pw.println(memInfo.getSwapFreeSizeKb());
13609                    }
13610                }
13611                final int[] SINGLE_LONG_FORMAT = new int[] {
13612                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13613                };
13614                long[] longOut = new long[1];
13615                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13616                        SINGLE_LONG_FORMAT, null, longOut, null);
13617                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13618                longOut[0] = 0;
13619                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13620                        SINGLE_LONG_FORMAT, null, longOut, null);
13621                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13622                longOut[0] = 0;
13623                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13624                        SINGLE_LONG_FORMAT, null, longOut, null);
13625                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13626                longOut[0] = 0;
13627                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13628                        SINGLE_LONG_FORMAT, null, longOut, null);
13629                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13630                if (!isCompact) {
13631                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13632                        pw.print("      KSM: "); pw.print(sharing);
13633                                pw.print(" kB saved from shared ");
13634                                pw.print(shared); pw.println(" kB");
13635                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13636                                pw.print(voltile); pw.println(" kB volatile");
13637                    }
13638                    pw.print("   Tuning: ");
13639                    pw.print(ActivityManager.staticGetMemoryClass());
13640                    pw.print(" (large ");
13641                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13642                    pw.print("), oom ");
13643                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13644                    pw.print(" kB");
13645                    pw.print(", restore limit ");
13646                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13647                    pw.print(" kB");
13648                    if (ActivityManager.isLowRamDeviceStatic()) {
13649                        pw.print(" (low-ram)");
13650                    }
13651                    if (ActivityManager.isHighEndGfx()) {
13652                        pw.print(" (high-end-gfx)");
13653                    }
13654                    pw.println();
13655                } else {
13656                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13657                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13658                    pw.println(voltile);
13659                    pw.print("tuning,");
13660                    pw.print(ActivityManager.staticGetMemoryClass());
13661                    pw.print(',');
13662                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13663                    pw.print(',');
13664                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13665                    if (ActivityManager.isLowRamDeviceStatic()) {
13666                        pw.print(",low-ram");
13667                    }
13668                    if (ActivityManager.isHighEndGfx()) {
13669                        pw.print(",high-end-gfx");
13670                    }
13671                    pw.println();
13672                }
13673            }
13674        }
13675    }
13676
13677    /**
13678     * Searches array of arguments for the specified string
13679     * @param args array of argument strings
13680     * @param value value to search for
13681     * @return true if the value is contained in the array
13682     */
13683    private static boolean scanArgs(String[] args, String value) {
13684        if (args != null) {
13685            for (String arg : args) {
13686                if (value.equals(arg)) {
13687                    return true;
13688                }
13689            }
13690        }
13691        return false;
13692    }
13693
13694    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13695            ContentProviderRecord cpr, boolean always) {
13696        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13697
13698        if (!inLaunching || always) {
13699            synchronized (cpr) {
13700                cpr.launchingApp = null;
13701                cpr.notifyAll();
13702            }
13703            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13704            String names[] = cpr.info.authority.split(";");
13705            for (int j = 0; j < names.length; j++) {
13706                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13707            }
13708        }
13709
13710        for (int i=0; i<cpr.connections.size(); i++) {
13711            ContentProviderConnection conn = cpr.connections.get(i);
13712            if (conn.waiting) {
13713                // If this connection is waiting for the provider, then we don't
13714                // need to mess with its process unless we are always removing
13715                // or for some reason the provider is not currently launching.
13716                if (inLaunching && !always) {
13717                    continue;
13718                }
13719            }
13720            ProcessRecord capp = conn.client;
13721            conn.dead = true;
13722            if (conn.stableCount > 0) {
13723                if (!capp.persistent && capp.thread != null
13724                        && capp.pid != 0
13725                        && capp.pid != MY_PID) {
13726                    capp.kill("depends on provider "
13727                            + cpr.name.flattenToShortString()
13728                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
13729                }
13730            } else if (capp.thread != null && conn.provider.provider != null) {
13731                try {
13732                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13733                } catch (RemoteException e) {
13734                }
13735                // In the protocol here, we don't expect the client to correctly
13736                // clean up this connection, we'll just remove it.
13737                cpr.connections.remove(i);
13738                conn.client.conProviders.remove(conn);
13739            }
13740        }
13741
13742        if (inLaunching && always) {
13743            mLaunchingProviders.remove(cpr);
13744        }
13745        return inLaunching;
13746    }
13747
13748    /**
13749     * Main code for cleaning up a process when it has gone away.  This is
13750     * called both as a result of the process dying, or directly when stopping
13751     * a process when running in single process mode.
13752     */
13753    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13754            boolean restarting, boolean allowRestart, int index) {
13755        if (index >= 0) {
13756            removeLruProcessLocked(app);
13757            ProcessList.remove(app.pid);
13758        }
13759
13760        mProcessesToGc.remove(app);
13761        mPendingPssProcesses.remove(app);
13762
13763        // Dismiss any open dialogs.
13764        if (app.crashDialog != null && !app.forceCrashReport) {
13765            app.crashDialog.dismiss();
13766            app.crashDialog = null;
13767        }
13768        if (app.anrDialog != null) {
13769            app.anrDialog.dismiss();
13770            app.anrDialog = null;
13771        }
13772        if (app.waitDialog != null) {
13773            app.waitDialog.dismiss();
13774            app.waitDialog = null;
13775        }
13776
13777        app.crashing = false;
13778        app.notResponding = false;
13779
13780        app.resetPackageList(mProcessStats);
13781        app.unlinkDeathRecipient();
13782        app.makeInactive(mProcessStats);
13783        app.waitingToKill = null;
13784        app.forcingToForeground = null;
13785        updateProcessForegroundLocked(app, false, false);
13786        app.foregroundActivities = false;
13787        app.hasShownUi = false;
13788        app.treatLikeActivity = false;
13789        app.hasAboveClient = false;
13790        app.hasClientActivities = false;
13791
13792        mServices.killServicesLocked(app, allowRestart);
13793
13794        boolean restart = false;
13795
13796        // Remove published content providers.
13797        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13798            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13799            final boolean always = app.bad || !allowRestart;
13800            if (removeDyingProviderLocked(app, cpr, always) || always) {
13801                // We left the provider in the launching list, need to
13802                // restart it.
13803                restart = true;
13804            }
13805
13806            cpr.provider = null;
13807            cpr.proc = null;
13808        }
13809        app.pubProviders.clear();
13810
13811        // Take care of any launching providers waiting for this process.
13812        if (checkAppInLaunchingProvidersLocked(app, false)) {
13813            restart = true;
13814        }
13815
13816        // Unregister from connected content providers.
13817        if (!app.conProviders.isEmpty()) {
13818            for (int i=0; i<app.conProviders.size(); i++) {
13819                ContentProviderConnection conn = app.conProviders.get(i);
13820                conn.provider.connections.remove(conn);
13821            }
13822            app.conProviders.clear();
13823        }
13824
13825        // At this point there may be remaining entries in mLaunchingProviders
13826        // where we were the only one waiting, so they are no longer of use.
13827        // Look for these and clean up if found.
13828        // XXX Commented out for now.  Trying to figure out a way to reproduce
13829        // the actual situation to identify what is actually going on.
13830        if (false) {
13831            for (int i=0; i<mLaunchingProviders.size(); i++) {
13832                ContentProviderRecord cpr = (ContentProviderRecord)
13833                        mLaunchingProviders.get(i);
13834                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13835                    synchronized (cpr) {
13836                        cpr.launchingApp = null;
13837                        cpr.notifyAll();
13838                    }
13839                }
13840            }
13841        }
13842
13843        skipCurrentReceiverLocked(app);
13844
13845        // Unregister any receivers.
13846        for (int i=app.receivers.size()-1; i>=0; i--) {
13847            removeReceiverLocked(app.receivers.valueAt(i));
13848        }
13849        app.receivers.clear();
13850
13851        // If the app is undergoing backup, tell the backup manager about it
13852        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13853            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13854                    + mBackupTarget.appInfo + " died during backup");
13855            try {
13856                IBackupManager bm = IBackupManager.Stub.asInterface(
13857                        ServiceManager.getService(Context.BACKUP_SERVICE));
13858                bm.agentDisconnected(app.info.packageName);
13859            } catch (RemoteException e) {
13860                // can't happen; backup manager is local
13861            }
13862        }
13863
13864        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13865            ProcessChangeItem item = mPendingProcessChanges.get(i);
13866            if (item.pid == app.pid) {
13867                mPendingProcessChanges.remove(i);
13868                mAvailProcessChanges.add(item);
13869            }
13870        }
13871        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13872
13873        // If the caller is restarting this app, then leave it in its
13874        // current lists and let the caller take care of it.
13875        if (restarting) {
13876            return;
13877        }
13878
13879        if (!app.persistent || app.isolated) {
13880            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13881                    "Removing non-persistent process during cleanup: " + app);
13882            mProcessNames.remove(app.processName, app.uid);
13883            mIsolatedProcesses.remove(app.uid);
13884            if (mHeavyWeightProcess == app) {
13885                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13886                        mHeavyWeightProcess.userId, 0));
13887                mHeavyWeightProcess = null;
13888            }
13889        } else if (!app.removed) {
13890            // This app is persistent, so we need to keep its record around.
13891            // If it is not already on the pending app list, add it there
13892            // and start a new process for it.
13893            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13894                mPersistentStartingProcesses.add(app);
13895                restart = true;
13896            }
13897        }
13898        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13899                "Clean-up removing on hold: " + app);
13900        mProcessesOnHold.remove(app);
13901
13902        if (app == mHomeProcess) {
13903            mHomeProcess = null;
13904        }
13905        if (app == mPreviousProcess) {
13906            mPreviousProcess = null;
13907        }
13908
13909        if (restart && !app.isolated) {
13910            // We have components that still need to be running in the
13911            // process, so re-launch it.
13912            mProcessNames.put(app.processName, app.uid, app);
13913            startProcessLocked(app, "restart", app.processName);
13914        } else if (app.pid > 0 && app.pid != MY_PID) {
13915            // Goodbye!
13916            boolean removed;
13917            synchronized (mPidsSelfLocked) {
13918                mPidsSelfLocked.remove(app.pid);
13919                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13920            }
13921            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13922            if (app.isolated) {
13923                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13924            }
13925            app.setPid(0);
13926        }
13927    }
13928
13929    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13930        // Look through the content providers we are waiting to have launched,
13931        // and if any run in this process then either schedule a restart of
13932        // the process or kill the client waiting for it if this process has
13933        // gone bad.
13934        int NL = mLaunchingProviders.size();
13935        boolean restart = false;
13936        for (int i=0; i<NL; i++) {
13937            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13938            if (cpr.launchingApp == app) {
13939                if (!alwaysBad && !app.bad) {
13940                    restart = true;
13941                } else {
13942                    removeDyingProviderLocked(app, cpr, true);
13943                    // cpr should have been removed from mLaunchingProviders
13944                    NL = mLaunchingProviders.size();
13945                    i--;
13946                }
13947            }
13948        }
13949        return restart;
13950    }
13951
13952    // =========================================================
13953    // SERVICES
13954    // =========================================================
13955
13956    @Override
13957    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13958            int flags) {
13959        enforceNotIsolatedCaller("getServices");
13960        synchronized (this) {
13961            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13962        }
13963    }
13964
13965    @Override
13966    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13967        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13968        synchronized (this) {
13969            return mServices.getRunningServiceControlPanelLocked(name);
13970        }
13971    }
13972
13973    @Override
13974    public ComponentName startService(IApplicationThread caller, Intent service,
13975            String resolvedType, int userId) {
13976        enforceNotIsolatedCaller("startService");
13977        // Refuse possible leaked file descriptors
13978        if (service != null && service.hasFileDescriptors() == true) {
13979            throw new IllegalArgumentException("File descriptors passed in Intent");
13980        }
13981
13982        if (DEBUG_SERVICE)
13983            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13984        synchronized(this) {
13985            final int callingPid = Binder.getCallingPid();
13986            final int callingUid = Binder.getCallingUid();
13987            final long origId = Binder.clearCallingIdentity();
13988            ComponentName res = mServices.startServiceLocked(caller, service,
13989                    resolvedType, callingPid, callingUid, userId);
13990            Binder.restoreCallingIdentity(origId);
13991            return res;
13992        }
13993    }
13994
13995    ComponentName startServiceInPackage(int uid,
13996            Intent service, String resolvedType, int userId) {
13997        synchronized(this) {
13998            if (DEBUG_SERVICE)
13999                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14000            final long origId = Binder.clearCallingIdentity();
14001            ComponentName res = mServices.startServiceLocked(null, service,
14002                    resolvedType, -1, uid, userId);
14003            Binder.restoreCallingIdentity(origId);
14004            return res;
14005        }
14006    }
14007
14008    @Override
14009    public int stopService(IApplicationThread caller, Intent service,
14010            String resolvedType, int userId) {
14011        enforceNotIsolatedCaller("stopService");
14012        // Refuse possible leaked file descriptors
14013        if (service != null && service.hasFileDescriptors() == true) {
14014            throw new IllegalArgumentException("File descriptors passed in Intent");
14015        }
14016
14017        synchronized(this) {
14018            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14019        }
14020    }
14021
14022    @Override
14023    public IBinder peekService(Intent service, String resolvedType) {
14024        enforceNotIsolatedCaller("peekService");
14025        // Refuse possible leaked file descriptors
14026        if (service != null && service.hasFileDescriptors() == true) {
14027            throw new IllegalArgumentException("File descriptors passed in Intent");
14028        }
14029        synchronized(this) {
14030            return mServices.peekServiceLocked(service, resolvedType);
14031        }
14032    }
14033
14034    @Override
14035    public boolean stopServiceToken(ComponentName className, IBinder token,
14036            int startId) {
14037        synchronized(this) {
14038            return mServices.stopServiceTokenLocked(className, token, startId);
14039        }
14040    }
14041
14042    @Override
14043    public void setServiceForeground(ComponentName className, IBinder token,
14044            int id, Notification notification, boolean removeNotification) {
14045        synchronized(this) {
14046            mServices.setServiceForegroundLocked(className, token, id, notification,
14047                    removeNotification);
14048        }
14049    }
14050
14051    @Override
14052    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14053            boolean requireFull, String name, String callerPackage) {
14054        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14055                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14056    }
14057
14058    int unsafeConvertIncomingUser(int userId) {
14059        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14060                ? mCurrentUserId : userId;
14061    }
14062
14063    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14064            int allowMode, String name, String callerPackage) {
14065        final int callingUserId = UserHandle.getUserId(callingUid);
14066        if (callingUserId == userId) {
14067            return userId;
14068        }
14069
14070        // Note that we may be accessing mCurrentUserId outside of a lock...
14071        // shouldn't be a big deal, if this is being called outside
14072        // of a locked context there is intrinsically a race with
14073        // the value the caller will receive and someone else changing it.
14074        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14075        // we will switch to the calling user if access to the current user fails.
14076        int targetUserId = unsafeConvertIncomingUser(userId);
14077
14078        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14079            final boolean allow;
14080            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14081                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14082                // If the caller has this permission, they always pass go.  And collect $200.
14083                allow = true;
14084            } else if (allowMode == ALLOW_FULL_ONLY) {
14085                // We require full access, sucks to be you.
14086                allow = false;
14087            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14088                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14089                // If the caller does not have either permission, they are always doomed.
14090                allow = false;
14091            } else if (allowMode == ALLOW_NON_FULL) {
14092                // We are blanket allowing non-full access, you lucky caller!
14093                allow = true;
14094            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14095                // We may or may not allow this depending on whether the two users are
14096                // in the same profile.
14097                synchronized (mUserProfileGroupIdsSelfLocked) {
14098                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14099                            UserInfo.NO_PROFILE_GROUP_ID);
14100                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14101                            UserInfo.NO_PROFILE_GROUP_ID);
14102                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14103                            && callingProfile == targetProfile;
14104                }
14105            } else {
14106                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14107            }
14108            if (!allow) {
14109                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14110                    // In this case, they would like to just execute as their
14111                    // owner user instead of failing.
14112                    targetUserId = callingUserId;
14113                } else {
14114                    StringBuilder builder = new StringBuilder(128);
14115                    builder.append("Permission Denial: ");
14116                    builder.append(name);
14117                    if (callerPackage != null) {
14118                        builder.append(" from ");
14119                        builder.append(callerPackage);
14120                    }
14121                    builder.append(" asks to run as user ");
14122                    builder.append(userId);
14123                    builder.append(" but is calling from user ");
14124                    builder.append(UserHandle.getUserId(callingUid));
14125                    builder.append("; this requires ");
14126                    builder.append(INTERACT_ACROSS_USERS_FULL);
14127                    if (allowMode != ALLOW_FULL_ONLY) {
14128                        builder.append(" or ");
14129                        builder.append(INTERACT_ACROSS_USERS);
14130                    }
14131                    String msg = builder.toString();
14132                    Slog.w(TAG, msg);
14133                    throw new SecurityException(msg);
14134                }
14135            }
14136        }
14137        if (!allowAll && targetUserId < 0) {
14138            throw new IllegalArgumentException(
14139                    "Call does not support special user #" + targetUserId);
14140        }
14141        return targetUserId;
14142    }
14143
14144    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14145            String className, int flags) {
14146        boolean result = false;
14147        // For apps that don't have pre-defined UIDs, check for permission
14148        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14149            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14150                if (ActivityManager.checkUidPermission(
14151                        INTERACT_ACROSS_USERS,
14152                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14153                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14154                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14155                            + " requests FLAG_SINGLE_USER, but app does not hold "
14156                            + INTERACT_ACROSS_USERS;
14157                    Slog.w(TAG, msg);
14158                    throw new SecurityException(msg);
14159                }
14160                // Permission passed
14161                result = true;
14162            }
14163        } else if ("system".equals(componentProcessName)) {
14164            result = true;
14165        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14166                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14167            // Phone app is allowed to export singleuser providers.
14168            result = true;
14169        } else {
14170            // App with pre-defined UID, check if it's a persistent app
14171            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14172        }
14173        if (DEBUG_MU) {
14174            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14175                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14176        }
14177        return result;
14178    }
14179
14180    /**
14181     * Checks to see if the caller is in the same app as the singleton
14182     * component, or the component is in a special app. It allows special apps
14183     * to export singleton components but prevents exporting singleton
14184     * components for regular apps.
14185     */
14186    boolean isValidSingletonCall(int callingUid, int componentUid) {
14187        int componentAppId = UserHandle.getAppId(componentUid);
14188        return UserHandle.isSameApp(callingUid, componentUid)
14189                || componentAppId == Process.SYSTEM_UID
14190                || componentAppId == Process.PHONE_UID
14191                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14192                        == PackageManager.PERMISSION_GRANTED;
14193    }
14194
14195    public int bindService(IApplicationThread caller, IBinder token,
14196            Intent service, String resolvedType,
14197            IServiceConnection connection, int flags, int userId) {
14198        enforceNotIsolatedCaller("bindService");
14199        // Refuse possible leaked file descriptors
14200        if (service != null && service.hasFileDescriptors() == true) {
14201            throw new IllegalArgumentException("File descriptors passed in Intent");
14202        }
14203
14204        synchronized(this) {
14205            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14206                    connection, flags, userId);
14207        }
14208    }
14209
14210    public boolean unbindService(IServiceConnection connection) {
14211        synchronized (this) {
14212            return mServices.unbindServiceLocked(connection);
14213        }
14214    }
14215
14216    public void publishService(IBinder token, Intent intent, IBinder service) {
14217        // Refuse possible leaked file descriptors
14218        if (intent != null && intent.hasFileDescriptors() == true) {
14219            throw new IllegalArgumentException("File descriptors passed in Intent");
14220        }
14221
14222        synchronized(this) {
14223            if (!(token instanceof ServiceRecord)) {
14224                throw new IllegalArgumentException("Invalid service token");
14225            }
14226            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14227        }
14228    }
14229
14230    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14231        // Refuse possible leaked file descriptors
14232        if (intent != null && intent.hasFileDescriptors() == true) {
14233            throw new IllegalArgumentException("File descriptors passed in Intent");
14234        }
14235
14236        synchronized(this) {
14237            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14238        }
14239    }
14240
14241    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14242        synchronized(this) {
14243            if (!(token instanceof ServiceRecord)) {
14244                throw new IllegalArgumentException("Invalid service token");
14245            }
14246            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14247        }
14248    }
14249
14250    // =========================================================
14251    // BACKUP AND RESTORE
14252    // =========================================================
14253
14254    // Cause the target app to be launched if necessary and its backup agent
14255    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14256    // activity manager to announce its creation.
14257    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14258        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14259        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14260
14261        synchronized(this) {
14262            // !!! TODO: currently no check here that we're already bound
14263            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14264            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14265            synchronized (stats) {
14266                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14267            }
14268
14269            // Backup agent is now in use, its package can't be stopped.
14270            try {
14271                AppGlobals.getPackageManager().setPackageStoppedState(
14272                        app.packageName, false, UserHandle.getUserId(app.uid));
14273            } catch (RemoteException e) {
14274            } catch (IllegalArgumentException e) {
14275                Slog.w(TAG, "Failed trying to unstop package "
14276                        + app.packageName + ": " + e);
14277            }
14278
14279            BackupRecord r = new BackupRecord(ss, app, backupMode);
14280            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14281                    ? new ComponentName(app.packageName, app.backupAgentName)
14282                    : new ComponentName("android", "FullBackupAgent");
14283            // startProcessLocked() returns existing proc's record if it's already running
14284            ProcessRecord proc = startProcessLocked(app.processName, app,
14285                    false, 0, "backup", hostingName, false, false, false);
14286            if (proc == null) {
14287                Slog.e(TAG, "Unable to start backup agent process " + r);
14288                return false;
14289            }
14290
14291            r.app = proc;
14292            mBackupTarget = r;
14293            mBackupAppName = app.packageName;
14294
14295            // Try not to kill the process during backup
14296            updateOomAdjLocked(proc);
14297
14298            // If the process is already attached, schedule the creation of the backup agent now.
14299            // If it is not yet live, this will be done when it attaches to the framework.
14300            if (proc.thread != null) {
14301                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14302                try {
14303                    proc.thread.scheduleCreateBackupAgent(app,
14304                            compatibilityInfoForPackageLocked(app), backupMode);
14305                } catch (RemoteException e) {
14306                    // Will time out on the backup manager side
14307                }
14308            } else {
14309                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14310            }
14311            // Invariants: at this point, the target app process exists and the application
14312            // is either already running or in the process of coming up.  mBackupTarget and
14313            // mBackupAppName describe the app, so that when it binds back to the AM we
14314            // know that it's scheduled for a backup-agent operation.
14315        }
14316
14317        return true;
14318    }
14319
14320    @Override
14321    public void clearPendingBackup() {
14322        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14323        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14324
14325        synchronized (this) {
14326            mBackupTarget = null;
14327            mBackupAppName = null;
14328        }
14329    }
14330
14331    // A backup agent has just come up
14332    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14333        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14334                + " = " + agent);
14335
14336        synchronized(this) {
14337            if (!agentPackageName.equals(mBackupAppName)) {
14338                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14339                return;
14340            }
14341        }
14342
14343        long oldIdent = Binder.clearCallingIdentity();
14344        try {
14345            IBackupManager bm = IBackupManager.Stub.asInterface(
14346                    ServiceManager.getService(Context.BACKUP_SERVICE));
14347            bm.agentConnected(agentPackageName, agent);
14348        } catch (RemoteException e) {
14349            // can't happen; the backup manager service is local
14350        } catch (Exception e) {
14351            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14352            e.printStackTrace();
14353        } finally {
14354            Binder.restoreCallingIdentity(oldIdent);
14355        }
14356    }
14357
14358    // done with this agent
14359    public void unbindBackupAgent(ApplicationInfo appInfo) {
14360        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14361        if (appInfo == null) {
14362            Slog.w(TAG, "unbind backup agent for null app");
14363            return;
14364        }
14365
14366        synchronized(this) {
14367            try {
14368                if (mBackupAppName == null) {
14369                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14370                    return;
14371                }
14372
14373                if (!mBackupAppName.equals(appInfo.packageName)) {
14374                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14375                    return;
14376                }
14377
14378                // Not backing this app up any more; reset its OOM adjustment
14379                final ProcessRecord proc = mBackupTarget.app;
14380                updateOomAdjLocked(proc);
14381
14382                // If the app crashed during backup, 'thread' will be null here
14383                if (proc.thread != null) {
14384                    try {
14385                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14386                                compatibilityInfoForPackageLocked(appInfo));
14387                    } catch (Exception e) {
14388                        Slog.e(TAG, "Exception when unbinding backup agent:");
14389                        e.printStackTrace();
14390                    }
14391                }
14392            } finally {
14393                mBackupTarget = null;
14394                mBackupAppName = null;
14395            }
14396        }
14397    }
14398    // =========================================================
14399    // BROADCASTS
14400    // =========================================================
14401
14402    private final List getStickiesLocked(String action, IntentFilter filter,
14403            List cur, int userId) {
14404        final ContentResolver resolver = mContext.getContentResolver();
14405        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14406        if (stickies == null) {
14407            return cur;
14408        }
14409        final ArrayList<Intent> list = stickies.get(action);
14410        if (list == null) {
14411            return cur;
14412        }
14413        int N = list.size();
14414        for (int i=0; i<N; i++) {
14415            Intent intent = list.get(i);
14416            if (filter.match(resolver, intent, true, TAG) >= 0) {
14417                if (cur == null) {
14418                    cur = new ArrayList<Intent>();
14419                }
14420                cur.add(intent);
14421            }
14422        }
14423        return cur;
14424    }
14425
14426    boolean isPendingBroadcastProcessLocked(int pid) {
14427        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14428                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14429    }
14430
14431    void skipPendingBroadcastLocked(int pid) {
14432            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14433            for (BroadcastQueue queue : mBroadcastQueues) {
14434                queue.skipPendingBroadcastLocked(pid);
14435            }
14436    }
14437
14438    // The app just attached; send any pending broadcasts that it should receive
14439    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14440        boolean didSomething = false;
14441        for (BroadcastQueue queue : mBroadcastQueues) {
14442            didSomething |= queue.sendPendingBroadcastsLocked(app);
14443        }
14444        return didSomething;
14445    }
14446
14447    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14448            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14449        enforceNotIsolatedCaller("registerReceiver");
14450        int callingUid;
14451        int callingPid;
14452        synchronized(this) {
14453            ProcessRecord callerApp = null;
14454            if (caller != null) {
14455                callerApp = getRecordForAppLocked(caller);
14456                if (callerApp == null) {
14457                    throw new SecurityException(
14458                            "Unable to find app for caller " + caller
14459                            + " (pid=" + Binder.getCallingPid()
14460                            + ") when registering receiver " + receiver);
14461                }
14462                if (callerApp.info.uid != Process.SYSTEM_UID &&
14463                        !callerApp.pkgList.containsKey(callerPackage) &&
14464                        !"android".equals(callerPackage)) {
14465                    throw new SecurityException("Given caller package " + callerPackage
14466                            + " is not running in process " + callerApp);
14467                }
14468                callingUid = callerApp.info.uid;
14469                callingPid = callerApp.pid;
14470            } else {
14471                callerPackage = null;
14472                callingUid = Binder.getCallingUid();
14473                callingPid = Binder.getCallingPid();
14474            }
14475
14476            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14477                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14478
14479            List allSticky = null;
14480
14481            // Look for any matching sticky broadcasts...
14482            Iterator actions = filter.actionsIterator();
14483            if (actions != null) {
14484                while (actions.hasNext()) {
14485                    String action = (String)actions.next();
14486                    allSticky = getStickiesLocked(action, filter, allSticky,
14487                            UserHandle.USER_ALL);
14488                    allSticky = getStickiesLocked(action, filter, allSticky,
14489                            UserHandle.getUserId(callingUid));
14490                }
14491            } else {
14492                allSticky = getStickiesLocked(null, filter, allSticky,
14493                        UserHandle.USER_ALL);
14494                allSticky = getStickiesLocked(null, filter, allSticky,
14495                        UserHandle.getUserId(callingUid));
14496            }
14497
14498            // The first sticky in the list is returned directly back to
14499            // the client.
14500            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14501
14502            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14503                    + ": " + sticky);
14504
14505            if (receiver == null) {
14506                return sticky;
14507            }
14508
14509            ReceiverList rl
14510                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14511            if (rl == null) {
14512                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14513                        userId, receiver);
14514                if (rl.app != null) {
14515                    rl.app.receivers.add(rl);
14516                } else {
14517                    try {
14518                        receiver.asBinder().linkToDeath(rl, 0);
14519                    } catch (RemoteException e) {
14520                        return sticky;
14521                    }
14522                    rl.linkedToDeath = true;
14523                }
14524                mRegisteredReceivers.put(receiver.asBinder(), rl);
14525            } else if (rl.uid != callingUid) {
14526                throw new IllegalArgumentException(
14527                        "Receiver requested to register for uid " + callingUid
14528                        + " was previously registered for uid " + rl.uid);
14529            } else if (rl.pid != callingPid) {
14530                throw new IllegalArgumentException(
14531                        "Receiver requested to register for pid " + callingPid
14532                        + " was previously registered for pid " + rl.pid);
14533            } else if (rl.userId != userId) {
14534                throw new IllegalArgumentException(
14535                        "Receiver requested to register for user " + userId
14536                        + " was previously registered for user " + rl.userId);
14537            }
14538            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14539                    permission, callingUid, userId);
14540            rl.add(bf);
14541            if (!bf.debugCheck()) {
14542                Slog.w(TAG, "==> For Dynamic broadast");
14543            }
14544            mReceiverResolver.addFilter(bf);
14545
14546            // Enqueue broadcasts for all existing stickies that match
14547            // this filter.
14548            if (allSticky != null) {
14549                ArrayList receivers = new ArrayList();
14550                receivers.add(bf);
14551
14552                int N = allSticky.size();
14553                for (int i=0; i<N; i++) {
14554                    Intent intent = (Intent)allSticky.get(i);
14555                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14556                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14557                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14558                            null, null, false, true, true, -1);
14559                    queue.enqueueParallelBroadcastLocked(r);
14560                    queue.scheduleBroadcastsLocked();
14561                }
14562            }
14563
14564            return sticky;
14565        }
14566    }
14567
14568    public void unregisterReceiver(IIntentReceiver receiver) {
14569        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14570
14571        final long origId = Binder.clearCallingIdentity();
14572        try {
14573            boolean doTrim = false;
14574
14575            synchronized(this) {
14576                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14577                if (rl != null) {
14578                    if (rl.curBroadcast != null) {
14579                        BroadcastRecord r = rl.curBroadcast;
14580                        final boolean doNext = finishReceiverLocked(
14581                                receiver.asBinder(), r.resultCode, r.resultData,
14582                                r.resultExtras, r.resultAbort);
14583                        if (doNext) {
14584                            doTrim = true;
14585                            r.queue.processNextBroadcast(false);
14586                        }
14587                    }
14588
14589                    if (rl.app != null) {
14590                        rl.app.receivers.remove(rl);
14591                    }
14592                    removeReceiverLocked(rl);
14593                    if (rl.linkedToDeath) {
14594                        rl.linkedToDeath = false;
14595                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14596                    }
14597                }
14598            }
14599
14600            // If we actually concluded any broadcasts, we might now be able
14601            // to trim the recipients' apps from our working set
14602            if (doTrim) {
14603                trimApplications();
14604                return;
14605            }
14606
14607        } finally {
14608            Binder.restoreCallingIdentity(origId);
14609        }
14610    }
14611
14612    void removeReceiverLocked(ReceiverList rl) {
14613        mRegisteredReceivers.remove(rl.receiver.asBinder());
14614        int N = rl.size();
14615        for (int i=0; i<N; i++) {
14616            mReceiverResolver.removeFilter(rl.get(i));
14617        }
14618    }
14619
14620    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14621        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14622            ProcessRecord r = mLruProcesses.get(i);
14623            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14624                try {
14625                    r.thread.dispatchPackageBroadcast(cmd, packages);
14626                } catch (RemoteException ex) {
14627                }
14628            }
14629        }
14630    }
14631
14632    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14633            int[] users) {
14634        List<ResolveInfo> receivers = null;
14635        try {
14636            HashSet<ComponentName> singleUserReceivers = null;
14637            boolean scannedFirstReceivers = false;
14638            for (int user : users) {
14639                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14640                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14641                if (user != 0 && newReceivers != null) {
14642                    // If this is not the primary user, we need to check for
14643                    // any receivers that should be filtered out.
14644                    for (int i=0; i<newReceivers.size(); i++) {
14645                        ResolveInfo ri = newReceivers.get(i);
14646                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14647                            newReceivers.remove(i);
14648                            i--;
14649                        }
14650                    }
14651                }
14652                if (newReceivers != null && newReceivers.size() == 0) {
14653                    newReceivers = null;
14654                }
14655                if (receivers == null) {
14656                    receivers = newReceivers;
14657                } else if (newReceivers != null) {
14658                    // We need to concatenate the additional receivers
14659                    // found with what we have do far.  This would be easy,
14660                    // but we also need to de-dup any receivers that are
14661                    // singleUser.
14662                    if (!scannedFirstReceivers) {
14663                        // Collect any single user receivers we had already retrieved.
14664                        scannedFirstReceivers = true;
14665                        for (int i=0; i<receivers.size(); i++) {
14666                            ResolveInfo ri = receivers.get(i);
14667                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14668                                ComponentName cn = new ComponentName(
14669                                        ri.activityInfo.packageName, ri.activityInfo.name);
14670                                if (singleUserReceivers == null) {
14671                                    singleUserReceivers = new HashSet<ComponentName>();
14672                                }
14673                                singleUserReceivers.add(cn);
14674                            }
14675                        }
14676                    }
14677                    // Add the new results to the existing results, tracking
14678                    // and de-dupping single user receivers.
14679                    for (int i=0; i<newReceivers.size(); i++) {
14680                        ResolveInfo ri = newReceivers.get(i);
14681                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14682                            ComponentName cn = new ComponentName(
14683                                    ri.activityInfo.packageName, ri.activityInfo.name);
14684                            if (singleUserReceivers == null) {
14685                                singleUserReceivers = new HashSet<ComponentName>();
14686                            }
14687                            if (!singleUserReceivers.contains(cn)) {
14688                                singleUserReceivers.add(cn);
14689                                receivers.add(ri);
14690                            }
14691                        } else {
14692                            receivers.add(ri);
14693                        }
14694                    }
14695                }
14696            }
14697        } catch (RemoteException ex) {
14698            // pm is in same process, this will never happen.
14699        }
14700        return receivers;
14701    }
14702
14703    private final int broadcastIntentLocked(ProcessRecord callerApp,
14704            String callerPackage, Intent intent, String resolvedType,
14705            IIntentReceiver resultTo, int resultCode, String resultData,
14706            Bundle map, String requiredPermission, int appOp,
14707            boolean ordered, boolean sticky, int callingPid, int callingUid,
14708            int userId) {
14709        intent = new Intent(intent);
14710
14711        // By default broadcasts do not go to stopped apps.
14712        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14713
14714        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14715            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14716            + " ordered=" + ordered + " userid=" + userId);
14717        if ((resultTo != null) && !ordered) {
14718            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14719        }
14720
14721        userId = handleIncomingUser(callingPid, callingUid, userId,
14722                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14723
14724        // Make sure that the user who is receiving this broadcast is started.
14725        // If not, we will just skip it.
14726
14727
14728        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14729            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14730                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14731                Slog.w(TAG, "Skipping broadcast of " + intent
14732                        + ": user " + userId + " is stopped");
14733                return ActivityManager.BROADCAST_SUCCESS;
14734            }
14735        }
14736
14737        /*
14738         * Prevent non-system code (defined here to be non-persistent
14739         * processes) from sending protected broadcasts.
14740         */
14741        int callingAppId = UserHandle.getAppId(callingUid);
14742        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14743            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14744            || callingAppId == Process.NFC_UID || callingUid == 0) {
14745            // Always okay.
14746        } else if (callerApp == null || !callerApp.persistent) {
14747            try {
14748                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14749                        intent.getAction())) {
14750                    String msg = "Permission Denial: not allowed to send broadcast "
14751                            + intent.getAction() + " from pid="
14752                            + callingPid + ", uid=" + callingUid;
14753                    Slog.w(TAG, msg);
14754                    throw new SecurityException(msg);
14755                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14756                    // Special case for compatibility: we don't want apps to send this,
14757                    // but historically it has not been protected and apps may be using it
14758                    // to poke their own app widget.  So, instead of making it protected,
14759                    // just limit it to the caller.
14760                    if (callerApp == null) {
14761                        String msg = "Permission Denial: not allowed to send broadcast "
14762                                + intent.getAction() + " from unknown caller.";
14763                        Slog.w(TAG, msg);
14764                        throw new SecurityException(msg);
14765                    } else if (intent.getComponent() != null) {
14766                        // They are good enough to send to an explicit component...  verify
14767                        // it is being sent to the calling app.
14768                        if (!intent.getComponent().getPackageName().equals(
14769                                callerApp.info.packageName)) {
14770                            String msg = "Permission Denial: not allowed to send broadcast "
14771                                    + intent.getAction() + " to "
14772                                    + intent.getComponent().getPackageName() + " from "
14773                                    + callerApp.info.packageName;
14774                            Slog.w(TAG, msg);
14775                            throw new SecurityException(msg);
14776                        }
14777                    } else {
14778                        // Limit broadcast to their own package.
14779                        intent.setPackage(callerApp.info.packageName);
14780                    }
14781                }
14782            } catch (RemoteException e) {
14783                Slog.w(TAG, "Remote exception", e);
14784                return ActivityManager.BROADCAST_SUCCESS;
14785            }
14786        }
14787
14788        // Handle special intents: if this broadcast is from the package
14789        // manager about a package being removed, we need to remove all of
14790        // its activities from the history stack.
14791        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14792                intent.getAction());
14793        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14794                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14795                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14796                || uidRemoved) {
14797            if (checkComponentPermission(
14798                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14799                    callingPid, callingUid, -1, true)
14800                    == PackageManager.PERMISSION_GRANTED) {
14801                if (uidRemoved) {
14802                    final Bundle intentExtras = intent.getExtras();
14803                    final int uid = intentExtras != null
14804                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14805                    if (uid >= 0) {
14806                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14807                        synchronized (bs) {
14808                            bs.removeUidStatsLocked(uid);
14809                        }
14810                        mAppOpsService.uidRemoved(uid);
14811                    }
14812                } else {
14813                    // If resources are unavailable just force stop all
14814                    // those packages and flush the attribute cache as well.
14815                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14816                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14817                        if (list != null && (list.length > 0)) {
14818                            for (String pkg : list) {
14819                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14820                                        "storage unmount");
14821                            }
14822                            sendPackageBroadcastLocked(
14823                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14824                        }
14825                    } else {
14826                        Uri data = intent.getData();
14827                        String ssp;
14828                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14829                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14830                                    intent.getAction());
14831                            boolean fullUninstall = removed &&
14832                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14833                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14834                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14835                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14836                                        false, fullUninstall, userId,
14837                                        removed ? "pkg removed" : "pkg changed");
14838                            }
14839                            if (removed) {
14840                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14841                                        new String[] {ssp}, userId);
14842                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14843                                    mAppOpsService.packageRemoved(
14844                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14845
14846                                    // Remove all permissions granted from/to this package
14847                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14848                                }
14849                            }
14850                        }
14851                    }
14852                }
14853            } else {
14854                String msg = "Permission Denial: " + intent.getAction()
14855                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14856                        + ", uid=" + callingUid + ")"
14857                        + " requires "
14858                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14859                Slog.w(TAG, msg);
14860                throw new SecurityException(msg);
14861            }
14862
14863        // Special case for adding a package: by default turn on compatibility
14864        // mode.
14865        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14866            Uri data = intent.getData();
14867            String ssp;
14868            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14869                mCompatModePackages.handlePackageAddedLocked(ssp,
14870                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14871            }
14872        }
14873
14874        /*
14875         * If this is the time zone changed action, queue up a message that will reset the timezone
14876         * of all currently running processes. This message will get queued up before the broadcast
14877         * happens.
14878         */
14879        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14880            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14881        }
14882
14883        /*
14884         * If the user set the time, let all running processes know.
14885         */
14886        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14887            final int is24Hour = intent.getBooleanExtra(
14888                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14889            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14890        }
14891
14892        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14893            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14894        }
14895
14896        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14897            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14898            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14899        }
14900
14901        // Add to the sticky list if requested.
14902        if (sticky) {
14903            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14904                    callingPid, callingUid)
14905                    != PackageManager.PERMISSION_GRANTED) {
14906                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14907                        + callingPid + ", uid=" + callingUid
14908                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14909                Slog.w(TAG, msg);
14910                throw new SecurityException(msg);
14911            }
14912            if (requiredPermission != null) {
14913                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14914                        + " and enforce permission " + requiredPermission);
14915                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14916            }
14917            if (intent.getComponent() != null) {
14918                throw new SecurityException(
14919                        "Sticky broadcasts can't target a specific component");
14920            }
14921            // We use userId directly here, since the "all" target is maintained
14922            // as a separate set of sticky broadcasts.
14923            if (userId != UserHandle.USER_ALL) {
14924                // But first, if this is not a broadcast to all users, then
14925                // make sure it doesn't conflict with an existing broadcast to
14926                // all users.
14927                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14928                        UserHandle.USER_ALL);
14929                if (stickies != null) {
14930                    ArrayList<Intent> list = stickies.get(intent.getAction());
14931                    if (list != null) {
14932                        int N = list.size();
14933                        int i;
14934                        for (i=0; i<N; i++) {
14935                            if (intent.filterEquals(list.get(i))) {
14936                                throw new IllegalArgumentException(
14937                                        "Sticky broadcast " + intent + " for user "
14938                                        + userId + " conflicts with existing global broadcast");
14939                            }
14940                        }
14941                    }
14942                }
14943            }
14944            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14945            if (stickies == null) {
14946                stickies = new ArrayMap<String, ArrayList<Intent>>();
14947                mStickyBroadcasts.put(userId, stickies);
14948            }
14949            ArrayList<Intent> list = stickies.get(intent.getAction());
14950            if (list == null) {
14951                list = new ArrayList<Intent>();
14952                stickies.put(intent.getAction(), list);
14953            }
14954            int N = list.size();
14955            int i;
14956            for (i=0; i<N; i++) {
14957                if (intent.filterEquals(list.get(i))) {
14958                    // This sticky already exists, replace it.
14959                    list.set(i, new Intent(intent));
14960                    break;
14961                }
14962            }
14963            if (i >= N) {
14964                list.add(new Intent(intent));
14965            }
14966        }
14967
14968        int[] users;
14969        if (userId == UserHandle.USER_ALL) {
14970            // Caller wants broadcast to go to all started users.
14971            users = mStartedUserArray;
14972        } else {
14973            // Caller wants broadcast to go to one specific user.
14974            users = new int[] {userId};
14975        }
14976
14977        // Figure out who all will receive this broadcast.
14978        List receivers = null;
14979        List<BroadcastFilter> registeredReceivers = null;
14980        // Need to resolve the intent to interested receivers...
14981        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14982                 == 0) {
14983            receivers = collectReceiverComponents(intent, resolvedType, users);
14984        }
14985        if (intent.getComponent() == null) {
14986            registeredReceivers = mReceiverResolver.queryIntent(intent,
14987                    resolvedType, false, userId);
14988        }
14989
14990        final boolean replacePending =
14991                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14992
14993        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14994                + " replacePending=" + replacePending);
14995
14996        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14997        if (!ordered && NR > 0) {
14998            // If we are not serializing this broadcast, then send the
14999            // registered receivers separately so they don't wait for the
15000            // components to be launched.
15001            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15002            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15003                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15004                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15005                    ordered, sticky, false, userId);
15006            if (DEBUG_BROADCAST) Slog.v(
15007                    TAG, "Enqueueing parallel broadcast " + r);
15008            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15009            if (!replaced) {
15010                queue.enqueueParallelBroadcastLocked(r);
15011                queue.scheduleBroadcastsLocked();
15012            }
15013            registeredReceivers = null;
15014            NR = 0;
15015        }
15016
15017        // Merge into one list.
15018        int ir = 0;
15019        if (receivers != null) {
15020            // A special case for PACKAGE_ADDED: do not allow the package
15021            // being added to see this broadcast.  This prevents them from
15022            // using this as a back door to get run as soon as they are
15023            // installed.  Maybe in the future we want to have a special install
15024            // broadcast or such for apps, but we'd like to deliberately make
15025            // this decision.
15026            String skipPackages[] = null;
15027            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15028                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15029                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15030                Uri data = intent.getData();
15031                if (data != null) {
15032                    String pkgName = data.getSchemeSpecificPart();
15033                    if (pkgName != null) {
15034                        skipPackages = new String[] { pkgName };
15035                    }
15036                }
15037            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15038                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15039            }
15040            if (skipPackages != null && (skipPackages.length > 0)) {
15041                for (String skipPackage : skipPackages) {
15042                    if (skipPackage != null) {
15043                        int NT = receivers.size();
15044                        for (int it=0; it<NT; it++) {
15045                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15046                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15047                                receivers.remove(it);
15048                                it--;
15049                                NT--;
15050                            }
15051                        }
15052                    }
15053                }
15054            }
15055
15056            int NT = receivers != null ? receivers.size() : 0;
15057            int it = 0;
15058            ResolveInfo curt = null;
15059            BroadcastFilter curr = null;
15060            while (it < NT && ir < NR) {
15061                if (curt == null) {
15062                    curt = (ResolveInfo)receivers.get(it);
15063                }
15064                if (curr == null) {
15065                    curr = registeredReceivers.get(ir);
15066                }
15067                if (curr.getPriority() >= curt.priority) {
15068                    // Insert this broadcast record into the final list.
15069                    receivers.add(it, curr);
15070                    ir++;
15071                    curr = null;
15072                    it++;
15073                    NT++;
15074                } else {
15075                    // Skip to the next ResolveInfo in the final list.
15076                    it++;
15077                    curt = null;
15078                }
15079            }
15080        }
15081        while (ir < NR) {
15082            if (receivers == null) {
15083                receivers = new ArrayList();
15084            }
15085            receivers.add(registeredReceivers.get(ir));
15086            ir++;
15087        }
15088
15089        if ((receivers != null && receivers.size() > 0)
15090                || resultTo != null) {
15091            BroadcastQueue queue = broadcastQueueForIntent(intent);
15092            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15093                    callerPackage, callingPid, callingUid, resolvedType,
15094                    requiredPermission, appOp, receivers, resultTo, resultCode,
15095                    resultData, map, ordered, sticky, false, userId);
15096            if (DEBUG_BROADCAST) Slog.v(
15097                    TAG, "Enqueueing ordered broadcast " + r
15098                    + ": prev had " + queue.mOrderedBroadcasts.size());
15099            if (DEBUG_BROADCAST) {
15100                int seq = r.intent.getIntExtra("seq", -1);
15101                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15102            }
15103            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15104            if (!replaced) {
15105                queue.enqueueOrderedBroadcastLocked(r);
15106                queue.scheduleBroadcastsLocked();
15107            }
15108        }
15109
15110        return ActivityManager.BROADCAST_SUCCESS;
15111    }
15112
15113    final Intent verifyBroadcastLocked(Intent intent) {
15114        // Refuse possible leaked file descriptors
15115        if (intent != null && intent.hasFileDescriptors() == true) {
15116            throw new IllegalArgumentException("File descriptors passed in Intent");
15117        }
15118
15119        int flags = intent.getFlags();
15120
15121        if (!mProcessesReady) {
15122            // if the caller really truly claims to know what they're doing, go
15123            // ahead and allow the broadcast without launching any receivers
15124            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15125                intent = new Intent(intent);
15126                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15127            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15128                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15129                        + " before boot completion");
15130                throw new IllegalStateException("Cannot broadcast before boot completed");
15131            }
15132        }
15133
15134        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15135            throw new IllegalArgumentException(
15136                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15137        }
15138
15139        return intent;
15140    }
15141
15142    public final int broadcastIntent(IApplicationThread caller,
15143            Intent intent, String resolvedType, IIntentReceiver resultTo,
15144            int resultCode, String resultData, Bundle map,
15145            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15146        enforceNotIsolatedCaller("broadcastIntent");
15147        synchronized(this) {
15148            intent = verifyBroadcastLocked(intent);
15149
15150            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15151            final int callingPid = Binder.getCallingPid();
15152            final int callingUid = Binder.getCallingUid();
15153            final long origId = Binder.clearCallingIdentity();
15154            int res = broadcastIntentLocked(callerApp,
15155                    callerApp != null ? callerApp.info.packageName : null,
15156                    intent, resolvedType, resultTo,
15157                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15158                    callingPid, callingUid, userId);
15159            Binder.restoreCallingIdentity(origId);
15160            return res;
15161        }
15162    }
15163
15164    int broadcastIntentInPackage(String packageName, int uid,
15165            Intent intent, String resolvedType, IIntentReceiver resultTo,
15166            int resultCode, String resultData, Bundle map,
15167            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15168        synchronized(this) {
15169            intent = verifyBroadcastLocked(intent);
15170
15171            final long origId = Binder.clearCallingIdentity();
15172            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15173                    resultTo, resultCode, resultData, map, requiredPermission,
15174                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15175            Binder.restoreCallingIdentity(origId);
15176            return res;
15177        }
15178    }
15179
15180    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15181        // Refuse possible leaked file descriptors
15182        if (intent != null && intent.hasFileDescriptors() == true) {
15183            throw new IllegalArgumentException("File descriptors passed in Intent");
15184        }
15185
15186        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15187                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15188
15189        synchronized(this) {
15190            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15191                    != PackageManager.PERMISSION_GRANTED) {
15192                String msg = "Permission Denial: unbroadcastIntent() from pid="
15193                        + Binder.getCallingPid()
15194                        + ", uid=" + Binder.getCallingUid()
15195                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15196                Slog.w(TAG, msg);
15197                throw new SecurityException(msg);
15198            }
15199            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15200            if (stickies != null) {
15201                ArrayList<Intent> list = stickies.get(intent.getAction());
15202                if (list != null) {
15203                    int N = list.size();
15204                    int i;
15205                    for (i=0; i<N; i++) {
15206                        if (intent.filterEquals(list.get(i))) {
15207                            list.remove(i);
15208                            break;
15209                        }
15210                    }
15211                    if (list.size() <= 0) {
15212                        stickies.remove(intent.getAction());
15213                    }
15214                }
15215                if (stickies.size() <= 0) {
15216                    mStickyBroadcasts.remove(userId);
15217                }
15218            }
15219        }
15220    }
15221
15222    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15223            String resultData, Bundle resultExtras, boolean resultAbort) {
15224        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15225        if (r == null) {
15226            Slog.w(TAG, "finishReceiver called but not found on queue");
15227            return false;
15228        }
15229
15230        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15231    }
15232
15233    void backgroundServicesFinishedLocked(int userId) {
15234        for (BroadcastQueue queue : mBroadcastQueues) {
15235            queue.backgroundServicesFinishedLocked(userId);
15236        }
15237    }
15238
15239    public void finishReceiver(IBinder who, int resultCode, String resultData,
15240            Bundle resultExtras, boolean resultAbort) {
15241        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15242
15243        // Refuse possible leaked file descriptors
15244        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15245            throw new IllegalArgumentException("File descriptors passed in Bundle");
15246        }
15247
15248        final long origId = Binder.clearCallingIdentity();
15249        try {
15250            boolean doNext = false;
15251            BroadcastRecord r;
15252
15253            synchronized(this) {
15254                r = broadcastRecordForReceiverLocked(who);
15255                if (r != null) {
15256                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15257                        resultData, resultExtras, resultAbort, true);
15258                }
15259            }
15260
15261            if (doNext) {
15262                r.queue.processNextBroadcast(false);
15263            }
15264            trimApplications();
15265        } finally {
15266            Binder.restoreCallingIdentity(origId);
15267        }
15268    }
15269
15270    // =========================================================
15271    // INSTRUMENTATION
15272    // =========================================================
15273
15274    public boolean startInstrumentation(ComponentName className,
15275            String profileFile, int flags, Bundle arguments,
15276            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15277            int userId, String abiOverride) {
15278        enforceNotIsolatedCaller("startInstrumentation");
15279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15280                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15281        // Refuse possible leaked file descriptors
15282        if (arguments != null && arguments.hasFileDescriptors()) {
15283            throw new IllegalArgumentException("File descriptors passed in Bundle");
15284        }
15285
15286        synchronized(this) {
15287            InstrumentationInfo ii = null;
15288            ApplicationInfo ai = null;
15289            try {
15290                ii = mContext.getPackageManager().getInstrumentationInfo(
15291                    className, STOCK_PM_FLAGS);
15292                ai = AppGlobals.getPackageManager().getApplicationInfo(
15293                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15294            } catch (PackageManager.NameNotFoundException e) {
15295            } catch (RemoteException e) {
15296            }
15297            if (ii == null) {
15298                reportStartInstrumentationFailure(watcher, className,
15299                        "Unable to find instrumentation info for: " + className);
15300                return false;
15301            }
15302            if (ai == null) {
15303                reportStartInstrumentationFailure(watcher, className,
15304                        "Unable to find instrumentation target package: " + ii.targetPackage);
15305                return false;
15306            }
15307
15308            int match = mContext.getPackageManager().checkSignatures(
15309                    ii.targetPackage, ii.packageName);
15310            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15311                String msg = "Permission Denial: starting instrumentation "
15312                        + className + " from pid="
15313                        + Binder.getCallingPid()
15314                        + ", uid=" + Binder.getCallingPid()
15315                        + " not allowed because package " + ii.packageName
15316                        + " does not have a signature matching the target "
15317                        + ii.targetPackage;
15318                reportStartInstrumentationFailure(watcher, className, msg);
15319                throw new SecurityException(msg);
15320            }
15321
15322            final long origId = Binder.clearCallingIdentity();
15323            // Instrumentation can kill and relaunch even persistent processes
15324            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15325                    "start instr");
15326            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15327            app.instrumentationClass = className;
15328            app.instrumentationInfo = ai;
15329            app.instrumentationProfileFile = profileFile;
15330            app.instrumentationArguments = arguments;
15331            app.instrumentationWatcher = watcher;
15332            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15333            app.instrumentationResultClass = className;
15334            Binder.restoreCallingIdentity(origId);
15335        }
15336
15337        return true;
15338    }
15339
15340    /**
15341     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15342     * error to the logs, but if somebody is watching, send the report there too.  This enables
15343     * the "am" command to report errors with more information.
15344     *
15345     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15346     * @param cn The component name of the instrumentation.
15347     * @param report The error report.
15348     */
15349    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15350            ComponentName cn, String report) {
15351        Slog.w(TAG, report);
15352        try {
15353            if (watcher != null) {
15354                Bundle results = new Bundle();
15355                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15356                results.putString("Error", report);
15357                watcher.instrumentationStatus(cn, -1, results);
15358            }
15359        } catch (RemoteException e) {
15360            Slog.w(TAG, e);
15361        }
15362    }
15363
15364    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15365        if (app.instrumentationWatcher != null) {
15366            try {
15367                // NOTE:  IInstrumentationWatcher *must* be oneway here
15368                app.instrumentationWatcher.instrumentationFinished(
15369                    app.instrumentationClass,
15370                    resultCode,
15371                    results);
15372            } catch (RemoteException e) {
15373            }
15374        }
15375        if (app.instrumentationUiAutomationConnection != null) {
15376            try {
15377                app.instrumentationUiAutomationConnection.shutdown();
15378            } catch (RemoteException re) {
15379                /* ignore */
15380            }
15381            // Only a UiAutomation can set this flag and now that
15382            // it is finished we make sure it is reset to its default.
15383            mUserIsMonkey = false;
15384        }
15385        app.instrumentationWatcher = null;
15386        app.instrumentationUiAutomationConnection = null;
15387        app.instrumentationClass = null;
15388        app.instrumentationInfo = null;
15389        app.instrumentationProfileFile = null;
15390        app.instrumentationArguments = null;
15391
15392        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15393                "finished inst");
15394    }
15395
15396    public void finishInstrumentation(IApplicationThread target,
15397            int resultCode, Bundle results) {
15398        int userId = UserHandle.getCallingUserId();
15399        // Refuse possible leaked file descriptors
15400        if (results != null && results.hasFileDescriptors()) {
15401            throw new IllegalArgumentException("File descriptors passed in Intent");
15402        }
15403
15404        synchronized(this) {
15405            ProcessRecord app = getRecordForAppLocked(target);
15406            if (app == null) {
15407                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15408                return;
15409            }
15410            final long origId = Binder.clearCallingIdentity();
15411            finishInstrumentationLocked(app, resultCode, results);
15412            Binder.restoreCallingIdentity(origId);
15413        }
15414    }
15415
15416    // =========================================================
15417    // CONFIGURATION
15418    // =========================================================
15419
15420    public ConfigurationInfo getDeviceConfigurationInfo() {
15421        ConfigurationInfo config = new ConfigurationInfo();
15422        synchronized (this) {
15423            config.reqTouchScreen = mConfiguration.touchscreen;
15424            config.reqKeyboardType = mConfiguration.keyboard;
15425            config.reqNavigation = mConfiguration.navigation;
15426            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15427                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15428                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15429            }
15430            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15431                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15432                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15433            }
15434            config.reqGlEsVersion = GL_ES_VERSION;
15435        }
15436        return config;
15437    }
15438
15439    ActivityStack getFocusedStack() {
15440        return mStackSupervisor.getFocusedStack();
15441    }
15442
15443    public Configuration getConfiguration() {
15444        Configuration ci;
15445        synchronized(this) {
15446            ci = new Configuration(mConfiguration);
15447        }
15448        return ci;
15449    }
15450
15451    public void updatePersistentConfiguration(Configuration values) {
15452        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15453                "updateConfiguration()");
15454        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15455                "updateConfiguration()");
15456        if (values == null) {
15457            throw new NullPointerException("Configuration must not be null");
15458        }
15459
15460        synchronized(this) {
15461            final long origId = Binder.clearCallingIdentity();
15462            updateConfigurationLocked(values, null, true, false);
15463            Binder.restoreCallingIdentity(origId);
15464        }
15465    }
15466
15467    public void updateConfiguration(Configuration values) {
15468        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15469                "updateConfiguration()");
15470
15471        synchronized(this) {
15472            if (values == null && mWindowManager != null) {
15473                // sentinel: fetch the current configuration from the window manager
15474                values = mWindowManager.computeNewConfiguration();
15475            }
15476
15477            if (mWindowManager != null) {
15478                mProcessList.applyDisplaySize(mWindowManager);
15479            }
15480
15481            final long origId = Binder.clearCallingIdentity();
15482            if (values != null) {
15483                Settings.System.clearConfiguration(values);
15484            }
15485            updateConfigurationLocked(values, null, false, false);
15486            Binder.restoreCallingIdentity(origId);
15487        }
15488    }
15489
15490    /**
15491     * Do either or both things: (1) change the current configuration, and (2)
15492     * make sure the given activity is running with the (now) current
15493     * configuration.  Returns true if the activity has been left running, or
15494     * false if <var>starting</var> is being destroyed to match the new
15495     * configuration.
15496     * @param persistent TODO
15497     */
15498    boolean updateConfigurationLocked(Configuration values,
15499            ActivityRecord starting, boolean persistent, boolean initLocale) {
15500        int changes = 0;
15501
15502        if (values != null) {
15503            Configuration newConfig = new Configuration(mConfiguration);
15504            changes = newConfig.updateFrom(values);
15505            if (changes != 0) {
15506                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15507                    Slog.i(TAG, "Updating configuration to: " + values);
15508                }
15509
15510                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15511
15512                if (values.locale != null && !initLocale) {
15513                    saveLocaleLocked(values.locale,
15514                                     !values.locale.equals(mConfiguration.locale),
15515                                     values.userSetLocale);
15516                }
15517
15518                mConfigurationSeq++;
15519                if (mConfigurationSeq <= 0) {
15520                    mConfigurationSeq = 1;
15521                }
15522                newConfig.seq = mConfigurationSeq;
15523                mConfiguration = newConfig;
15524                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15525                //mUsageStatsService.noteStartConfig(newConfig);
15526
15527                final Configuration configCopy = new Configuration(mConfiguration);
15528
15529                // TODO: If our config changes, should we auto dismiss any currently
15530                // showing dialogs?
15531                mShowDialogs = shouldShowDialogs(newConfig);
15532
15533                AttributeCache ac = AttributeCache.instance();
15534                if (ac != null) {
15535                    ac.updateConfiguration(configCopy);
15536                }
15537
15538                // Make sure all resources in our process are updated
15539                // right now, so that anyone who is going to retrieve
15540                // resource values after we return will be sure to get
15541                // the new ones.  This is especially important during
15542                // boot, where the first config change needs to guarantee
15543                // all resources have that config before following boot
15544                // code is executed.
15545                mSystemThread.applyConfigurationToResources(configCopy);
15546
15547                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15548                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15549                    msg.obj = new Configuration(configCopy);
15550                    mHandler.sendMessage(msg);
15551                }
15552
15553                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15554                    ProcessRecord app = mLruProcesses.get(i);
15555                    try {
15556                        if (app.thread != null) {
15557                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15558                                    + app.processName + " new config " + mConfiguration);
15559                            app.thread.scheduleConfigurationChanged(configCopy);
15560                        }
15561                    } catch (Exception e) {
15562                    }
15563                }
15564                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15565                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15566                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15567                        | Intent.FLAG_RECEIVER_FOREGROUND);
15568                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15569                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15570                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15571                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15572                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15573                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15574                    broadcastIntentLocked(null, null, intent,
15575                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15576                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15577                }
15578            }
15579        }
15580
15581        boolean kept = true;
15582        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15583        // mainStack is null during startup.
15584        if (mainStack != null) {
15585            if (changes != 0 && starting == null) {
15586                // If the configuration changed, and the caller is not already
15587                // in the process of starting an activity, then find the top
15588                // activity to check if its configuration needs to change.
15589                starting = mainStack.topRunningActivityLocked(null);
15590            }
15591
15592            if (starting != null) {
15593                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15594                // And we need to make sure at this point that all other activities
15595                // are made visible with the correct configuration.
15596                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15597            }
15598        }
15599
15600        if (values != null && mWindowManager != null) {
15601            mWindowManager.setNewConfiguration(mConfiguration);
15602        }
15603
15604        return kept;
15605    }
15606
15607    /**
15608     * Decide based on the configuration whether we should shouw the ANR,
15609     * crash, etc dialogs.  The idea is that if there is no affordnace to
15610     * press the on-screen buttons, we shouldn't show the dialog.
15611     *
15612     * A thought: SystemUI might also want to get told about this, the Power
15613     * dialog / global actions also might want different behaviors.
15614     */
15615    private static final boolean shouldShowDialogs(Configuration config) {
15616        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15617                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15618    }
15619
15620    /**
15621     * Save the locale.  You must be inside a synchronized (this) block.
15622     */
15623    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15624        if(isDiff) {
15625            SystemProperties.set("user.language", l.getLanguage());
15626            SystemProperties.set("user.region", l.getCountry());
15627        }
15628
15629        if(isPersist) {
15630            SystemProperties.set("persist.sys.language", l.getLanguage());
15631            SystemProperties.set("persist.sys.country", l.getCountry());
15632            SystemProperties.set("persist.sys.localevar", l.getVariant());
15633        }
15634    }
15635
15636    @Override
15637    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15638        synchronized (this) {
15639            ActivityRecord srec = ActivityRecord.forToken(token);
15640            if (srec.task != null && srec.task.stack != null) {
15641                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15642            }
15643        }
15644        return false;
15645    }
15646
15647    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15648            Intent resultData) {
15649
15650        synchronized (this) {
15651            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15652            if (stack != null) {
15653                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15654            }
15655            return false;
15656        }
15657    }
15658
15659    public int getLaunchedFromUid(IBinder activityToken) {
15660        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15661        if (srec == null) {
15662            return -1;
15663        }
15664        return srec.launchedFromUid;
15665    }
15666
15667    public String getLaunchedFromPackage(IBinder activityToken) {
15668        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15669        if (srec == null) {
15670            return null;
15671        }
15672        return srec.launchedFromPackage;
15673    }
15674
15675    // =========================================================
15676    // LIFETIME MANAGEMENT
15677    // =========================================================
15678
15679    // Returns which broadcast queue the app is the current [or imminent] receiver
15680    // on, or 'null' if the app is not an active broadcast recipient.
15681    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15682        BroadcastRecord r = app.curReceiver;
15683        if (r != null) {
15684            return r.queue;
15685        }
15686
15687        // It's not the current receiver, but it might be starting up to become one
15688        synchronized (this) {
15689            for (BroadcastQueue queue : mBroadcastQueues) {
15690                r = queue.mPendingBroadcast;
15691                if (r != null && r.curApp == app) {
15692                    // found it; report which queue it's in
15693                    return queue;
15694                }
15695            }
15696        }
15697
15698        return null;
15699    }
15700
15701    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15702            boolean doingAll, long now) {
15703        if (mAdjSeq == app.adjSeq) {
15704            // This adjustment has already been computed.
15705            return app.curRawAdj;
15706        }
15707
15708        if (app.thread == null) {
15709            app.adjSeq = mAdjSeq;
15710            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15711            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15712            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15713        }
15714
15715        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15716        app.adjSource = null;
15717        app.adjTarget = null;
15718        app.empty = false;
15719        app.cached = false;
15720
15721        final int activitiesSize = app.activities.size();
15722
15723        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15724            // The max adjustment doesn't allow this app to be anything
15725            // below foreground, so it is not worth doing work for it.
15726            app.adjType = "fixed";
15727            app.adjSeq = mAdjSeq;
15728            app.curRawAdj = app.maxAdj;
15729            app.foregroundActivities = false;
15730            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15731            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15732            // System processes can do UI, and when they do we want to have
15733            // them trim their memory after the user leaves the UI.  To
15734            // facilitate this, here we need to determine whether or not it
15735            // is currently showing UI.
15736            app.systemNoUi = true;
15737            if (app == TOP_APP) {
15738                app.systemNoUi = false;
15739            } else if (activitiesSize > 0) {
15740                for (int j = 0; j < activitiesSize; j++) {
15741                    final ActivityRecord r = app.activities.get(j);
15742                    if (r.visible) {
15743                        app.systemNoUi = false;
15744                    }
15745                }
15746            }
15747            if (!app.systemNoUi) {
15748                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15749            }
15750            return (app.curAdj=app.maxAdj);
15751        }
15752
15753        app.systemNoUi = false;
15754
15755        // Determine the importance of the process, starting with most
15756        // important to least, and assign an appropriate OOM adjustment.
15757        int adj;
15758        int schedGroup;
15759        int procState;
15760        boolean foregroundActivities = false;
15761        BroadcastQueue queue;
15762        if (app == TOP_APP) {
15763            // The last app on the list is the foreground app.
15764            adj = ProcessList.FOREGROUND_APP_ADJ;
15765            schedGroup = Process.THREAD_GROUP_DEFAULT;
15766            app.adjType = "top-activity";
15767            foregroundActivities = true;
15768            procState = ActivityManager.PROCESS_STATE_TOP;
15769        } else if (app.instrumentationClass != null) {
15770            // Don't want to kill running instrumentation.
15771            adj = ProcessList.FOREGROUND_APP_ADJ;
15772            schedGroup = Process.THREAD_GROUP_DEFAULT;
15773            app.adjType = "instrumentation";
15774            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15775        } else if ((queue = isReceivingBroadcast(app)) != null) {
15776            // An app that is currently receiving a broadcast also
15777            // counts as being in the foreground for OOM killer purposes.
15778            // It's placed in a sched group based on the nature of the
15779            // broadcast as reflected by which queue it's active in.
15780            adj = ProcessList.FOREGROUND_APP_ADJ;
15781            schedGroup = (queue == mFgBroadcastQueue)
15782                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15783            app.adjType = "broadcast";
15784            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15785        } else if (app.executingServices.size() > 0) {
15786            // An app that is currently executing a service callback also
15787            // counts as being in the foreground.
15788            adj = ProcessList.FOREGROUND_APP_ADJ;
15789            schedGroup = app.execServicesFg ?
15790                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15791            app.adjType = "exec-service";
15792            procState = ActivityManager.PROCESS_STATE_SERVICE;
15793            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15794        } else {
15795            // As far as we know the process is empty.  We may change our mind later.
15796            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15797            // At this point we don't actually know the adjustment.  Use the cached adj
15798            // value that the caller wants us to.
15799            adj = cachedAdj;
15800            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15801            app.cached = true;
15802            app.empty = true;
15803            app.adjType = "cch-empty";
15804        }
15805
15806        // Examine all activities if not already foreground.
15807        if (!foregroundActivities && activitiesSize > 0) {
15808            for (int j = 0; j < activitiesSize; j++) {
15809                final ActivityRecord r = app.activities.get(j);
15810                if (r.app != app) {
15811                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15812                            + app + "?!?");
15813                    continue;
15814                }
15815                if (r.visible) {
15816                    // App has a visible activity; only upgrade adjustment.
15817                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15818                        adj = ProcessList.VISIBLE_APP_ADJ;
15819                        app.adjType = "visible";
15820                    }
15821                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15822                        procState = ActivityManager.PROCESS_STATE_TOP;
15823                    }
15824                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15825                    app.cached = false;
15826                    app.empty = false;
15827                    foregroundActivities = true;
15828                    break;
15829                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15830                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15831                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15832                        app.adjType = "pausing";
15833                    }
15834                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15835                        procState = ActivityManager.PROCESS_STATE_TOP;
15836                    }
15837                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15838                    app.cached = false;
15839                    app.empty = false;
15840                    foregroundActivities = true;
15841                } else if (r.state == ActivityState.STOPPING) {
15842                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15843                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15844                        app.adjType = "stopping";
15845                    }
15846                    // For the process state, we will at this point consider the
15847                    // process to be cached.  It will be cached either as an activity
15848                    // or empty depending on whether the activity is finishing.  We do
15849                    // this so that we can treat the process as cached for purposes of
15850                    // memory trimming (determing current memory level, trim command to
15851                    // send to process) since there can be an arbitrary number of stopping
15852                    // processes and they should soon all go into the cached state.
15853                    if (!r.finishing) {
15854                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15855                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15856                        }
15857                    }
15858                    app.cached = false;
15859                    app.empty = false;
15860                    foregroundActivities = true;
15861                } else {
15862                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15863                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15864                        app.adjType = "cch-act";
15865                    }
15866                }
15867            }
15868        }
15869
15870        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15871            if (app.foregroundServices) {
15872                // The user is aware of this app, so make it visible.
15873                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15874                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15875                app.cached = false;
15876                app.adjType = "fg-service";
15877                schedGroup = Process.THREAD_GROUP_DEFAULT;
15878            } else if (app.forcingToForeground != null) {
15879                // The user is aware of this app, so make it visible.
15880                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15881                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15882                app.cached = false;
15883                app.adjType = "force-fg";
15884                app.adjSource = app.forcingToForeground;
15885                schedGroup = Process.THREAD_GROUP_DEFAULT;
15886            }
15887        }
15888
15889        if (app == mHeavyWeightProcess) {
15890            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15891                // We don't want to kill the current heavy-weight process.
15892                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15893                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15894                app.cached = false;
15895                app.adjType = "heavy";
15896            }
15897            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15898                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15899            }
15900        }
15901
15902        if (app == mHomeProcess) {
15903            if (adj > ProcessList.HOME_APP_ADJ) {
15904                // This process is hosting what we currently consider to be the
15905                // home app, so we don't want to let it go into the background.
15906                adj = ProcessList.HOME_APP_ADJ;
15907                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15908                app.cached = false;
15909                app.adjType = "home";
15910            }
15911            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15912                procState = ActivityManager.PROCESS_STATE_HOME;
15913            }
15914        }
15915
15916        if (app == mPreviousProcess && app.activities.size() > 0) {
15917            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15918                // This was the previous process that showed UI to the user.
15919                // We want to try to keep it around more aggressively, to give
15920                // a good experience around switching between two apps.
15921                adj = ProcessList.PREVIOUS_APP_ADJ;
15922                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15923                app.cached = false;
15924                app.adjType = "previous";
15925            }
15926            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15927                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15928            }
15929        }
15930
15931        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15932                + " reason=" + app.adjType);
15933
15934        // By default, we use the computed adjustment.  It may be changed if
15935        // there are applications dependent on our services or providers, but
15936        // this gives us a baseline and makes sure we don't get into an
15937        // infinite recursion.
15938        app.adjSeq = mAdjSeq;
15939        app.curRawAdj = adj;
15940        app.hasStartedServices = false;
15941
15942        if (mBackupTarget != null && app == mBackupTarget.app) {
15943            // If possible we want to avoid killing apps while they're being backed up
15944            if (adj > ProcessList.BACKUP_APP_ADJ) {
15945                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15946                adj = ProcessList.BACKUP_APP_ADJ;
15947                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15948                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15949                }
15950                app.adjType = "backup";
15951                app.cached = false;
15952            }
15953            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15954                procState = ActivityManager.PROCESS_STATE_BACKUP;
15955            }
15956        }
15957
15958        boolean mayBeTop = false;
15959
15960        for (int is = app.services.size()-1;
15961                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15962                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15963                        || procState > ActivityManager.PROCESS_STATE_TOP);
15964                is--) {
15965            ServiceRecord s = app.services.valueAt(is);
15966            if (s.startRequested) {
15967                app.hasStartedServices = true;
15968                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15969                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15970                }
15971                if (app.hasShownUi && app != mHomeProcess) {
15972                    // If this process has shown some UI, let it immediately
15973                    // go to the LRU list because it may be pretty heavy with
15974                    // UI stuff.  We'll tag it with a label just to help
15975                    // debug and understand what is going on.
15976                    if (adj > ProcessList.SERVICE_ADJ) {
15977                        app.adjType = "cch-started-ui-services";
15978                    }
15979                } else {
15980                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15981                        // This service has seen some activity within
15982                        // recent memory, so we will keep its process ahead
15983                        // of the background processes.
15984                        if (adj > ProcessList.SERVICE_ADJ) {
15985                            adj = ProcessList.SERVICE_ADJ;
15986                            app.adjType = "started-services";
15987                            app.cached = false;
15988                        }
15989                    }
15990                    // If we have let the service slide into the background
15991                    // state, still have some text describing what it is doing
15992                    // even though the service no longer has an impact.
15993                    if (adj > ProcessList.SERVICE_ADJ) {
15994                        app.adjType = "cch-started-services";
15995                    }
15996                }
15997            }
15998            for (int conni = s.connections.size()-1;
15999                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16000                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16001                            || procState > ActivityManager.PROCESS_STATE_TOP);
16002                    conni--) {
16003                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16004                for (int i = 0;
16005                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16006                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16007                                || procState > ActivityManager.PROCESS_STATE_TOP);
16008                        i++) {
16009                    // XXX should compute this based on the max of
16010                    // all connected clients.
16011                    ConnectionRecord cr = clist.get(i);
16012                    if (cr.binding.client == app) {
16013                        // Binding to ourself is not interesting.
16014                        continue;
16015                    }
16016                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16017                        ProcessRecord client = cr.binding.client;
16018                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16019                                TOP_APP, doingAll, now);
16020                        int clientProcState = client.curProcState;
16021                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16022                            // If the other app is cached for any reason, for purposes here
16023                            // we are going to consider it empty.  The specific cached state
16024                            // doesn't propagate except under certain conditions.
16025                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16026                        }
16027                        String adjType = null;
16028                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16029                            // Not doing bind OOM management, so treat
16030                            // this guy more like a started service.
16031                            if (app.hasShownUi && app != mHomeProcess) {
16032                                // If this process has shown some UI, let it immediately
16033                                // go to the LRU list because it may be pretty heavy with
16034                                // UI stuff.  We'll tag it with a label just to help
16035                                // debug and understand what is going on.
16036                                if (adj > clientAdj) {
16037                                    adjType = "cch-bound-ui-services";
16038                                }
16039                                app.cached = false;
16040                                clientAdj = adj;
16041                                clientProcState = procState;
16042                            } else {
16043                                if (now >= (s.lastActivity
16044                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16045                                    // This service has not seen activity within
16046                                    // recent memory, so allow it to drop to the
16047                                    // LRU list if there is no other reason to keep
16048                                    // it around.  We'll also tag it with a label just
16049                                    // to help debug and undertand what is going on.
16050                                    if (adj > clientAdj) {
16051                                        adjType = "cch-bound-services";
16052                                    }
16053                                    clientAdj = adj;
16054                                }
16055                            }
16056                        }
16057                        if (adj > clientAdj) {
16058                            // If this process has recently shown UI, and
16059                            // the process that is binding to it is less
16060                            // important than being visible, then we don't
16061                            // care about the binding as much as we care
16062                            // about letting this process get into the LRU
16063                            // list to be killed and restarted if needed for
16064                            // memory.
16065                            if (app.hasShownUi && app != mHomeProcess
16066                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16067                                adjType = "cch-bound-ui-services";
16068                            } else {
16069                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16070                                        |Context.BIND_IMPORTANT)) != 0) {
16071                                    adj = clientAdj;
16072                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16073                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16074                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16075                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16076                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16077                                    adj = clientAdj;
16078                                } else {
16079                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16080                                        adj = ProcessList.VISIBLE_APP_ADJ;
16081                                    }
16082                                }
16083                                if (!client.cached) {
16084                                    app.cached = false;
16085                                }
16086                                adjType = "service";
16087                            }
16088                        }
16089                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16090                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16091                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16092                            }
16093                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16094                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16095                                    // Special handling of clients who are in the top state.
16096                                    // We *may* want to consider this process to be in the
16097                                    // top state as well, but only if there is not another
16098                                    // reason for it to be running.  Being on the top is a
16099                                    // special state, meaning you are specifically running
16100                                    // for the current top app.  If the process is already
16101                                    // running in the background for some other reason, it
16102                                    // is more important to continue considering it to be
16103                                    // in the background state.
16104                                    mayBeTop = true;
16105                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16106                                } else {
16107                                    // Special handling for above-top states (persistent
16108                                    // processes).  These should not bring the current process
16109                                    // into the top state, since they are not on top.  Instead
16110                                    // give them the best state after that.
16111                                    clientProcState =
16112                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16113                                }
16114                            }
16115                        } else {
16116                            if (clientProcState <
16117                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16118                                clientProcState =
16119                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16120                            }
16121                        }
16122                        if (procState > clientProcState) {
16123                            procState = clientProcState;
16124                        }
16125                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16126                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16127                            app.pendingUiClean = true;
16128                        }
16129                        if (adjType != null) {
16130                            app.adjType = adjType;
16131                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16132                                    .REASON_SERVICE_IN_USE;
16133                            app.adjSource = cr.binding.client;
16134                            app.adjSourceProcState = clientProcState;
16135                            app.adjTarget = s.name;
16136                        }
16137                    }
16138                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16139                        app.treatLikeActivity = true;
16140                    }
16141                    final ActivityRecord a = cr.activity;
16142                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16143                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16144                                (a.visible || a.state == ActivityState.RESUMED
16145                                 || a.state == ActivityState.PAUSING)) {
16146                            adj = ProcessList.FOREGROUND_APP_ADJ;
16147                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16148                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16149                            }
16150                            app.cached = false;
16151                            app.adjType = "service";
16152                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16153                                    .REASON_SERVICE_IN_USE;
16154                            app.adjSource = a;
16155                            app.adjSourceProcState = procState;
16156                            app.adjTarget = s.name;
16157                        }
16158                    }
16159                }
16160            }
16161        }
16162
16163        for (int provi = app.pubProviders.size()-1;
16164                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16165                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16166                        || procState > ActivityManager.PROCESS_STATE_TOP);
16167                provi--) {
16168            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16169            for (int i = cpr.connections.size()-1;
16170                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16171                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16172                            || procState > ActivityManager.PROCESS_STATE_TOP);
16173                    i--) {
16174                ContentProviderConnection conn = cpr.connections.get(i);
16175                ProcessRecord client = conn.client;
16176                if (client == app) {
16177                    // Being our own client is not interesting.
16178                    continue;
16179                }
16180                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16181                int clientProcState = client.curProcState;
16182                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16183                    // If the other app is cached for any reason, for purposes here
16184                    // we are going to consider it empty.
16185                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16186                }
16187                if (adj > clientAdj) {
16188                    if (app.hasShownUi && app != mHomeProcess
16189                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16190                        app.adjType = "cch-ui-provider";
16191                    } else {
16192                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16193                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16194                        app.adjType = "provider";
16195                    }
16196                    app.cached &= client.cached;
16197                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16198                            .REASON_PROVIDER_IN_USE;
16199                    app.adjSource = client;
16200                    app.adjSourceProcState = clientProcState;
16201                    app.adjTarget = cpr.name;
16202                }
16203                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16204                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16205                        // Special handling of clients who are in the top state.
16206                        // We *may* want to consider this process to be in the
16207                        // top state as well, but only if there is not another
16208                        // reason for it to be running.  Being on the top is a
16209                        // special state, meaning you are specifically running
16210                        // for the current top app.  If the process is already
16211                        // running in the background for some other reason, it
16212                        // is more important to continue considering it to be
16213                        // in the background state.
16214                        mayBeTop = true;
16215                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16216                    } else {
16217                        // Special handling for above-top states (persistent
16218                        // processes).  These should not bring the current process
16219                        // into the top state, since they are not on top.  Instead
16220                        // give them the best state after that.
16221                        clientProcState =
16222                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16223                    }
16224                }
16225                if (procState > clientProcState) {
16226                    procState = clientProcState;
16227                }
16228                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16229                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16230                }
16231            }
16232            // If the provider has external (non-framework) process
16233            // dependencies, ensure that its adjustment is at least
16234            // FOREGROUND_APP_ADJ.
16235            if (cpr.hasExternalProcessHandles()) {
16236                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16237                    adj = ProcessList.FOREGROUND_APP_ADJ;
16238                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16239                    app.cached = false;
16240                    app.adjType = "provider";
16241                    app.adjTarget = cpr.name;
16242                }
16243                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16244                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16245                }
16246            }
16247        }
16248
16249        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16250            // A client of one of our services or providers is in the top state.  We
16251            // *may* want to be in the top state, but not if we are already running in
16252            // the background for some other reason.  For the decision here, we are going
16253            // to pick out a few specific states that we want to remain in when a client
16254            // is top (states that tend to be longer-term) and otherwise allow it to go
16255            // to the top state.
16256            switch (procState) {
16257                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16258                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16259                case ActivityManager.PROCESS_STATE_SERVICE:
16260                    // These all are longer-term states, so pull them up to the top
16261                    // of the background states, but not all the way to the top state.
16262                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16263                    break;
16264                default:
16265                    // Otherwise, top is a better choice, so take it.
16266                    procState = ActivityManager.PROCESS_STATE_TOP;
16267                    break;
16268            }
16269        }
16270
16271        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16272            if (app.hasClientActivities) {
16273                // This is a cached process, but with client activities.  Mark it so.
16274                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16275                app.adjType = "cch-client-act";
16276            } else if (app.treatLikeActivity) {
16277                // This is a cached process, but somebody wants us to treat it like it has
16278                // an activity, okay!
16279                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16280                app.adjType = "cch-as-act";
16281            }
16282        }
16283
16284        if (adj == ProcessList.SERVICE_ADJ) {
16285            if (doingAll) {
16286                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16287                mNewNumServiceProcs++;
16288                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16289                if (!app.serviceb) {
16290                    // This service isn't far enough down on the LRU list to
16291                    // normally be a B service, but if we are low on RAM and it
16292                    // is large we want to force it down since we would prefer to
16293                    // keep launcher over it.
16294                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16295                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16296                        app.serviceHighRam = true;
16297                        app.serviceb = true;
16298                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16299                    } else {
16300                        mNewNumAServiceProcs++;
16301                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16302                    }
16303                } else {
16304                    app.serviceHighRam = false;
16305                }
16306            }
16307            if (app.serviceb) {
16308                adj = ProcessList.SERVICE_B_ADJ;
16309            }
16310        }
16311
16312        app.curRawAdj = adj;
16313
16314        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16315        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16316        if (adj > app.maxAdj) {
16317            adj = app.maxAdj;
16318            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16319                schedGroup = Process.THREAD_GROUP_DEFAULT;
16320            }
16321        }
16322
16323        // Do final modification to adj.  Everything we do between here and applying
16324        // the final setAdj must be done in this function, because we will also use
16325        // it when computing the final cached adj later.  Note that we don't need to
16326        // worry about this for max adj above, since max adj will always be used to
16327        // keep it out of the cached vaues.
16328        app.curAdj = app.modifyRawOomAdj(adj);
16329        app.curSchedGroup = schedGroup;
16330        app.curProcState = procState;
16331        app.foregroundActivities = foregroundActivities;
16332
16333        return app.curRawAdj;
16334    }
16335
16336    /**
16337     * Schedule PSS collection of a process.
16338     */
16339    void requestPssLocked(ProcessRecord proc, int procState) {
16340        if (mPendingPssProcesses.contains(proc)) {
16341            return;
16342        }
16343        if (mPendingPssProcesses.size() == 0) {
16344            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16345        }
16346        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16347        proc.pssProcState = procState;
16348        mPendingPssProcesses.add(proc);
16349    }
16350
16351    /**
16352     * Schedule PSS collection of all processes.
16353     */
16354    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16355        if (!always) {
16356            if (now < (mLastFullPssTime +
16357                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16358                return;
16359            }
16360        }
16361        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16362        mLastFullPssTime = now;
16363        mFullPssPending = true;
16364        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16365        mPendingPssProcesses.clear();
16366        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16367            ProcessRecord app = mLruProcesses.get(i);
16368            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16369                app.pssProcState = app.setProcState;
16370                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16371                        isSleeping(), now);
16372                mPendingPssProcesses.add(app);
16373            }
16374        }
16375        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16376    }
16377
16378    /**
16379     * Ask a given process to GC right now.
16380     */
16381    final void performAppGcLocked(ProcessRecord app) {
16382        try {
16383            app.lastRequestedGc = SystemClock.uptimeMillis();
16384            if (app.thread != null) {
16385                if (app.reportLowMemory) {
16386                    app.reportLowMemory = false;
16387                    app.thread.scheduleLowMemory();
16388                } else {
16389                    app.thread.processInBackground();
16390                }
16391            }
16392        } catch (Exception e) {
16393            // whatever.
16394        }
16395    }
16396
16397    /**
16398     * Returns true if things are idle enough to perform GCs.
16399     */
16400    private final boolean canGcNowLocked() {
16401        boolean processingBroadcasts = false;
16402        for (BroadcastQueue q : mBroadcastQueues) {
16403            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16404                processingBroadcasts = true;
16405            }
16406        }
16407        return !processingBroadcasts
16408                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16409    }
16410
16411    /**
16412     * Perform GCs on all processes that are waiting for it, but only
16413     * if things are idle.
16414     */
16415    final void performAppGcsLocked() {
16416        final int N = mProcessesToGc.size();
16417        if (N <= 0) {
16418            return;
16419        }
16420        if (canGcNowLocked()) {
16421            while (mProcessesToGc.size() > 0) {
16422                ProcessRecord proc = mProcessesToGc.remove(0);
16423                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16424                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16425                            <= SystemClock.uptimeMillis()) {
16426                        // To avoid spamming the system, we will GC processes one
16427                        // at a time, waiting a few seconds between each.
16428                        performAppGcLocked(proc);
16429                        scheduleAppGcsLocked();
16430                        return;
16431                    } else {
16432                        // It hasn't been long enough since we last GCed this
16433                        // process...  put it in the list to wait for its time.
16434                        addProcessToGcListLocked(proc);
16435                        break;
16436                    }
16437                }
16438            }
16439
16440            scheduleAppGcsLocked();
16441        }
16442    }
16443
16444    /**
16445     * If all looks good, perform GCs on all processes waiting for them.
16446     */
16447    final void performAppGcsIfAppropriateLocked() {
16448        if (canGcNowLocked()) {
16449            performAppGcsLocked();
16450            return;
16451        }
16452        // Still not idle, wait some more.
16453        scheduleAppGcsLocked();
16454    }
16455
16456    /**
16457     * Schedule the execution of all pending app GCs.
16458     */
16459    final void scheduleAppGcsLocked() {
16460        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16461
16462        if (mProcessesToGc.size() > 0) {
16463            // Schedule a GC for the time to the next process.
16464            ProcessRecord proc = mProcessesToGc.get(0);
16465            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16466
16467            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16468            long now = SystemClock.uptimeMillis();
16469            if (when < (now+GC_TIMEOUT)) {
16470                when = now + GC_TIMEOUT;
16471            }
16472            mHandler.sendMessageAtTime(msg, when);
16473        }
16474    }
16475
16476    /**
16477     * Add a process to the array of processes waiting to be GCed.  Keeps the
16478     * list in sorted order by the last GC time.  The process can't already be
16479     * on the list.
16480     */
16481    final void addProcessToGcListLocked(ProcessRecord proc) {
16482        boolean added = false;
16483        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16484            if (mProcessesToGc.get(i).lastRequestedGc <
16485                    proc.lastRequestedGc) {
16486                added = true;
16487                mProcessesToGc.add(i+1, proc);
16488                break;
16489            }
16490        }
16491        if (!added) {
16492            mProcessesToGc.add(0, proc);
16493        }
16494    }
16495
16496    /**
16497     * Set up to ask a process to GC itself.  This will either do it
16498     * immediately, or put it on the list of processes to gc the next
16499     * time things are idle.
16500     */
16501    final void scheduleAppGcLocked(ProcessRecord app) {
16502        long now = SystemClock.uptimeMillis();
16503        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16504            return;
16505        }
16506        if (!mProcessesToGc.contains(app)) {
16507            addProcessToGcListLocked(app);
16508            scheduleAppGcsLocked();
16509        }
16510    }
16511
16512    final void checkExcessivePowerUsageLocked(boolean doKills) {
16513        updateCpuStatsNow();
16514
16515        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16516        boolean doWakeKills = doKills;
16517        boolean doCpuKills = doKills;
16518        if (mLastPowerCheckRealtime == 0) {
16519            doWakeKills = false;
16520        }
16521        if (mLastPowerCheckUptime == 0) {
16522            doCpuKills = false;
16523        }
16524        if (stats.isScreenOn()) {
16525            doWakeKills = false;
16526        }
16527        final long curRealtime = SystemClock.elapsedRealtime();
16528        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16529        final long curUptime = SystemClock.uptimeMillis();
16530        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16531        mLastPowerCheckRealtime = curRealtime;
16532        mLastPowerCheckUptime = curUptime;
16533        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16534            doWakeKills = false;
16535        }
16536        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16537            doCpuKills = false;
16538        }
16539        int i = mLruProcesses.size();
16540        while (i > 0) {
16541            i--;
16542            ProcessRecord app = mLruProcesses.get(i);
16543            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16544                long wtime;
16545                synchronized (stats) {
16546                    wtime = stats.getProcessWakeTime(app.info.uid,
16547                            app.pid, curRealtime);
16548                }
16549                long wtimeUsed = wtime - app.lastWakeTime;
16550                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16551                if (DEBUG_POWER) {
16552                    StringBuilder sb = new StringBuilder(128);
16553                    sb.append("Wake for ");
16554                    app.toShortString(sb);
16555                    sb.append(": over ");
16556                    TimeUtils.formatDuration(realtimeSince, sb);
16557                    sb.append(" used ");
16558                    TimeUtils.formatDuration(wtimeUsed, sb);
16559                    sb.append(" (");
16560                    sb.append((wtimeUsed*100)/realtimeSince);
16561                    sb.append("%)");
16562                    Slog.i(TAG, sb.toString());
16563                    sb.setLength(0);
16564                    sb.append("CPU for ");
16565                    app.toShortString(sb);
16566                    sb.append(": over ");
16567                    TimeUtils.formatDuration(uptimeSince, sb);
16568                    sb.append(" used ");
16569                    TimeUtils.formatDuration(cputimeUsed, sb);
16570                    sb.append(" (");
16571                    sb.append((cputimeUsed*100)/uptimeSince);
16572                    sb.append("%)");
16573                    Slog.i(TAG, sb.toString());
16574                }
16575                // If a process has held a wake lock for more
16576                // than 50% of the time during this period,
16577                // that sounds bad.  Kill!
16578                if (doWakeKills && realtimeSince > 0
16579                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16580                    synchronized (stats) {
16581                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16582                                realtimeSince, wtimeUsed);
16583                    }
16584                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16585                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16586                } else if (doCpuKills && uptimeSince > 0
16587                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16588                    synchronized (stats) {
16589                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16590                                uptimeSince, cputimeUsed);
16591                    }
16592                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16593                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16594                } else {
16595                    app.lastWakeTime = wtime;
16596                    app.lastCpuTime = app.curCpuTime;
16597                }
16598            }
16599        }
16600    }
16601
16602    private final boolean applyOomAdjLocked(ProcessRecord app,
16603            ProcessRecord TOP_APP, boolean doingAll, long now) {
16604        boolean success = true;
16605
16606        if (app.curRawAdj != app.setRawAdj) {
16607            app.setRawAdj = app.curRawAdj;
16608        }
16609
16610        int changes = 0;
16611
16612        if (app.curAdj != app.setAdj) {
16613            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16614            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16615                TAG, "Set " + app.pid + " " + app.processName +
16616                " adj " + app.curAdj + ": " + app.adjType);
16617            app.setAdj = app.curAdj;
16618        }
16619
16620        if (app.setSchedGroup != app.curSchedGroup) {
16621            app.setSchedGroup = app.curSchedGroup;
16622            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16623                    "Setting process group of " + app.processName
16624                    + " to " + app.curSchedGroup);
16625            if (app.waitingToKill != null &&
16626                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16627                app.kill(app.waitingToKill, true);
16628                success = false;
16629            } else {
16630                if (true) {
16631                    long oldId = Binder.clearCallingIdentity();
16632                    try {
16633                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16634                    } catch (Exception e) {
16635                        Slog.w(TAG, "Failed setting process group of " + app.pid
16636                                + " to " + app.curSchedGroup);
16637                        e.printStackTrace();
16638                    } finally {
16639                        Binder.restoreCallingIdentity(oldId);
16640                    }
16641                } else {
16642                    if (app.thread != null) {
16643                        try {
16644                            app.thread.setSchedulingGroup(app.curSchedGroup);
16645                        } catch (RemoteException e) {
16646                        }
16647                    }
16648                }
16649                Process.setSwappiness(app.pid,
16650                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16651            }
16652        }
16653        if (app.repForegroundActivities != app.foregroundActivities) {
16654            app.repForegroundActivities = app.foregroundActivities;
16655            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16656        }
16657        if (app.repProcState != app.curProcState) {
16658            app.repProcState = app.curProcState;
16659            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16660            if (app.thread != null) {
16661                try {
16662                    if (false) {
16663                        //RuntimeException h = new RuntimeException("here");
16664                        Slog.i(TAG, "Sending new process state " + app.repProcState
16665                                + " to " + app /*, h*/);
16666                    }
16667                    app.thread.setProcessState(app.repProcState);
16668                } catch (RemoteException e) {
16669                }
16670            }
16671        }
16672        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16673                app.setProcState)) {
16674            app.lastStateTime = now;
16675            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16676                    isSleeping(), now);
16677            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16678                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16679                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16680                    + (app.nextPssTime-now) + ": " + app);
16681        } else {
16682            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16683                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16684                requestPssLocked(app, app.setProcState);
16685                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16686                        isSleeping(), now);
16687            } else if (false && DEBUG_PSS) {
16688                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16689            }
16690        }
16691        if (app.setProcState != app.curProcState) {
16692            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16693                    "Proc state change of " + app.processName
16694                    + " to " + app.curProcState);
16695            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16696            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16697            if (setImportant && !curImportant) {
16698                // This app is no longer something we consider important enough to allow to
16699                // use arbitrary amounts of battery power.  Note
16700                // its current wake lock time to later know to kill it if
16701                // it is not behaving well.
16702                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16703                synchronized (stats) {
16704                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16705                            app.pid, SystemClock.elapsedRealtime());
16706                }
16707                app.lastCpuTime = app.curCpuTime;
16708
16709            }
16710            app.setProcState = app.curProcState;
16711            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16712                app.notCachedSinceIdle = false;
16713            }
16714            if (!doingAll) {
16715                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16716            } else {
16717                app.procStateChanged = true;
16718            }
16719        }
16720
16721        if (changes != 0) {
16722            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16723            int i = mPendingProcessChanges.size()-1;
16724            ProcessChangeItem item = null;
16725            while (i >= 0) {
16726                item = mPendingProcessChanges.get(i);
16727                if (item.pid == app.pid) {
16728                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16729                    break;
16730                }
16731                i--;
16732            }
16733            if (i < 0) {
16734                // No existing item in pending changes; need a new one.
16735                final int NA = mAvailProcessChanges.size();
16736                if (NA > 0) {
16737                    item = mAvailProcessChanges.remove(NA-1);
16738                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16739                } else {
16740                    item = new ProcessChangeItem();
16741                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16742                }
16743                item.changes = 0;
16744                item.pid = app.pid;
16745                item.uid = app.info.uid;
16746                if (mPendingProcessChanges.size() == 0) {
16747                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16748                            "*** Enqueueing dispatch processes changed!");
16749                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16750                }
16751                mPendingProcessChanges.add(item);
16752            }
16753            item.changes |= changes;
16754            item.processState = app.repProcState;
16755            item.foregroundActivities = app.repForegroundActivities;
16756            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16757                    + Integer.toHexString(System.identityHashCode(item))
16758                    + " " + app.toShortString() + ": changes=" + item.changes
16759                    + " procState=" + item.processState
16760                    + " foreground=" + item.foregroundActivities
16761                    + " type=" + app.adjType + " source=" + app.adjSource
16762                    + " target=" + app.adjTarget);
16763        }
16764
16765        return success;
16766    }
16767
16768    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16769        if (proc.thread != null) {
16770            if (proc.baseProcessTracker != null) {
16771                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16772            }
16773            if (proc.repProcState >= 0) {
16774                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16775                        proc.repProcState);
16776            }
16777        }
16778    }
16779
16780    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16781            ProcessRecord TOP_APP, boolean doingAll, long now) {
16782        if (app.thread == null) {
16783            return false;
16784        }
16785
16786        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16787
16788        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16789    }
16790
16791    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16792            boolean oomAdj) {
16793        if (isForeground != proc.foregroundServices) {
16794            proc.foregroundServices = isForeground;
16795            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16796                    proc.info.uid);
16797            if (isForeground) {
16798                if (curProcs == null) {
16799                    curProcs = new ArrayList<ProcessRecord>();
16800                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16801                }
16802                if (!curProcs.contains(proc)) {
16803                    curProcs.add(proc);
16804                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16805                            proc.info.packageName, proc.info.uid);
16806                }
16807            } else {
16808                if (curProcs != null) {
16809                    if (curProcs.remove(proc)) {
16810                        mBatteryStatsService.noteEvent(
16811                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16812                                proc.info.packageName, proc.info.uid);
16813                        if (curProcs.size() <= 0) {
16814                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16815                        }
16816                    }
16817                }
16818            }
16819            if (oomAdj) {
16820                updateOomAdjLocked();
16821            }
16822        }
16823    }
16824
16825    private final ActivityRecord resumedAppLocked() {
16826        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16827        String pkg;
16828        int uid;
16829        if (act != null) {
16830            pkg = act.packageName;
16831            uid = act.info.applicationInfo.uid;
16832        } else {
16833            pkg = null;
16834            uid = -1;
16835        }
16836        // Has the UID or resumed package name changed?
16837        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16838                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16839            if (mCurResumedPackage != null) {
16840                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16841                        mCurResumedPackage, mCurResumedUid);
16842            }
16843            mCurResumedPackage = pkg;
16844            mCurResumedUid = uid;
16845            if (mCurResumedPackage != null) {
16846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16847                        mCurResumedPackage, mCurResumedUid);
16848            }
16849        }
16850        return act;
16851    }
16852
16853    final boolean updateOomAdjLocked(ProcessRecord app) {
16854        final ActivityRecord TOP_ACT = resumedAppLocked();
16855        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16856        final boolean wasCached = app.cached;
16857
16858        mAdjSeq++;
16859
16860        // This is the desired cached adjusment we want to tell it to use.
16861        // If our app is currently cached, we know it, and that is it.  Otherwise,
16862        // we don't know it yet, and it needs to now be cached we will then
16863        // need to do a complete oom adj.
16864        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16865                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16866        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16867                SystemClock.uptimeMillis());
16868        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16869            // Changed to/from cached state, so apps after it in the LRU
16870            // list may also be changed.
16871            updateOomAdjLocked();
16872        }
16873        return success;
16874    }
16875
16876    final void updateOomAdjLocked() {
16877        final ActivityRecord TOP_ACT = resumedAppLocked();
16878        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16879        final long now = SystemClock.uptimeMillis();
16880        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16881        final int N = mLruProcesses.size();
16882
16883        if (false) {
16884            RuntimeException e = new RuntimeException();
16885            e.fillInStackTrace();
16886            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16887        }
16888
16889        mAdjSeq++;
16890        mNewNumServiceProcs = 0;
16891        mNewNumAServiceProcs = 0;
16892
16893        final int emptyProcessLimit;
16894        final int cachedProcessLimit;
16895        if (mProcessLimit <= 0) {
16896            emptyProcessLimit = cachedProcessLimit = 0;
16897        } else if (mProcessLimit == 1) {
16898            emptyProcessLimit = 1;
16899            cachedProcessLimit = 0;
16900        } else {
16901            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16902            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16903        }
16904
16905        // Let's determine how many processes we have running vs.
16906        // how many slots we have for background processes; we may want
16907        // to put multiple processes in a slot of there are enough of
16908        // them.
16909        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16910                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16911        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16912        if (numEmptyProcs > cachedProcessLimit) {
16913            // If there are more empty processes than our limit on cached
16914            // processes, then use the cached process limit for the factor.
16915            // This ensures that the really old empty processes get pushed
16916            // down to the bottom, so if we are running low on memory we will
16917            // have a better chance at keeping around more cached processes
16918            // instead of a gazillion empty processes.
16919            numEmptyProcs = cachedProcessLimit;
16920        }
16921        int emptyFactor = numEmptyProcs/numSlots;
16922        if (emptyFactor < 1) emptyFactor = 1;
16923        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16924        if (cachedFactor < 1) cachedFactor = 1;
16925        int stepCached = 0;
16926        int stepEmpty = 0;
16927        int numCached = 0;
16928        int numEmpty = 0;
16929        int numTrimming = 0;
16930
16931        mNumNonCachedProcs = 0;
16932        mNumCachedHiddenProcs = 0;
16933
16934        // First update the OOM adjustment for each of the
16935        // application processes based on their current state.
16936        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16937        int nextCachedAdj = curCachedAdj+1;
16938        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16939        int nextEmptyAdj = curEmptyAdj+2;
16940        for (int i=N-1; i>=0; i--) {
16941            ProcessRecord app = mLruProcesses.get(i);
16942            if (!app.killedByAm && app.thread != null) {
16943                app.procStateChanged = false;
16944                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16945
16946                // If we haven't yet assigned the final cached adj
16947                // to the process, do that now.
16948                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16949                    switch (app.curProcState) {
16950                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16951                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16952                            // This process is a cached process holding activities...
16953                            // assign it the next cached value for that type, and then
16954                            // step that cached level.
16955                            app.curRawAdj = curCachedAdj;
16956                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16957                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16958                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16959                                    + ")");
16960                            if (curCachedAdj != nextCachedAdj) {
16961                                stepCached++;
16962                                if (stepCached >= cachedFactor) {
16963                                    stepCached = 0;
16964                                    curCachedAdj = nextCachedAdj;
16965                                    nextCachedAdj += 2;
16966                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16967                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16968                                    }
16969                                }
16970                            }
16971                            break;
16972                        default:
16973                            // For everything else, assign next empty cached process
16974                            // level and bump that up.  Note that this means that
16975                            // long-running services that have dropped down to the
16976                            // cached level will be treated as empty (since their process
16977                            // state is still as a service), which is what we want.
16978                            app.curRawAdj = curEmptyAdj;
16979                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16980                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16981                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16982                                    + ")");
16983                            if (curEmptyAdj != nextEmptyAdj) {
16984                                stepEmpty++;
16985                                if (stepEmpty >= emptyFactor) {
16986                                    stepEmpty = 0;
16987                                    curEmptyAdj = nextEmptyAdj;
16988                                    nextEmptyAdj += 2;
16989                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16990                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16991                                    }
16992                                }
16993                            }
16994                            break;
16995                    }
16996                }
16997
16998                applyOomAdjLocked(app, TOP_APP, true, now);
16999
17000                // Count the number of process types.
17001                switch (app.curProcState) {
17002                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17003                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17004                        mNumCachedHiddenProcs++;
17005                        numCached++;
17006                        if (numCached > cachedProcessLimit) {
17007                            app.kill("cached #" + numCached, true);
17008                        }
17009                        break;
17010                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17011                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17012                                && app.lastActivityTime < oldTime) {
17013                            app.kill("empty for "
17014                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17015                                    / 1000) + "s", true);
17016                        } else {
17017                            numEmpty++;
17018                            if (numEmpty > emptyProcessLimit) {
17019                                app.kill("empty #" + numEmpty, true);
17020                            }
17021                        }
17022                        break;
17023                    default:
17024                        mNumNonCachedProcs++;
17025                        break;
17026                }
17027
17028                if (app.isolated && app.services.size() <= 0) {
17029                    // If this is an isolated process, and there are no
17030                    // services running in it, then the process is no longer
17031                    // needed.  We agressively kill these because we can by
17032                    // definition not re-use the same process again, and it is
17033                    // good to avoid having whatever code was running in them
17034                    // left sitting around after no longer needed.
17035                    app.kill("isolated not needed", true);
17036                }
17037
17038                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17039                        && !app.killedByAm) {
17040                    numTrimming++;
17041                }
17042            }
17043        }
17044
17045        mNumServiceProcs = mNewNumServiceProcs;
17046
17047        // Now determine the memory trimming level of background processes.
17048        // Unfortunately we need to start at the back of the list to do this
17049        // properly.  We only do this if the number of background apps we
17050        // are managing to keep around is less than half the maximum we desire;
17051        // if we are keeping a good number around, we'll let them use whatever
17052        // memory they want.
17053        final int numCachedAndEmpty = numCached + numEmpty;
17054        int memFactor;
17055        if (numCached <= ProcessList.TRIM_CACHED_APPS
17056                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17057            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17058                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17059            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17060                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17061            } else {
17062                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17063            }
17064        } else {
17065            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17066        }
17067        // We always allow the memory level to go up (better).  We only allow it to go
17068        // down if we are in a state where that is allowed, *and* the total number of processes
17069        // has gone down since last time.
17070        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17071                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17072                + " last=" + mLastNumProcesses);
17073        if (memFactor > mLastMemoryLevel) {
17074            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17075                memFactor = mLastMemoryLevel;
17076                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17077            }
17078        }
17079        mLastMemoryLevel = memFactor;
17080        mLastNumProcesses = mLruProcesses.size();
17081        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17082        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17083        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17084            if (mLowRamStartTime == 0) {
17085                mLowRamStartTime = now;
17086            }
17087            int step = 0;
17088            int fgTrimLevel;
17089            switch (memFactor) {
17090                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17091                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17092                    break;
17093                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17094                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17095                    break;
17096                default:
17097                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17098                    break;
17099            }
17100            int factor = numTrimming/3;
17101            int minFactor = 2;
17102            if (mHomeProcess != null) minFactor++;
17103            if (mPreviousProcess != null) minFactor++;
17104            if (factor < minFactor) factor = minFactor;
17105            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17106            for (int i=N-1; i>=0; i--) {
17107                ProcessRecord app = mLruProcesses.get(i);
17108                if (allChanged || app.procStateChanged) {
17109                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17110                    app.procStateChanged = false;
17111                }
17112                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17113                        && !app.killedByAm) {
17114                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17115                        try {
17116                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17117                                    "Trimming memory of " + app.processName
17118                                    + " to " + curLevel);
17119                            app.thread.scheduleTrimMemory(curLevel);
17120                        } catch (RemoteException e) {
17121                        }
17122                        if (false) {
17123                            // For now we won't do this; our memory trimming seems
17124                            // to be good enough at this point that destroying
17125                            // activities causes more harm than good.
17126                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17127                                    && app != mHomeProcess && app != mPreviousProcess) {
17128                                // Need to do this on its own message because the stack may not
17129                                // be in a consistent state at this point.
17130                                // For these apps we will also finish their activities
17131                                // to help them free memory.
17132                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17133                            }
17134                        }
17135                    }
17136                    app.trimMemoryLevel = curLevel;
17137                    step++;
17138                    if (step >= factor) {
17139                        step = 0;
17140                        switch (curLevel) {
17141                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17142                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17143                                break;
17144                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17145                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17146                                break;
17147                        }
17148                    }
17149                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17150                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17151                            && app.thread != null) {
17152                        try {
17153                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17154                                    "Trimming memory of heavy-weight " + app.processName
17155                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17156                            app.thread.scheduleTrimMemory(
17157                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17158                        } catch (RemoteException e) {
17159                        }
17160                    }
17161                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17162                } else {
17163                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17164                            || app.systemNoUi) && app.pendingUiClean) {
17165                        // If this application is now in the background and it
17166                        // had done UI, then give it the special trim level to
17167                        // have it free UI resources.
17168                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17169                        if (app.trimMemoryLevel < level && app.thread != null) {
17170                            try {
17171                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17172                                        "Trimming memory of bg-ui " + app.processName
17173                                        + " to " + level);
17174                                app.thread.scheduleTrimMemory(level);
17175                            } catch (RemoteException e) {
17176                            }
17177                        }
17178                        app.pendingUiClean = false;
17179                    }
17180                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17181                        try {
17182                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17183                                    "Trimming memory of fg " + app.processName
17184                                    + " to " + fgTrimLevel);
17185                            app.thread.scheduleTrimMemory(fgTrimLevel);
17186                        } catch (RemoteException e) {
17187                        }
17188                    }
17189                    app.trimMemoryLevel = fgTrimLevel;
17190                }
17191            }
17192        } else {
17193            if (mLowRamStartTime != 0) {
17194                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17195                mLowRamStartTime = 0;
17196            }
17197            for (int i=N-1; i>=0; i--) {
17198                ProcessRecord app = mLruProcesses.get(i);
17199                if (allChanged || app.procStateChanged) {
17200                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17201                    app.procStateChanged = false;
17202                }
17203                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17204                        || app.systemNoUi) && app.pendingUiClean) {
17205                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17206                            && app.thread != null) {
17207                        try {
17208                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17209                                    "Trimming memory of ui hidden " + app.processName
17210                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17211                            app.thread.scheduleTrimMemory(
17212                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17213                        } catch (RemoteException e) {
17214                        }
17215                    }
17216                    app.pendingUiClean = false;
17217                }
17218                app.trimMemoryLevel = 0;
17219            }
17220        }
17221
17222        if (mAlwaysFinishActivities) {
17223            // Need to do this on its own message because the stack may not
17224            // be in a consistent state at this point.
17225            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17226        }
17227
17228        if (allChanged) {
17229            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17230        }
17231
17232        if (mProcessStats.shouldWriteNowLocked(now)) {
17233            mHandler.post(new Runnable() {
17234                @Override public void run() {
17235                    synchronized (ActivityManagerService.this) {
17236                        mProcessStats.writeStateAsyncLocked();
17237                    }
17238                }
17239            });
17240        }
17241
17242        if (DEBUG_OOM_ADJ) {
17243            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17244        }
17245    }
17246
17247    final void trimApplications() {
17248        synchronized (this) {
17249            int i;
17250
17251            // First remove any unused application processes whose package
17252            // has been removed.
17253            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17254                final ProcessRecord app = mRemovedProcesses.get(i);
17255                if (app.activities.size() == 0
17256                        && app.curReceiver == null && app.services.size() == 0) {
17257                    Slog.i(
17258                        TAG, "Exiting empty application process "
17259                        + app.processName + " ("
17260                        + (app.thread != null ? app.thread.asBinder() : null)
17261                        + ")\n");
17262                    if (app.pid > 0 && app.pid != MY_PID) {
17263                        app.kill("empty", false);
17264                    } else {
17265                        try {
17266                            app.thread.scheduleExit();
17267                        } catch (Exception e) {
17268                            // Ignore exceptions.
17269                        }
17270                    }
17271                    cleanUpApplicationRecordLocked(app, false, true, -1);
17272                    mRemovedProcesses.remove(i);
17273
17274                    if (app.persistent) {
17275                        addAppLocked(app.info, false, null /* ABI override */);
17276                    }
17277                }
17278            }
17279
17280            // Now update the oom adj for all processes.
17281            updateOomAdjLocked();
17282        }
17283    }
17284
17285    /** This method sends the specified signal to each of the persistent apps */
17286    public void signalPersistentProcesses(int sig) throws RemoteException {
17287        if (sig != Process.SIGNAL_USR1) {
17288            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17289        }
17290
17291        synchronized (this) {
17292            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17293                    != PackageManager.PERMISSION_GRANTED) {
17294                throw new SecurityException("Requires permission "
17295                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17296            }
17297
17298            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17299                ProcessRecord r = mLruProcesses.get(i);
17300                if (r.thread != null && r.persistent) {
17301                    Process.sendSignal(r.pid, sig);
17302                }
17303            }
17304        }
17305    }
17306
17307    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17308        if (proc == null || proc == mProfileProc) {
17309            proc = mProfileProc;
17310            path = mProfileFile;
17311            profileType = mProfileType;
17312            clearProfilerLocked();
17313        }
17314        if (proc == null) {
17315            return;
17316        }
17317        try {
17318            proc.thread.profilerControl(false, path, null, profileType);
17319        } catch (RemoteException e) {
17320            throw new IllegalStateException("Process disappeared");
17321        }
17322    }
17323
17324    private void clearProfilerLocked() {
17325        if (mProfileFd != null) {
17326            try {
17327                mProfileFd.close();
17328            } catch (IOException e) {
17329            }
17330        }
17331        mProfileApp = null;
17332        mProfileProc = null;
17333        mProfileFile = null;
17334        mProfileType = 0;
17335        mAutoStopProfiler = false;
17336    }
17337
17338    public boolean profileControl(String process, int userId, boolean start,
17339            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17340
17341        try {
17342            synchronized (this) {
17343                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17344                // its own permission.
17345                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17346                        != PackageManager.PERMISSION_GRANTED) {
17347                    throw new SecurityException("Requires permission "
17348                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17349                }
17350
17351                if (start && fd == null) {
17352                    throw new IllegalArgumentException("null fd");
17353                }
17354
17355                ProcessRecord proc = null;
17356                if (process != null) {
17357                    proc = findProcessLocked(process, userId, "profileControl");
17358                }
17359
17360                if (start && (proc == null || proc.thread == null)) {
17361                    throw new IllegalArgumentException("Unknown process: " + process);
17362                }
17363
17364                if (start) {
17365                    stopProfilerLocked(null, null, 0);
17366                    setProfileApp(proc.info, proc.processName, path, fd, false);
17367                    mProfileProc = proc;
17368                    mProfileType = profileType;
17369                    try {
17370                        fd = fd.dup();
17371                    } catch (IOException e) {
17372                        fd = null;
17373                    }
17374                    proc.thread.profilerControl(start, path, fd, profileType);
17375                    fd = null;
17376                    mProfileFd = null;
17377                } else {
17378                    stopProfilerLocked(proc, path, profileType);
17379                    if (fd != null) {
17380                        try {
17381                            fd.close();
17382                        } catch (IOException e) {
17383                        }
17384                    }
17385                }
17386
17387                return true;
17388            }
17389        } catch (RemoteException e) {
17390            throw new IllegalStateException("Process disappeared");
17391        } finally {
17392            if (fd != null) {
17393                try {
17394                    fd.close();
17395                } catch (IOException e) {
17396                }
17397            }
17398        }
17399    }
17400
17401    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17402        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17403                userId, true, ALLOW_FULL_ONLY, callName, null);
17404        ProcessRecord proc = null;
17405        try {
17406            int pid = Integer.parseInt(process);
17407            synchronized (mPidsSelfLocked) {
17408                proc = mPidsSelfLocked.get(pid);
17409            }
17410        } catch (NumberFormatException e) {
17411        }
17412
17413        if (proc == null) {
17414            ArrayMap<String, SparseArray<ProcessRecord>> all
17415                    = mProcessNames.getMap();
17416            SparseArray<ProcessRecord> procs = all.get(process);
17417            if (procs != null && procs.size() > 0) {
17418                proc = procs.valueAt(0);
17419                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17420                    for (int i=1; i<procs.size(); i++) {
17421                        ProcessRecord thisProc = procs.valueAt(i);
17422                        if (thisProc.userId == userId) {
17423                            proc = thisProc;
17424                            break;
17425                        }
17426                    }
17427                }
17428            }
17429        }
17430
17431        return proc;
17432    }
17433
17434    public boolean dumpHeap(String process, int userId, boolean managed,
17435            String path, ParcelFileDescriptor fd) throws RemoteException {
17436
17437        try {
17438            synchronized (this) {
17439                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17440                // its own permission (same as profileControl).
17441                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17442                        != PackageManager.PERMISSION_GRANTED) {
17443                    throw new SecurityException("Requires permission "
17444                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17445                }
17446
17447                if (fd == null) {
17448                    throw new IllegalArgumentException("null fd");
17449                }
17450
17451                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17452                if (proc == null || proc.thread == null) {
17453                    throw new IllegalArgumentException("Unknown process: " + process);
17454                }
17455
17456                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17457                if (!isDebuggable) {
17458                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17459                        throw new SecurityException("Process not debuggable: " + proc);
17460                    }
17461                }
17462
17463                proc.thread.dumpHeap(managed, path, fd);
17464                fd = null;
17465                return true;
17466            }
17467        } catch (RemoteException e) {
17468            throw new IllegalStateException("Process disappeared");
17469        } finally {
17470            if (fd != null) {
17471                try {
17472                    fd.close();
17473                } catch (IOException e) {
17474                }
17475            }
17476        }
17477    }
17478
17479    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17480    public void monitor() {
17481        synchronized (this) { }
17482    }
17483
17484    void onCoreSettingsChange(Bundle settings) {
17485        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17486            ProcessRecord processRecord = mLruProcesses.get(i);
17487            try {
17488                if (processRecord.thread != null) {
17489                    processRecord.thread.setCoreSettings(settings);
17490                }
17491            } catch (RemoteException re) {
17492                /* ignore */
17493            }
17494        }
17495    }
17496
17497    // Multi-user methods
17498
17499    /**
17500     * Start user, if its not already running, but don't bring it to foreground.
17501     */
17502    @Override
17503    public boolean startUserInBackground(final int userId) {
17504        return startUser(userId, /* foreground */ false);
17505    }
17506
17507    /**
17508     * Start user, if its not already running, and bring it to foreground.
17509     */
17510    boolean startUserInForeground(final int userId, Dialog dlg) {
17511        boolean result = startUser(userId, /* foreground */ true);
17512        dlg.dismiss();
17513        return result;
17514    }
17515
17516    /**
17517     * Refreshes the list of users related to the current user when either a
17518     * user switch happens or when a new related user is started in the
17519     * background.
17520     */
17521    private void updateCurrentProfileIdsLocked() {
17522        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17523                mCurrentUserId, false /* enabledOnly */);
17524        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17525        for (int i = 0; i < currentProfileIds.length; i++) {
17526            currentProfileIds[i] = profiles.get(i).id;
17527        }
17528        mCurrentProfileIds = currentProfileIds;
17529
17530        synchronized (mUserProfileGroupIdsSelfLocked) {
17531            mUserProfileGroupIdsSelfLocked.clear();
17532            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17533            for (int i = 0; i < users.size(); i++) {
17534                UserInfo user = users.get(i);
17535                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17536                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17537                }
17538            }
17539        }
17540    }
17541
17542    private Set getProfileIdsLocked(int userId) {
17543        Set userIds = new HashSet<Integer>();
17544        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17545                userId, false /* enabledOnly */);
17546        for (UserInfo user : profiles) {
17547            userIds.add(Integer.valueOf(user.id));
17548        }
17549        return userIds;
17550    }
17551
17552    @Override
17553    public boolean switchUser(final int userId) {
17554        String userName;
17555        synchronized (this) {
17556            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17557            if (userInfo == null) {
17558                Slog.w(TAG, "No user info for user #" + userId);
17559                return false;
17560            }
17561            if (userInfo.isManagedProfile()) {
17562                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17563                return false;
17564            }
17565            userName = userInfo.name;
17566        }
17567        mHandler.removeMessages(START_USER_SWITCH_MSG);
17568        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17569        return true;
17570    }
17571
17572    private void showUserSwitchDialog(int userId, String userName) {
17573        // The dialog will show and then initiate the user switch by calling startUserInForeground
17574        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17575                true /* above system */);
17576        d.show();
17577    }
17578
17579    private boolean startUser(final int userId, boolean foreground) {
17580        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17581                != PackageManager.PERMISSION_GRANTED) {
17582            String msg = "Permission Denial: switchUser() from pid="
17583                    + Binder.getCallingPid()
17584                    + ", uid=" + Binder.getCallingUid()
17585                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17586            Slog.w(TAG, msg);
17587            throw new SecurityException(msg);
17588        }
17589
17590        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17591
17592        final long ident = Binder.clearCallingIdentity();
17593        try {
17594            synchronized (this) {
17595                final int oldUserId = mCurrentUserId;
17596                if (oldUserId == userId) {
17597                    return true;
17598                }
17599
17600                mStackSupervisor.setLockTaskModeLocked(null, false);
17601
17602                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17603                if (userInfo == null) {
17604                    Slog.w(TAG, "No user info for user #" + userId);
17605                    return false;
17606                }
17607                if (foreground && userInfo.isManagedProfile()) {
17608                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17609                    return false;
17610                }
17611
17612                if (foreground) {
17613                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17614                            R.anim.screen_user_enter);
17615                }
17616
17617                boolean needStart = false;
17618
17619                // If the user we are switching to is not currently started, then
17620                // we need to start it now.
17621                if (mStartedUsers.get(userId) == null) {
17622                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17623                    updateStartedUserArrayLocked();
17624                    needStart = true;
17625                }
17626
17627                final Integer userIdInt = Integer.valueOf(userId);
17628                mUserLru.remove(userIdInt);
17629                mUserLru.add(userIdInt);
17630
17631                if (foreground) {
17632                    mCurrentUserId = userId;
17633                    updateCurrentProfileIdsLocked();
17634                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17635                    // Once the internal notion of the active user has switched, we lock the device
17636                    // with the option to show the user switcher on the keyguard.
17637                    mWindowManager.lockNow(null);
17638                } else {
17639                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17640                    updateCurrentProfileIdsLocked();
17641                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17642                    mUserLru.remove(currentUserIdInt);
17643                    mUserLru.add(currentUserIdInt);
17644                }
17645
17646                final UserStartedState uss = mStartedUsers.get(userId);
17647
17648                // Make sure user is in the started state.  If it is currently
17649                // stopping, we need to knock that off.
17650                if (uss.mState == UserStartedState.STATE_STOPPING) {
17651                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17652                    // so we can just fairly silently bring the user back from
17653                    // the almost-dead.
17654                    uss.mState = UserStartedState.STATE_RUNNING;
17655                    updateStartedUserArrayLocked();
17656                    needStart = true;
17657                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17658                    // This means ACTION_SHUTDOWN has been sent, so we will
17659                    // need to treat this as a new boot of the user.
17660                    uss.mState = UserStartedState.STATE_BOOTING;
17661                    updateStartedUserArrayLocked();
17662                    needStart = true;
17663                }
17664
17665                if (uss.mState == UserStartedState.STATE_BOOTING) {
17666                    // Booting up a new user, need to tell system services about it.
17667                    // Note that this is on the same handler as scheduling of broadcasts,
17668                    // which is important because it needs to go first.
17669                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17670                }
17671
17672                if (foreground) {
17673                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17674                            oldUserId));
17675                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17676                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17677                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17678                            oldUserId, userId, uss));
17679                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17680                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17681                }
17682
17683                if (needStart) {
17684                    // Send USER_STARTED broadcast
17685                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17686                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17687                            | Intent.FLAG_RECEIVER_FOREGROUND);
17688                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17689                    broadcastIntentLocked(null, null, intent,
17690                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17691                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17692                }
17693
17694                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17695                    if (userId != UserHandle.USER_OWNER) {
17696                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17697                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17698                        broadcastIntentLocked(null, null, intent, null,
17699                                new IIntentReceiver.Stub() {
17700                                    public void performReceive(Intent intent, int resultCode,
17701                                            String data, Bundle extras, boolean ordered,
17702                                            boolean sticky, int sendingUser) {
17703                                        userInitialized(uss, userId);
17704                                    }
17705                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17706                                true, false, MY_PID, Process.SYSTEM_UID,
17707                                userId);
17708                        uss.initializing = true;
17709                    } else {
17710                        getUserManagerLocked().makeInitialized(userInfo.id);
17711                    }
17712                }
17713
17714                if (foreground) {
17715                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17716                    if (homeInFront) {
17717                        startHomeActivityLocked(userId);
17718                    } else {
17719                        mStackSupervisor.resumeTopActivitiesLocked();
17720                    }
17721                    EventLogTags.writeAmSwitchUser(userId);
17722                    getUserManagerLocked().userForeground(userId);
17723                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17724                } else {
17725                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17726                }
17727
17728                if (needStart) {
17729                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17730                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17731                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17732                    broadcastIntentLocked(null, null, intent,
17733                            null, new IIntentReceiver.Stub() {
17734                                @Override
17735                                public void performReceive(Intent intent, int resultCode, String data,
17736                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17737                                        throws RemoteException {
17738                                }
17739                            }, 0, null, null,
17740                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17741                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17742                }
17743            }
17744        } finally {
17745            Binder.restoreCallingIdentity(ident);
17746        }
17747
17748        return true;
17749    }
17750
17751    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17752        long ident = Binder.clearCallingIdentity();
17753        try {
17754            Intent intent;
17755            if (oldUserId >= 0) {
17756                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17757                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17758                int count = profiles.size();
17759                for (int i = 0; i < count; i++) {
17760                    int profileUserId = profiles.get(i).id;
17761                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17762                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17763                            | Intent.FLAG_RECEIVER_FOREGROUND);
17764                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17765                    broadcastIntentLocked(null, null, intent,
17766                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17767                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17768                }
17769            }
17770            if (newUserId >= 0) {
17771                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17772                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17773                int count = profiles.size();
17774                for (int i = 0; i < count; i++) {
17775                    int profileUserId = profiles.get(i).id;
17776                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17777                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17778                            | Intent.FLAG_RECEIVER_FOREGROUND);
17779                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17780                    broadcastIntentLocked(null, null, intent,
17781                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17782                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17783                }
17784                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17785                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17786                        | Intent.FLAG_RECEIVER_FOREGROUND);
17787                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17788                broadcastIntentLocked(null, null, intent,
17789                        null, null, 0, null, null,
17790                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17791                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17792            }
17793        } finally {
17794            Binder.restoreCallingIdentity(ident);
17795        }
17796    }
17797
17798    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17799            final int newUserId) {
17800        final int N = mUserSwitchObservers.beginBroadcast();
17801        if (N > 0) {
17802            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17803                int mCount = 0;
17804                @Override
17805                public void sendResult(Bundle data) throws RemoteException {
17806                    synchronized (ActivityManagerService.this) {
17807                        if (mCurUserSwitchCallback == this) {
17808                            mCount++;
17809                            if (mCount == N) {
17810                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17811                            }
17812                        }
17813                    }
17814                }
17815            };
17816            synchronized (this) {
17817                uss.switching = true;
17818                mCurUserSwitchCallback = callback;
17819            }
17820            for (int i=0; i<N; i++) {
17821                try {
17822                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17823                            newUserId, callback);
17824                } catch (RemoteException e) {
17825                }
17826            }
17827        } else {
17828            synchronized (this) {
17829                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17830            }
17831        }
17832        mUserSwitchObservers.finishBroadcast();
17833    }
17834
17835    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17836        synchronized (this) {
17837            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17838            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17839        }
17840    }
17841
17842    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17843        mCurUserSwitchCallback = null;
17844        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17845        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17846                oldUserId, newUserId, uss));
17847    }
17848
17849    void userInitialized(UserStartedState uss, int newUserId) {
17850        completeSwitchAndInitalize(uss, newUserId, true, false);
17851    }
17852
17853    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17854        completeSwitchAndInitalize(uss, newUserId, false, true);
17855    }
17856
17857    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17858            boolean clearInitializing, boolean clearSwitching) {
17859        boolean unfrozen = false;
17860        synchronized (this) {
17861            if (clearInitializing) {
17862                uss.initializing = false;
17863                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17864            }
17865            if (clearSwitching) {
17866                uss.switching = false;
17867            }
17868            if (!uss.switching && !uss.initializing) {
17869                mWindowManager.stopFreezingScreen();
17870                unfrozen = true;
17871            }
17872        }
17873        if (unfrozen) {
17874            final int N = mUserSwitchObservers.beginBroadcast();
17875            for (int i=0; i<N; i++) {
17876                try {
17877                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17878                } catch (RemoteException e) {
17879                }
17880            }
17881            mUserSwitchObservers.finishBroadcast();
17882        }
17883    }
17884
17885    void scheduleStartProfilesLocked() {
17886        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17887            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17888                    DateUtils.SECOND_IN_MILLIS);
17889        }
17890    }
17891
17892    void startProfilesLocked() {
17893        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17894        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17895                mCurrentUserId, false /* enabledOnly */);
17896        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17897        for (UserInfo user : profiles) {
17898            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17899                    && user.id != mCurrentUserId) {
17900                toStart.add(user);
17901            }
17902        }
17903        final int n = toStart.size();
17904        int i = 0;
17905        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17906            startUserInBackground(toStart.get(i).id);
17907        }
17908        if (i < n) {
17909            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17910        }
17911    }
17912
17913    void finishUserBoot(UserStartedState uss) {
17914        synchronized (this) {
17915            if (uss.mState == UserStartedState.STATE_BOOTING
17916                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17917                uss.mState = UserStartedState.STATE_RUNNING;
17918                final int userId = uss.mHandle.getIdentifier();
17919                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17920                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17921                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17922                broadcastIntentLocked(null, null, intent,
17923                        null, null, 0, null, null,
17924                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17925                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17926            }
17927        }
17928    }
17929
17930    void finishUserSwitch(UserStartedState uss) {
17931        synchronized (this) {
17932            finishUserBoot(uss);
17933
17934            startProfilesLocked();
17935
17936            int num = mUserLru.size();
17937            int i = 0;
17938            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17939                Integer oldUserId = mUserLru.get(i);
17940                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17941                if (oldUss == null) {
17942                    // Shouldn't happen, but be sane if it does.
17943                    mUserLru.remove(i);
17944                    num--;
17945                    continue;
17946                }
17947                if (oldUss.mState == UserStartedState.STATE_STOPPING
17948                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17949                    // This user is already stopping, doesn't count.
17950                    num--;
17951                    i++;
17952                    continue;
17953                }
17954                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17955                    // Owner and current can't be stopped, but count as running.
17956                    i++;
17957                    continue;
17958                }
17959                // This is a user to be stopped.
17960                stopUserLocked(oldUserId, null);
17961                num--;
17962                i++;
17963            }
17964        }
17965    }
17966
17967    @Override
17968    public int stopUser(final int userId, final IStopUserCallback callback) {
17969        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17970                != PackageManager.PERMISSION_GRANTED) {
17971            String msg = "Permission Denial: switchUser() from pid="
17972                    + Binder.getCallingPid()
17973                    + ", uid=" + Binder.getCallingUid()
17974                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17975            Slog.w(TAG, msg);
17976            throw new SecurityException(msg);
17977        }
17978        if (userId <= 0) {
17979            throw new IllegalArgumentException("Can't stop primary user " + userId);
17980        }
17981        synchronized (this) {
17982            return stopUserLocked(userId, callback);
17983        }
17984    }
17985
17986    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17987        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17988        if (mCurrentUserId == userId) {
17989            return ActivityManager.USER_OP_IS_CURRENT;
17990        }
17991
17992        final UserStartedState uss = mStartedUsers.get(userId);
17993        if (uss == null) {
17994            // User is not started, nothing to do...  but we do need to
17995            // callback if requested.
17996            if (callback != null) {
17997                mHandler.post(new Runnable() {
17998                    @Override
17999                    public void run() {
18000                        try {
18001                            callback.userStopped(userId);
18002                        } catch (RemoteException e) {
18003                        }
18004                    }
18005                });
18006            }
18007            return ActivityManager.USER_OP_SUCCESS;
18008        }
18009
18010        if (callback != null) {
18011            uss.mStopCallbacks.add(callback);
18012        }
18013
18014        if (uss.mState != UserStartedState.STATE_STOPPING
18015                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18016            uss.mState = UserStartedState.STATE_STOPPING;
18017            updateStartedUserArrayLocked();
18018
18019            long ident = Binder.clearCallingIdentity();
18020            try {
18021                // We are going to broadcast ACTION_USER_STOPPING and then
18022                // once that is done send a final ACTION_SHUTDOWN and then
18023                // stop the user.
18024                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18025                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18026                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18027                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18028                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18029                // This is the result receiver for the final shutdown broadcast.
18030                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18031                    @Override
18032                    public void performReceive(Intent intent, int resultCode, String data,
18033                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18034                        finishUserStop(uss);
18035                    }
18036                };
18037                // This is the result receiver for the initial stopping broadcast.
18038                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18039                    @Override
18040                    public void performReceive(Intent intent, int resultCode, String data,
18041                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18042                        // On to the next.
18043                        synchronized (ActivityManagerService.this) {
18044                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18045                                // Whoops, we are being started back up.  Abort, abort!
18046                                return;
18047                            }
18048                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18049                        }
18050                        mBatteryStatsService.noteEvent(
18051                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18052                                Integer.toString(userId), userId);
18053                        mSystemServiceManager.stopUser(userId);
18054                        broadcastIntentLocked(null, null, shutdownIntent,
18055                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18056                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18057                    }
18058                };
18059                // Kick things off.
18060                broadcastIntentLocked(null, null, stoppingIntent,
18061                        null, stoppingReceiver, 0, null, null,
18062                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18063                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18064            } finally {
18065                Binder.restoreCallingIdentity(ident);
18066            }
18067        }
18068
18069        return ActivityManager.USER_OP_SUCCESS;
18070    }
18071
18072    void finishUserStop(UserStartedState uss) {
18073        final int userId = uss.mHandle.getIdentifier();
18074        boolean stopped;
18075        ArrayList<IStopUserCallback> callbacks;
18076        synchronized (this) {
18077            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18078            if (mStartedUsers.get(userId) != uss) {
18079                stopped = false;
18080            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18081                stopped = false;
18082            } else {
18083                stopped = true;
18084                // User can no longer run.
18085                mStartedUsers.remove(userId);
18086                mUserLru.remove(Integer.valueOf(userId));
18087                updateStartedUserArrayLocked();
18088
18089                // Clean up all state and processes associated with the user.
18090                // Kill all the processes for the user.
18091                forceStopUserLocked(userId, "finish user");
18092            }
18093
18094            // Explicitly remove the old information in mRecentTasks.
18095            removeRecentTasksForUserLocked(userId);
18096        }
18097
18098        for (int i=0; i<callbacks.size(); i++) {
18099            try {
18100                if (stopped) callbacks.get(i).userStopped(userId);
18101                else callbacks.get(i).userStopAborted(userId);
18102            } catch (RemoteException e) {
18103            }
18104        }
18105
18106        if (stopped) {
18107            mSystemServiceManager.cleanupUser(userId);
18108            synchronized (this) {
18109                mStackSupervisor.removeUserLocked(userId);
18110            }
18111        }
18112    }
18113
18114    @Override
18115    public UserInfo getCurrentUser() {
18116        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18117                != PackageManager.PERMISSION_GRANTED) && (
18118                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18119                != PackageManager.PERMISSION_GRANTED)) {
18120            String msg = "Permission Denial: getCurrentUser() from pid="
18121                    + Binder.getCallingPid()
18122                    + ", uid=" + Binder.getCallingUid()
18123                    + " requires " + INTERACT_ACROSS_USERS;
18124            Slog.w(TAG, msg);
18125            throw new SecurityException(msg);
18126        }
18127        synchronized (this) {
18128            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18129        }
18130    }
18131
18132    int getCurrentUserIdLocked() {
18133        return mCurrentUserId;
18134    }
18135
18136    @Override
18137    public boolean isUserRunning(int userId, boolean orStopped) {
18138        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18139                != PackageManager.PERMISSION_GRANTED) {
18140            String msg = "Permission Denial: isUserRunning() from pid="
18141                    + Binder.getCallingPid()
18142                    + ", uid=" + Binder.getCallingUid()
18143                    + " requires " + INTERACT_ACROSS_USERS;
18144            Slog.w(TAG, msg);
18145            throw new SecurityException(msg);
18146        }
18147        synchronized (this) {
18148            return isUserRunningLocked(userId, orStopped);
18149        }
18150    }
18151
18152    boolean isUserRunningLocked(int userId, boolean orStopped) {
18153        UserStartedState state = mStartedUsers.get(userId);
18154        if (state == null) {
18155            return false;
18156        }
18157        if (orStopped) {
18158            return true;
18159        }
18160        return state.mState != UserStartedState.STATE_STOPPING
18161                && state.mState != UserStartedState.STATE_SHUTDOWN;
18162    }
18163
18164    @Override
18165    public int[] getRunningUserIds() {
18166        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18167                != PackageManager.PERMISSION_GRANTED) {
18168            String msg = "Permission Denial: isUserRunning() from pid="
18169                    + Binder.getCallingPid()
18170                    + ", uid=" + Binder.getCallingUid()
18171                    + " requires " + INTERACT_ACROSS_USERS;
18172            Slog.w(TAG, msg);
18173            throw new SecurityException(msg);
18174        }
18175        synchronized (this) {
18176            return mStartedUserArray;
18177        }
18178    }
18179
18180    private void updateStartedUserArrayLocked() {
18181        int num = 0;
18182        for (int i=0; i<mStartedUsers.size();  i++) {
18183            UserStartedState uss = mStartedUsers.valueAt(i);
18184            // This list does not include stopping users.
18185            if (uss.mState != UserStartedState.STATE_STOPPING
18186                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18187                num++;
18188            }
18189        }
18190        mStartedUserArray = new int[num];
18191        num = 0;
18192        for (int i=0; i<mStartedUsers.size();  i++) {
18193            UserStartedState uss = mStartedUsers.valueAt(i);
18194            if (uss.mState != UserStartedState.STATE_STOPPING
18195                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18196                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18197                num++;
18198            }
18199        }
18200    }
18201
18202    @Override
18203    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18204        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18205                != PackageManager.PERMISSION_GRANTED) {
18206            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18207                    + Binder.getCallingPid()
18208                    + ", uid=" + Binder.getCallingUid()
18209                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18210            Slog.w(TAG, msg);
18211            throw new SecurityException(msg);
18212        }
18213
18214        mUserSwitchObservers.register(observer);
18215    }
18216
18217    @Override
18218    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18219        mUserSwitchObservers.unregister(observer);
18220    }
18221
18222    private boolean userExists(int userId) {
18223        if (userId == 0) {
18224            return true;
18225        }
18226        UserManagerService ums = getUserManagerLocked();
18227        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18228    }
18229
18230    int[] getUsersLocked() {
18231        UserManagerService ums = getUserManagerLocked();
18232        return ums != null ? ums.getUserIds() : new int[] { 0 };
18233    }
18234
18235    UserManagerService getUserManagerLocked() {
18236        if (mUserManager == null) {
18237            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18238            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18239        }
18240        return mUserManager;
18241    }
18242
18243    private int applyUserId(int uid, int userId) {
18244        return UserHandle.getUid(userId, uid);
18245    }
18246
18247    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18248        if (info == null) return null;
18249        ApplicationInfo newInfo = new ApplicationInfo(info);
18250        newInfo.uid = applyUserId(info.uid, userId);
18251        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18252                + info.packageName;
18253        return newInfo;
18254    }
18255
18256    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18257        if (aInfo == null
18258                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18259            return aInfo;
18260        }
18261
18262        ActivityInfo info = new ActivityInfo(aInfo);
18263        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18264        return info;
18265    }
18266
18267    private final class LocalService extends ActivityManagerInternal {
18268        @Override
18269        public void goingToSleep() {
18270            ActivityManagerService.this.goingToSleep();
18271        }
18272
18273        @Override
18274        public void wakingUp() {
18275            ActivityManagerService.this.wakingUp();
18276        }
18277
18278        @Override
18279        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18280                String processName, String abiOverride, int uid, Runnable crashHandler) {
18281            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18282                    processName, abiOverride, uid, crashHandler);
18283        }
18284    }
18285
18286    /**
18287     * An implementation of IAppTask, that allows an app to manage its own tasks via
18288     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18289     * only the process that calls getAppTasks() can call the AppTask methods.
18290     */
18291    class AppTaskImpl extends IAppTask.Stub {
18292        private int mTaskId;
18293        private int mCallingUid;
18294
18295        public AppTaskImpl(int taskId, int callingUid) {
18296            mTaskId = taskId;
18297            mCallingUid = callingUid;
18298        }
18299
18300        private void checkCaller() {
18301            if (mCallingUid != Binder.getCallingUid()) {
18302                throw new SecurityException("Caller " + mCallingUid
18303                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18304            }
18305        }
18306
18307        @Override
18308        public void finishAndRemoveTask() {
18309            checkCaller();
18310
18311            synchronized (ActivityManagerService.this) {
18312                long origId = Binder.clearCallingIdentity();
18313                try {
18314                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18315                    if (tr == null) {
18316                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18317                    }
18318                    // Only kill the process if we are not a new document
18319                    int flags = tr.getBaseIntent().getFlags();
18320                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18321                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18322                    removeTaskByIdLocked(mTaskId,
18323                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18324                } finally {
18325                    Binder.restoreCallingIdentity(origId);
18326                }
18327            }
18328        }
18329
18330        @Override
18331        public ActivityManager.RecentTaskInfo getTaskInfo() {
18332            checkCaller();
18333
18334            synchronized (ActivityManagerService.this) {
18335                long origId = Binder.clearCallingIdentity();
18336                try {
18337                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18338                    if (tr == null) {
18339                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18340                    }
18341                    return createRecentTaskInfoFromTaskRecord(tr);
18342                } finally {
18343                    Binder.restoreCallingIdentity(origId);
18344                }
18345            }
18346        }
18347
18348        @Override
18349        public void moveToFront() {
18350            checkCaller();
18351
18352            final TaskRecord tr;
18353            synchronized (ActivityManagerService.this) {
18354                tr = recentTaskForIdLocked(mTaskId);
18355                if (tr == null) {
18356                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18357                }
18358                if (tr.getRootActivity() != null) {
18359                    long origId = Binder.clearCallingIdentity();
18360                    try {
18361                        moveTaskToFrontLocked(tr.taskId, 0, null);
18362                        return;
18363                    } finally {
18364                        Binder.restoreCallingIdentity(origId);
18365                    }
18366                }
18367            }
18368
18369            startActivityFromRecentsInner(tr.taskId, null);
18370        }
18371
18372        @Override
18373        public int startActivity(IBinder whoThread, String callingPackage,
18374                Intent intent, String resolvedType, Bundle options) {
18375            checkCaller();
18376
18377            int callingUser = UserHandle.getCallingUserId();
18378            TaskRecord tr;
18379            IApplicationThread appThread;
18380            synchronized (ActivityManagerService.this) {
18381                tr = recentTaskForIdLocked(mTaskId);
18382                if (tr == null) {
18383                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18384                }
18385                appThread = ApplicationThreadNative.asInterface(whoThread);
18386                if (appThread == null) {
18387                    throw new IllegalArgumentException("Bad app thread " + appThread);
18388                }
18389            }
18390            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18391                    resolvedType, null, null, null, null, 0, 0, null, null,
18392                    null, null, options, callingUser, null, tr);
18393        }
18394
18395        @Override
18396        public void setExcludeFromRecents(boolean exclude) {
18397            checkCaller();
18398
18399            synchronized (ActivityManagerService.this) {
18400                long origId = Binder.clearCallingIdentity();
18401                try {
18402                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18403                    if (tr == null) {
18404                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18405                    }
18406                    Intent intent = tr.getBaseIntent();
18407                    if (exclude) {
18408                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18409                    } else {
18410                        intent.setFlags(intent.getFlags()
18411                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18412                    }
18413                } finally {
18414                    Binder.restoreCallingIdentity(origId);
18415                }
18416            }
18417        }
18418    }
18419}
18420