ActivityManagerService.java revision 1b012d302b56b4adf950035136d1d191a1936d5a
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199
200import java.io.BufferedInputStream;
201import java.io.BufferedOutputStream;
202import java.io.DataInputStream;
203import java.io.DataOutputStream;
204import java.io.File;
205import java.io.FileDescriptor;
206import java.io.FileInputStream;
207import java.io.FileNotFoundException;
208import java.io.FileOutputStream;
209import java.io.IOException;
210import java.io.InputStreamReader;
211import java.io.PrintWriter;
212import java.io.StringWriter;
213import java.lang.ref.WeakReference;
214import java.util.ArrayList;
215import java.util.Arrays;
216import java.util.Collections;
217import java.util.Comparator;
218import java.util.HashMap;
219import java.util.HashSet;
220import java.util.Iterator;
221import java.util.List;
222import java.util.Locale;
223import java.util.Map;
224import java.util.Set;
225import java.util.concurrent.atomic.AtomicBoolean;
226import java.util.concurrent.atomic.AtomicLong;
227
228public final class ActivityManagerService extends ActivityManagerNative
229        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
230
231    private static final String USER_DATA_DIR = "/data/user/";
232    // File that stores last updated system version and called preboot receivers
233    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
234
235    static final String TAG = "ActivityManager";
236    static final String TAG_MU = "ActivityManagerServiceMU";
237    static final boolean DEBUG = false;
238    static final boolean localLOGV = DEBUG;
239    static final boolean DEBUG_BACKUP = localLOGV || false;
240    static final boolean DEBUG_BROADCAST = localLOGV || false;
241    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_CLEANUP = localLOGV || false;
244    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
245    static final boolean DEBUG_FOCUS = false;
246    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
247    static final boolean DEBUG_MU = localLOGV || false;
248    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
249    static final boolean DEBUG_LRU = localLOGV || false;
250    static final boolean DEBUG_PAUSE = localLOGV || false;
251    static final boolean DEBUG_POWER = localLOGV || false;
252    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
253    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
254    static final boolean DEBUG_PROCESSES = localLOGV || false;
255    static final boolean DEBUG_PROVIDER = localLOGV || false;
256    static final boolean DEBUG_RESULTS = localLOGV || false;
257    static final boolean DEBUG_SERVICE = localLOGV || false;
258    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
259    static final boolean DEBUG_STACK = localLOGV || false;
260    static final boolean DEBUG_SWITCH = localLOGV || false;
261    static final boolean DEBUG_TASKS = localLOGV || false;
262    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
263    static final boolean DEBUG_TRANSITION = localLOGV || false;
264    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
265    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
266    static final boolean DEBUG_VISBILITY = localLOGV || false;
267    static final boolean DEBUG_PSS = localLOGV || false;
268    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
269    static final boolean DEBUG_RECENTS = localLOGV || false;
270    static final boolean VALIDATE_TOKENS = false;
271    static final boolean SHOW_ACTIVITY_START_TIME = true;
272
273    // Control over CPU and battery monitoring.
274    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
275    static final boolean MONITOR_CPU_USAGE = true;
276    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
277    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
278    static final boolean MONITOR_THREAD_CPU_USAGE = false;
279
280    // The flags that are set for all calls we make to the package manager.
281    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
282
283    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
284
285    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
286
287    // Maximum number of recent tasks that we can remember.
288    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
289
290    // Maximum number recent bitmaps to keep in memory.
291    static final int MAX_RECENT_BITMAPS = 5;
292
293    // Amount of time after a call to stopAppSwitches() during which we will
294    // prevent further untrusted switches from happening.
295    static final long APP_SWITCH_DELAY_TIME = 5*1000;
296
297    // How long we wait for a launched process to attach to the activity manager
298    // before we decide it's never going to come up for real.
299    static final int PROC_START_TIMEOUT = 10*1000;
300
301    // How long we wait for a launched process to attach to the activity manager
302    // before we decide it's never going to come up for real, when the process was
303    // started with a wrapper for instrumentation (such as Valgrind) because it
304    // could take much longer than usual.
305    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
306
307    // How long to wait after going idle before forcing apps to GC.
308    static final int GC_TIMEOUT = 5*1000;
309
310    // The minimum amount of time between successive GC requests for a process.
311    static final int GC_MIN_INTERVAL = 60*1000;
312
313    // The minimum amount of time between successive PSS requests for a process.
314    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process
317    // when the request is due to the memory state being lowered.
318    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
319
320    // The rate at which we check for apps using excessive power -- 15 mins.
321    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
322
323    // The minimum sample duration we will allow before deciding we have
324    // enough data on wake locks to start killing things.
325    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
326
327    // The minimum sample duration we will allow before deciding we have
328    // enough data on CPU usage to start killing things.
329    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
330
331    // How long we allow a receiver to run before giving up on it.
332    static final int BROADCAST_FG_TIMEOUT = 10*1000;
333    static final int BROADCAST_BG_TIMEOUT = 60*1000;
334
335    // How long we wait until we timeout on key dispatching.
336    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
337
338    // How long we wait until we timeout on key dispatching during instrumentation.
339    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
340
341    // Amount of time we wait for observers to handle a user switch before
342    // giving up on them and unfreezing the screen.
343    static final int USER_SWITCH_TIMEOUT = 2*1000;
344
345    // Maximum number of users we allow to be running at a time.
346    static final int MAX_RUNNING_USERS = 3;
347
348    // How long to wait in getAssistContextExtras for the activity and foreground services
349    // to respond with the result.
350    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
351
352    // Maximum number of persisted Uri grants a package is allowed
353    static final int MAX_PERSISTED_URI_GRANTS = 128;
354
355    static final int MY_PID = Process.myPid();
356
357    static final String[] EMPTY_STRING_ARRAY = new String[0];
358
359    // How many bytes to write into the dropbox log before truncating
360    static final int DROPBOX_MAX_SIZE = 256 * 1024;
361
362    // Access modes for handleIncomingUser.
363    static final int ALLOW_NON_FULL = 0;
364    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
365    static final int ALLOW_FULL_ONLY = 2;
366
367    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
368
369    /** All system services */
370    SystemServiceManager mSystemServiceManager;
371
372    /** Run all ActivityStacks through this */
373    ActivityStackSupervisor mStackSupervisor;
374
375    public IntentFirewall mIntentFirewall;
376
377    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
378    // default actuion automatically.  Important for devices without direct input
379    // devices.
380    private boolean mShowDialogs = true;
381
382    BroadcastQueue mFgBroadcastQueue;
383    BroadcastQueue mBgBroadcastQueue;
384    // Convenient for easy iteration over the queues. Foreground is first
385    // so that dispatch of foreground broadcasts gets precedence.
386    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
387
388    BroadcastQueue broadcastQueueForIntent(Intent intent) {
389        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
390        if (DEBUG_BACKGROUND_BROADCAST) {
391            Slog.i(TAG, "Broadcast intent " + intent + " on "
392                    + (isFg ? "foreground" : "background")
393                    + " queue");
394        }
395        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
396    }
397
398    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
399        for (BroadcastQueue queue : mBroadcastQueues) {
400            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
401            if (r != null) {
402                return r;
403            }
404        }
405        return null;
406    }
407
408    /**
409     * Activity we have told the window manager to have key focus.
410     */
411    ActivityRecord mFocusedActivity = null;
412
413    /**
414     * List of intents that were used to start the most recent tasks.
415     */
416    ArrayList<TaskRecord> mRecentTasks;
417    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
418
419    /**
420     * For addAppTask: cached of the last activity component that was added.
421     */
422    ComponentName mLastAddedTaskComponent;
423
424    /**
425     * For addAppTask: cached of the last activity uid that was added.
426     */
427    int mLastAddedTaskUid;
428
429    /**
430     * For addAppTask: cached of the last ActivityInfo that was added.
431     */
432    ActivityInfo mLastAddedTaskActivity;
433
434    public class PendingAssistExtras extends Binder implements Runnable {
435        public final ActivityRecord activity;
436        public boolean haveResult = false;
437        public Bundle result = null;
438        public PendingAssistExtras(ActivityRecord _activity) {
439            activity = _activity;
440        }
441        @Override
442        public void run() {
443            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
444            synchronized (this) {
445                haveResult = true;
446                notifyAll();
447            }
448        }
449    }
450
451    final ArrayList<PendingAssistExtras> mPendingAssistExtras
452            = new ArrayList<PendingAssistExtras>();
453
454    /**
455     * Process management.
456     */
457    final ProcessList mProcessList = new ProcessList();
458
459    /**
460     * All of the applications we currently have running organized by name.
461     * The keys are strings of the application package name (as
462     * returned by the package manager), and the keys are ApplicationRecord
463     * objects.
464     */
465    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
466
467    /**
468     * Tracking long-term execution of processes to look for abuse and other
469     * bad app behavior.
470     */
471    final ProcessStatsService mProcessStats;
472
473    /**
474     * The currently running isolated processes.
475     */
476    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
477
478    /**
479     * Counter for assigning isolated process uids, to avoid frequently reusing the
480     * same ones.
481     */
482    int mNextIsolatedProcessUid = 0;
483
484    /**
485     * The currently running heavy-weight process, if any.
486     */
487    ProcessRecord mHeavyWeightProcess = null;
488
489    /**
490     * The last time that various processes have crashed.
491     */
492    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
493
494    /**
495     * Information about a process that is currently marked as bad.
496     */
497    static final class BadProcessInfo {
498        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
499            this.time = time;
500            this.shortMsg = shortMsg;
501            this.longMsg = longMsg;
502            this.stack = stack;
503        }
504
505        final long time;
506        final String shortMsg;
507        final String longMsg;
508        final String stack;
509    }
510
511    /**
512     * Set of applications that we consider to be bad, and will reject
513     * incoming broadcasts from (which the user has no control over).
514     * Processes are added to this set when they have crashed twice within
515     * a minimum amount of time; they are removed from it when they are
516     * later restarted (hopefully due to some user action).  The value is the
517     * time it was added to the list.
518     */
519    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
520
521    /**
522     * All of the processes we currently have running organized by pid.
523     * The keys are the pid running the application.
524     *
525     * <p>NOTE: This object is protected by its own lock, NOT the global
526     * activity manager lock!
527     */
528    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
529
530    /**
531     * All of the processes that have been forced to be foreground.  The key
532     * is the pid of the caller who requested it (we hold a death
533     * link on it).
534     */
535    abstract class ForegroundToken implements IBinder.DeathRecipient {
536        int pid;
537        IBinder token;
538    }
539    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
540
541    /**
542     * List of records for processes that someone had tried to start before the
543     * system was ready.  We don't start them at that point, but ensure they
544     * are started by the time booting is complete.
545     */
546    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
547
548    /**
549     * List of persistent applications that are in the process
550     * of being started.
551     */
552    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Processes that are being forcibly torn down.
556     */
557    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
558
559    /**
560     * List of running applications, sorted by recent usage.
561     * The first entry in the list is the least recently used.
562     */
563    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Where in mLruProcesses that the processes hosting activities start.
567     */
568    int mLruProcessActivityStart = 0;
569
570    /**
571     * Where in mLruProcesses that the processes hosting services start.
572     * This is after (lower index) than mLruProcessesActivityStart.
573     */
574    int mLruProcessServiceStart = 0;
575
576    /**
577     * List of processes that should gc as soon as things are idle.
578     */
579    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
580
581    /**
582     * Processes we want to collect PSS data from.
583     */
584    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
585
586    /**
587     * Last time we requested PSS data of all processes.
588     */
589    long mLastFullPssTime = SystemClock.uptimeMillis();
590
591    /**
592     * If set, the next time we collect PSS data we should do a full collection
593     * with data from native processes and the kernel.
594     */
595    boolean mFullPssPending = false;
596
597    /**
598     * This is the process holding what we currently consider to be
599     * the "home" activity.
600     */
601    ProcessRecord mHomeProcess;
602
603    /**
604     * This is the process holding the activity the user last visited that
605     * is in a different process from the one they are currently in.
606     */
607    ProcessRecord mPreviousProcess;
608
609    /**
610     * The time at which the previous process was last visible.
611     */
612    long mPreviousProcessVisibleTime;
613
614    /**
615     * Which uses have been started, so are allowed to run code.
616     */
617    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
618
619    /**
620     * LRU list of history of current users.  Most recently current is at the end.
621     */
622    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
623
624    /**
625     * Constant array of the users that are currently started.
626     */
627    int[] mStartedUserArray = new int[] { 0 };
628
629    /**
630     * Registered observers of the user switching mechanics.
631     */
632    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
633            = new RemoteCallbackList<IUserSwitchObserver>();
634
635    /**
636     * Currently active user switch.
637     */
638    Object mCurUserSwitchCallback;
639
640    /**
641     * Packages that the user has asked to have run in screen size
642     * compatibility mode instead of filling the screen.
643     */
644    final CompatModePackages mCompatModePackages;
645
646    /**
647     * Set of IntentSenderRecord objects that are currently active.
648     */
649    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
650            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
651
652    /**
653     * Fingerprints (hashCode()) of stack traces that we've
654     * already logged DropBox entries for.  Guarded by itself.  If
655     * something (rogue user app) forces this over
656     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
657     */
658    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
659    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
660
661    /**
662     * Strict Mode background batched logging state.
663     *
664     * The string buffer is guarded by itself, and its lock is also
665     * used to determine if another batched write is already
666     * in-flight.
667     */
668    private final StringBuilder mStrictModeBuffer = new StringBuilder();
669
670    /**
671     * Keeps track of all IIntentReceivers that have been registered for
672     * broadcasts.  Hash keys are the receiver IBinder, hash value is
673     * a ReceiverList.
674     */
675    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
676            new HashMap<IBinder, ReceiverList>();
677
678    /**
679     * Resolver for broadcast intents to registered receivers.
680     * Holds BroadcastFilter (subclass of IntentFilter).
681     */
682    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
683            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
684        @Override
685        protected boolean allowFilterResult(
686                BroadcastFilter filter, List<BroadcastFilter> dest) {
687            IBinder target = filter.receiverList.receiver.asBinder();
688            for (int i=dest.size()-1; i>=0; i--) {
689                if (dest.get(i).receiverList.receiver.asBinder() == target) {
690                    return false;
691                }
692            }
693            return true;
694        }
695
696        @Override
697        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
698            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
699                    || userId == filter.owningUserId) {
700                return super.newResult(filter, match, userId);
701            }
702            return null;
703        }
704
705        @Override
706        protected BroadcastFilter[] newArray(int size) {
707            return new BroadcastFilter[size];
708        }
709
710        @Override
711        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
712            return packageName.equals(filter.packageName);
713        }
714    };
715
716    /**
717     * State of all active sticky broadcasts per user.  Keys are the action of the
718     * sticky Intent, values are an ArrayList of all broadcasted intents with
719     * that action (which should usually be one).  The SparseArray is keyed
720     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
721     * for stickies that are sent to all users.
722     */
723    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
724            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
725
726    final ActiveServices mServices;
727
728    /**
729     * Backup/restore process management
730     */
731    String mBackupAppName = null;
732    BackupRecord mBackupTarget = null;
733
734    final ProviderMap mProviderMap;
735
736    /**
737     * List of content providers who have clients waiting for them.  The
738     * application is currently being launched and the provider will be
739     * removed from this list once it is published.
740     */
741    final ArrayList<ContentProviderRecord> mLaunchingProviders
742            = new ArrayList<ContentProviderRecord>();
743
744    /**
745     * File storing persisted {@link #mGrantedUriPermissions}.
746     */
747    private final AtomicFile mGrantFile;
748
749    /** XML constants used in {@link #mGrantFile} */
750    private static final String TAG_URI_GRANTS = "uri-grants";
751    private static final String TAG_URI_GRANT = "uri-grant";
752    private static final String ATTR_USER_HANDLE = "userHandle";
753    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
754    private static final String ATTR_TARGET_USER_ID = "targetUserId";
755    private static final String ATTR_SOURCE_PKG = "sourcePkg";
756    private static final String ATTR_TARGET_PKG = "targetPkg";
757    private static final String ATTR_URI = "uri";
758    private static final String ATTR_MODE_FLAGS = "modeFlags";
759    private static final String ATTR_CREATED_TIME = "createdTime";
760    private static final String ATTR_PREFIX = "prefix";
761
762    /**
763     * Global set of specific {@link Uri} permissions that have been granted.
764     * This optimized lookup structure maps from {@link UriPermission#targetUid}
765     * to {@link UriPermission#uri} to {@link UriPermission}.
766     */
767    @GuardedBy("this")
768    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
769            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
770
771    public static class GrantUri {
772        public final int sourceUserId;
773        public final Uri uri;
774        public boolean prefix;
775
776        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
777            this.sourceUserId = sourceUserId;
778            this.uri = uri;
779            this.prefix = prefix;
780        }
781
782        @Override
783        public int hashCode() {
784            return toString().hashCode();
785        }
786
787        @Override
788        public boolean equals(Object o) {
789            if (o instanceof GrantUri) {
790                GrantUri other = (GrantUri) o;
791                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
792                        && prefix == other.prefix;
793            }
794            return false;
795        }
796
797        @Override
798        public String toString() {
799            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
800            if (prefix) result += " [prefix]";
801            return result;
802        }
803
804        public String toSafeString() {
805            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
806            if (prefix) result += " [prefix]";
807            return result;
808        }
809
810        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
811            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
812                    ContentProvider.getUriWithoutUserId(uri), false);
813        }
814    }
815
816    CoreSettingsObserver mCoreSettingsObserver;
817
818    /**
819     * Thread-local storage used to carry caller permissions over through
820     * indirect content-provider access.
821     */
822    private class Identity {
823        public int pid;
824        public int uid;
825
826        Identity(int _pid, int _uid) {
827            pid = _pid;
828            uid = _uid;
829        }
830    }
831
832    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
833
834    /**
835     * All information we have collected about the runtime performance of
836     * any user id that can impact battery performance.
837     */
838    final BatteryStatsService mBatteryStatsService;
839
840    /**
841     * Information about component usage
842     */
843    UsageStatsManagerInternal mUsageStatsService;
844
845    /**
846     * Information about and control over application operations
847     */
848    final AppOpsService mAppOpsService;
849
850    /**
851     * Save recent tasks information across reboots.
852     */
853    final TaskPersister mTaskPersister;
854
855    /**
856     * Current configuration information.  HistoryRecord objects are given
857     * a reference to this object to indicate which configuration they are
858     * currently running in, so this object must be kept immutable.
859     */
860    Configuration mConfiguration = new Configuration();
861
862    /**
863     * Current sequencing integer of the configuration, for skipping old
864     * configurations.
865     */
866    int mConfigurationSeq = 0;
867
868    /**
869     * Hardware-reported OpenGLES version.
870     */
871    final int GL_ES_VERSION;
872
873    /**
874     * List of initialization arguments to pass to all processes when binding applications to them.
875     * For example, references to the commonly used services.
876     */
877    HashMap<String, IBinder> mAppBindArgs;
878
879    /**
880     * Temporary to avoid allocations.  Protected by main lock.
881     */
882    final StringBuilder mStringBuilder = new StringBuilder(256);
883
884    /**
885     * Used to control how we initialize the service.
886     */
887    ComponentName mTopComponent;
888    String mTopAction = Intent.ACTION_MAIN;
889    String mTopData;
890    boolean mProcessesReady = false;
891    boolean mSystemReady = false;
892    boolean mBooting = false;
893    boolean mWaitingUpdate = false;
894    boolean mDidUpdate = false;
895    boolean mOnBattery = false;
896    boolean mLaunchWarningShown = false;
897
898    Context mContext;
899
900    int mFactoryTest;
901
902    boolean mCheckedForSetup;
903
904    /**
905     * The time at which we will allow normal application switches again,
906     * after a call to {@link #stopAppSwitches()}.
907     */
908    long mAppSwitchesAllowedTime;
909
910    /**
911     * This is set to true after the first switch after mAppSwitchesAllowedTime
912     * is set; any switches after that will clear the time.
913     */
914    boolean mDidAppSwitch;
915
916    /**
917     * Last time (in realtime) at which we checked for power usage.
918     */
919    long mLastPowerCheckRealtime;
920
921    /**
922     * Last time (in uptime) at which we checked for power usage.
923     */
924    long mLastPowerCheckUptime;
925
926    /**
927     * Set while we are wanting to sleep, to prevent any
928     * activities from being started/resumed.
929     */
930    private boolean mSleeping = false;
931
932    /**
933     * Set while we are running a voice interaction.  This overrides
934     * sleeping while it is active.
935     */
936    private boolean mRunningVoice = false;
937
938    /**
939     * State of external calls telling us if the device is asleep.
940     */
941    private boolean mWentToSleep = false;
942
943    /**
944     * State of external call telling us if the lock screen is shown.
945     */
946    private boolean mLockScreenShown = false;
947
948    /**
949     * Set if we are shutting down the system, similar to sleeping.
950     */
951    boolean mShuttingDown = false;
952
953    /**
954     * Current sequence id for oom_adj computation traversal.
955     */
956    int mAdjSeq = 0;
957
958    /**
959     * Current sequence id for process LRU updating.
960     */
961    int mLruSeq = 0;
962
963    /**
964     * Keep track of the non-cached/empty process we last found, to help
965     * determine how to distribute cached/empty processes next time.
966     */
967    int mNumNonCachedProcs = 0;
968
969    /**
970     * Keep track of the number of cached hidden procs, to balance oom adj
971     * distribution between those and empty procs.
972     */
973    int mNumCachedHiddenProcs = 0;
974
975    /**
976     * Keep track of the number of service processes we last found, to
977     * determine on the next iteration which should be B services.
978     */
979    int mNumServiceProcs = 0;
980    int mNewNumAServiceProcs = 0;
981    int mNewNumServiceProcs = 0;
982
983    /**
984     * Allow the current computed overall memory level of the system to go down?
985     * This is set to false when we are killing processes for reasons other than
986     * memory management, so that the now smaller process list will not be taken as
987     * an indication that memory is tighter.
988     */
989    boolean mAllowLowerMemLevel = false;
990
991    /**
992     * The last computed memory level, for holding when we are in a state that
993     * processes are going away for other reasons.
994     */
995    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
996
997    /**
998     * The last total number of process we have, to determine if changes actually look
999     * like a shrinking number of process due to lower RAM.
1000     */
1001    int mLastNumProcesses;
1002
1003    /**
1004     * The uptime of the last time we performed idle maintenance.
1005     */
1006    long mLastIdleTime = SystemClock.uptimeMillis();
1007
1008    /**
1009     * Total time spent with RAM that has been added in the past since the last idle time.
1010     */
1011    long mLowRamTimeSinceLastIdle = 0;
1012
1013    /**
1014     * If RAM is currently low, when that horrible situation started.
1015     */
1016    long mLowRamStartTime = 0;
1017
1018    /**
1019     * For reporting to battery stats the current top application.
1020     */
1021    private String mCurResumedPackage = null;
1022    private int mCurResumedUid = -1;
1023
1024    /**
1025     * For reporting to battery stats the apps currently running foreground
1026     * service.  The ProcessMap is package/uid tuples; each of these contain
1027     * an array of the currently foreground processes.
1028     */
1029    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1030            = new ProcessMap<ArrayList<ProcessRecord>>();
1031
1032    /**
1033     * This is set if we had to do a delayed dexopt of an app before launching
1034     * it, to increase the ANR timeouts in that case.
1035     */
1036    boolean mDidDexOpt;
1037
1038    /**
1039     * Set if the systemServer made a call to enterSafeMode.
1040     */
1041    boolean mSafeMode;
1042
1043    String mDebugApp = null;
1044    boolean mWaitForDebugger = false;
1045    boolean mDebugTransient = false;
1046    String mOrigDebugApp = null;
1047    boolean mOrigWaitForDebugger = false;
1048    boolean mAlwaysFinishActivities = false;
1049    IActivityController mController = null;
1050    String mProfileApp = null;
1051    ProcessRecord mProfileProc = null;
1052    String mProfileFile;
1053    ParcelFileDescriptor mProfileFd;
1054    int mSamplingInterval = 0;
1055    boolean mAutoStopProfiler = false;
1056    int mProfileType = 0;
1057    String mOpenGlTraceApp = null;
1058
1059    static class ProcessChangeItem {
1060        static final int CHANGE_ACTIVITIES = 1<<0;
1061        static final int CHANGE_PROCESS_STATE = 1<<1;
1062        int changes;
1063        int uid;
1064        int pid;
1065        int processState;
1066        boolean foregroundActivities;
1067    }
1068
1069    final RemoteCallbackList<IProcessObserver> mProcessObservers
1070            = new RemoteCallbackList<IProcessObserver>();
1071    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1072
1073    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1076            = new ArrayList<ProcessChangeItem>();
1077
1078    /**
1079     * Runtime CPU use collection thread.  This object's lock is used to
1080     * protect all related state.
1081     */
1082    final Thread mProcessCpuThread;
1083
1084    /**
1085     * Used to collect process stats when showing not responding dialog.
1086     * Protected by mProcessCpuThread.
1087     */
1088    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1089            MONITOR_THREAD_CPU_USAGE);
1090    final AtomicLong mLastCpuTime = new AtomicLong(0);
1091    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1092
1093    long mLastWriteTime = 0;
1094
1095    /**
1096     * Used to retain an update lock when the foreground activity is in
1097     * immersive mode.
1098     */
1099    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1100
1101    /**
1102     * Set to true after the system has finished booting.
1103     */
1104    boolean mBooted = false;
1105
1106    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1107    int mProcessLimitOverride = -1;
1108
1109    WindowManagerService mWindowManager;
1110
1111    final ActivityThread mSystemThread;
1112
1113    int mCurrentUserId = 0;
1114    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1115
1116    /**
1117     * Mapping from each known user ID to the profile group ID it is associated with.
1118     */
1119    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1120
1121    private UserManagerService mUserManager;
1122
1123    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1124        final ProcessRecord mApp;
1125        final int mPid;
1126        final IApplicationThread mAppThread;
1127
1128        AppDeathRecipient(ProcessRecord app, int pid,
1129                IApplicationThread thread) {
1130            if (localLOGV) Slog.v(
1131                TAG, "New death recipient " + this
1132                + " for thread " + thread.asBinder());
1133            mApp = app;
1134            mPid = pid;
1135            mAppThread = thread;
1136        }
1137
1138        @Override
1139        public void binderDied() {
1140            if (localLOGV) Slog.v(
1141                TAG, "Death received in " + this
1142                + " for thread " + mAppThread.asBinder());
1143            synchronized(ActivityManagerService.this) {
1144                appDiedLocked(mApp, mPid, mAppThread);
1145            }
1146        }
1147    }
1148
1149    static final int SHOW_ERROR_MSG = 1;
1150    static final int SHOW_NOT_RESPONDING_MSG = 2;
1151    static final int SHOW_FACTORY_ERROR_MSG = 3;
1152    static final int UPDATE_CONFIGURATION_MSG = 4;
1153    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1154    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1155    static final int SERVICE_TIMEOUT_MSG = 12;
1156    static final int UPDATE_TIME_ZONE = 13;
1157    static final int SHOW_UID_ERROR_MSG = 14;
1158    static final int IM_FEELING_LUCKY_MSG = 15;
1159    static final int PROC_START_TIMEOUT_MSG = 20;
1160    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1161    static final int KILL_APPLICATION_MSG = 22;
1162    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1163    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1164    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1165    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1166    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1167    static final int CLEAR_DNS_CACHE_MSG = 28;
1168    static final int UPDATE_HTTP_PROXY_MSG = 29;
1169    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1170    static final int DISPATCH_PROCESSES_CHANGED = 31;
1171    static final int DISPATCH_PROCESS_DIED = 32;
1172    static final int REPORT_MEM_USAGE_MSG = 33;
1173    static final int REPORT_USER_SWITCH_MSG = 34;
1174    static final int CONTINUE_USER_SWITCH_MSG = 35;
1175    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1176    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1177    static final int PERSIST_URI_GRANTS_MSG = 38;
1178    static final int REQUEST_ALL_PSS_MSG = 39;
1179    static final int START_PROFILES_MSG = 40;
1180    static final int UPDATE_TIME = 41;
1181    static final int SYSTEM_USER_START_MSG = 42;
1182    static final int SYSTEM_USER_CURRENT_MSG = 43;
1183    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1184    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1185    static final int START_USER_SWITCH_MSG = 46;
1186
1187    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1188    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1189    static final int FIRST_COMPAT_MODE_MSG = 300;
1190    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1191
1192    AlertDialog mUidAlert;
1193    CompatModeDialog mCompatModeDialog;
1194    long mLastMemUsageReportTime = 0;
1195
1196    private LockToAppRequestDialog mLockToAppRequest;
1197
1198    /**
1199     * Flag whether the current user is a "monkey", i.e. whether
1200     * the UI is driven by a UI automation tool.
1201     */
1202    private boolean mUserIsMonkey;
1203
1204    /** Flag whether the device has a recents UI */
1205    final boolean mHasRecents;
1206
1207    final int mThumbnailWidth;
1208    final int mThumbnailHeight;
1209
1210    final ServiceThread mHandlerThread;
1211    final MainHandler mHandler;
1212
1213    final class MainHandler extends Handler {
1214        public MainHandler(Looper looper) {
1215            super(looper, null, true);
1216        }
1217
1218        @Override
1219        public void handleMessage(Message msg) {
1220            switch (msg.what) {
1221            case SHOW_ERROR_MSG: {
1222                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1223                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1224                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1225                synchronized (ActivityManagerService.this) {
1226                    ProcessRecord proc = (ProcessRecord)data.get("app");
1227                    AppErrorResult res = (AppErrorResult) data.get("result");
1228                    if (proc != null && proc.crashDialog != null) {
1229                        Slog.e(TAG, "App already has crash dialog: " + proc);
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                        return;
1234                    }
1235                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1236                            >= Process.FIRST_APPLICATION_UID
1237                            && proc.pid != MY_PID);
1238                    for (int userId : mCurrentProfileIds) {
1239                        isBackground &= (proc.userId != userId);
1240                    }
1241                    if (isBackground && !showBackground) {
1242                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1243                        if (res != null) {
1244                            res.set(0);
1245                        }
1246                        return;
1247                    }
1248                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1249                        Dialog d = new AppErrorDialog(mContext,
1250                                ActivityManagerService.this, res, proc);
1251                        d.show();
1252                        proc.crashDialog = d;
1253                    } else {
1254                        // The device is asleep, so just pretend that the user
1255                        // saw a crash dialog and hit "force quit".
1256                        if (res != null) {
1257                            res.set(0);
1258                        }
1259                    }
1260                }
1261
1262                ensureBootCompleted();
1263            } break;
1264            case SHOW_NOT_RESPONDING_MSG: {
1265                synchronized (ActivityManagerService.this) {
1266                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                    ProcessRecord proc = (ProcessRecord)data.get("app");
1268                    if (proc != null && proc.anrDialog != null) {
1269                        Slog.e(TAG, "App already has anr dialog: " + proc);
1270                        return;
1271                    }
1272
1273                    Intent intent = new Intent("android.intent.action.ANR");
1274                    if (!mProcessesReady) {
1275                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1276                                | Intent.FLAG_RECEIVER_FOREGROUND);
1277                    }
1278                    broadcastIntentLocked(null, null, intent,
1279                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1280                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1281
1282                    if (mShowDialogs) {
1283                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1284                                mContext, proc, (ActivityRecord)data.get("activity"),
1285                                msg.arg1 != 0);
1286                        d.show();
1287                        proc.anrDialog = d;
1288                    } else {
1289                        // Just kill the app if there is no dialog to be shown.
1290                        killAppAtUsersRequest(proc, null);
1291                    }
1292                }
1293
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1297                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1298                synchronized (ActivityManagerService.this) {
1299                    ProcessRecord proc = (ProcessRecord) data.get("app");
1300                    if (proc == null) {
1301                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1302                        break;
1303                    }
1304                    if (proc.crashDialog != null) {
1305                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1306                        return;
1307                    }
1308                    AppErrorResult res = (AppErrorResult) data.get("result");
1309                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1310                        Dialog d = new StrictModeViolationDialog(mContext,
1311                                ActivityManagerService.this, res, proc);
1312                        d.show();
1313                        proc.crashDialog = d;
1314                    } else {
1315                        // The device is asleep, so just pretend that the user
1316                        // saw a crash dialog and hit "force quit".
1317                        res.set(0);
1318                    }
1319                }
1320                ensureBootCompleted();
1321            } break;
1322            case SHOW_FACTORY_ERROR_MSG: {
1323                Dialog d = new FactoryErrorDialog(
1324                    mContext, msg.getData().getCharSequence("msg"));
1325                d.show();
1326                ensureBootCompleted();
1327            } break;
1328            case UPDATE_CONFIGURATION_MSG: {
1329                final ContentResolver resolver = mContext.getContentResolver();
1330                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1331            } break;
1332            case GC_BACKGROUND_PROCESSES_MSG: {
1333                synchronized (ActivityManagerService.this) {
1334                    performAppGcsIfAppropriateLocked();
1335                }
1336            } break;
1337            case WAIT_FOR_DEBUGGER_MSG: {
1338                synchronized (ActivityManagerService.this) {
1339                    ProcessRecord app = (ProcessRecord)msg.obj;
1340                    if (msg.arg1 != 0) {
1341                        if (!app.waitedForDebugger) {
1342                            Dialog d = new AppWaitingForDebuggerDialog(
1343                                    ActivityManagerService.this,
1344                                    mContext, app);
1345                            app.waitDialog = d;
1346                            app.waitedForDebugger = true;
1347                            d.show();
1348                        }
1349                    } else {
1350                        if (app.waitDialog != null) {
1351                            app.waitDialog.dismiss();
1352                            app.waitDialog = null;
1353                        }
1354                    }
1355                }
1356            } break;
1357            case SERVICE_TIMEOUT_MSG: {
1358                if (mDidDexOpt) {
1359                    mDidDexOpt = false;
1360                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1361                    nmsg.obj = msg.obj;
1362                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1363                    return;
1364                }
1365                mServices.serviceTimeout((ProcessRecord)msg.obj);
1366            } break;
1367            case UPDATE_TIME_ZONE: {
1368                synchronized (ActivityManagerService.this) {
1369                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1370                        ProcessRecord r = mLruProcesses.get(i);
1371                        if (r.thread != null) {
1372                            try {
1373                                r.thread.updateTimeZone();
1374                            } catch (RemoteException ex) {
1375                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1376                            }
1377                        }
1378                    }
1379                }
1380            } break;
1381            case CLEAR_DNS_CACHE_MSG: {
1382                synchronized (ActivityManagerService.this) {
1383                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1384                        ProcessRecord r = mLruProcesses.get(i);
1385                        if (r.thread != null) {
1386                            try {
1387                                r.thread.clearDnsCache();
1388                            } catch (RemoteException ex) {
1389                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case UPDATE_HTTP_PROXY_MSG: {
1396                ProxyInfo proxy = (ProxyInfo)msg.obj;
1397                String host = "";
1398                String port = "";
1399                String exclList = "";
1400                Uri pacFileUrl = Uri.EMPTY;
1401                if (proxy != null) {
1402                    host = proxy.getHost();
1403                    port = Integer.toString(proxy.getPort());
1404                    exclList = proxy.getExclusionListAsString();
1405                    pacFileUrl = proxy.getPacFileUrl();
1406                }
1407                synchronized (ActivityManagerService.this) {
1408                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1409                        ProcessRecord r = mLruProcesses.get(i);
1410                        if (r.thread != null) {
1411                            try {
1412                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1413                            } catch (RemoteException ex) {
1414                                Slog.w(TAG, "Failed to update http proxy for: " +
1415                                        r.info.processName);
1416                            }
1417                        }
1418                    }
1419                }
1420            } break;
1421            case SHOW_UID_ERROR_MSG: {
1422                String title = "System UIDs Inconsistent";
1423                String text = "UIDs on the system are inconsistent, you need to wipe your"
1424                        + " data partition or your device will be unstable.";
1425                Log.e(TAG, title + ": " + text);
1426                if (mShowDialogs) {
1427                    // XXX This is a temporary dialog, no need to localize.
1428                    AlertDialog d = new BaseErrorDialog(mContext);
1429                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1430                    d.setCancelable(false);
1431                    d.setTitle(title);
1432                    d.setMessage(text);
1433                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1434                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1435                    mUidAlert = d;
1436                    d.show();
1437                }
1438            } break;
1439            case IM_FEELING_LUCKY_MSG: {
1440                if (mUidAlert != null) {
1441                    mUidAlert.dismiss();
1442                    mUidAlert = null;
1443                }
1444            } break;
1445            case PROC_START_TIMEOUT_MSG: {
1446                if (mDidDexOpt) {
1447                    mDidDexOpt = false;
1448                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1449                    nmsg.obj = msg.obj;
1450                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1451                    return;
1452                }
1453                ProcessRecord app = (ProcessRecord)msg.obj;
1454                synchronized (ActivityManagerService.this) {
1455                    processStartTimedOutLocked(app);
1456                }
1457            } break;
1458            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1459                synchronized (ActivityManagerService.this) {
1460                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1461                }
1462            } break;
1463            case KILL_APPLICATION_MSG: {
1464                synchronized (ActivityManagerService.this) {
1465                    int appid = msg.arg1;
1466                    boolean restart = (msg.arg2 == 1);
1467                    Bundle bundle = (Bundle)msg.obj;
1468                    String pkg = bundle.getString("pkg");
1469                    String reason = bundle.getString("reason");
1470                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1471                            false, UserHandle.USER_ALL, reason);
1472                }
1473            } break;
1474            case FINALIZE_PENDING_INTENT_MSG: {
1475                ((PendingIntentRecord)msg.obj).completeFinalize();
1476            } break;
1477            case POST_HEAVY_NOTIFICATION_MSG: {
1478                INotificationManager inm = NotificationManager.getService();
1479                if (inm == null) {
1480                    return;
1481                }
1482
1483                ActivityRecord root = (ActivityRecord)msg.obj;
1484                ProcessRecord process = root.app;
1485                if (process == null) {
1486                    return;
1487                }
1488
1489                try {
1490                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1491                    String text = mContext.getString(R.string.heavy_weight_notification,
1492                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1493                    Notification notification = new Notification();
1494                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1495                    notification.when = 0;
1496                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1497                    notification.tickerText = text;
1498                    notification.defaults = 0; // please be quiet
1499                    notification.sound = null;
1500                    notification.vibrate = null;
1501                    notification.color = mContext.getResources().getColor(
1502                            com.android.internal.R.color.system_notification_accent_color);
1503                    notification.setLatestEventInfo(context, text,
1504                            mContext.getText(R.string.heavy_weight_notification_detail),
1505                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1506                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1507                                    new UserHandle(root.userId)));
1508
1509                    try {
1510                        int[] outId = new int[1];
1511                        inm.enqueueNotificationWithTag("android", "android", null,
1512                                R.string.heavy_weight_notification,
1513                                notification, outId, root.userId);
1514                    } catch (RuntimeException e) {
1515                        Slog.w(ActivityManagerService.TAG,
1516                                "Error showing notification for heavy-weight app", e);
1517                    } catch (RemoteException e) {
1518                    }
1519                } catch (NameNotFoundException e) {
1520                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1521                }
1522            } break;
1523            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1524                INotificationManager inm = NotificationManager.getService();
1525                if (inm == null) {
1526                    return;
1527                }
1528                try {
1529                    inm.cancelNotificationWithTag("android", null,
1530                            R.string.heavy_weight_notification,  msg.arg1);
1531                } catch (RuntimeException e) {
1532                    Slog.w(ActivityManagerService.TAG,
1533                            "Error canceling notification for service", e);
1534                } catch (RemoteException e) {
1535                }
1536            } break;
1537            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1538                synchronized (ActivityManagerService.this) {
1539                    checkExcessivePowerUsageLocked(true);
1540                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1541                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1542                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1543                }
1544            } break;
1545            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1546                synchronized (ActivityManagerService.this) {
1547                    ActivityRecord ar = (ActivityRecord)msg.obj;
1548                    if (mCompatModeDialog != null) {
1549                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1550                                ar.info.applicationInfo.packageName)) {
1551                            return;
1552                        }
1553                        mCompatModeDialog.dismiss();
1554                        mCompatModeDialog = null;
1555                    }
1556                    if (ar != null && false) {
1557                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1558                                ar.packageName)) {
1559                            int mode = mCompatModePackages.computeCompatModeLocked(
1560                                    ar.info.applicationInfo);
1561                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1562                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1563                                mCompatModeDialog = new CompatModeDialog(
1564                                        ActivityManagerService.this, mContext,
1565                                        ar.info.applicationInfo);
1566                                mCompatModeDialog.show();
1567                            }
1568                        }
1569                    }
1570                }
1571                break;
1572            }
1573            case DISPATCH_PROCESSES_CHANGED: {
1574                dispatchProcessesChanged();
1575                break;
1576            }
1577            case DISPATCH_PROCESS_DIED: {
1578                final int pid = msg.arg1;
1579                final int uid = msg.arg2;
1580                dispatchProcessDied(pid, uid);
1581                break;
1582            }
1583            case REPORT_MEM_USAGE_MSG: {
1584                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1585                Thread thread = new Thread() {
1586                    @Override public void run() {
1587                        final SparseArray<ProcessMemInfo> infoMap
1588                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1589                        for (int i=0, N=memInfos.size(); i<N; i++) {
1590                            ProcessMemInfo mi = memInfos.get(i);
1591                            infoMap.put(mi.pid, mi);
1592                        }
1593                        updateCpuStatsNow();
1594                        synchronized (mProcessCpuThread) {
1595                            final int N = mProcessCpuTracker.countStats();
1596                            for (int i=0; i<N; i++) {
1597                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1598                                if (st.vsize > 0) {
1599                                    long pss = Debug.getPss(st.pid, null);
1600                                    if (pss > 0) {
1601                                        if (infoMap.indexOfKey(st.pid) < 0) {
1602                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1603                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1604                                            mi.pss = pss;
1605                                            memInfos.add(mi);
1606                                        }
1607                                    }
1608                                }
1609                            }
1610                        }
1611
1612                        long totalPss = 0;
1613                        for (int i=0, N=memInfos.size(); i<N; i++) {
1614                            ProcessMemInfo mi = memInfos.get(i);
1615                            if (mi.pss == 0) {
1616                                mi.pss = Debug.getPss(mi.pid, null);
1617                            }
1618                            totalPss += mi.pss;
1619                        }
1620                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1621                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1622                                if (lhs.oomAdj != rhs.oomAdj) {
1623                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1624                                }
1625                                if (lhs.pss != rhs.pss) {
1626                                    return lhs.pss < rhs.pss ? 1 : -1;
1627                                }
1628                                return 0;
1629                            }
1630                        });
1631
1632                        StringBuilder tag = new StringBuilder(128);
1633                        StringBuilder stack = new StringBuilder(128);
1634                        tag.append("Low on memory -- ");
1635                        appendMemBucket(tag, totalPss, "total", false);
1636                        appendMemBucket(stack, totalPss, "total", true);
1637
1638                        StringBuilder logBuilder = new StringBuilder(1024);
1639                        logBuilder.append("Low on memory:\n");
1640
1641                        boolean firstLine = true;
1642                        int lastOomAdj = Integer.MIN_VALUE;
1643                        for (int i=0, N=memInfos.size(); i<N; i++) {
1644                            ProcessMemInfo mi = memInfos.get(i);
1645
1646                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1647                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1648                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1649                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1650                                if (lastOomAdj != mi.oomAdj) {
1651                                    lastOomAdj = mi.oomAdj;
1652                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1653                                        tag.append(" / ");
1654                                    }
1655                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1656                                        if (firstLine) {
1657                                            stack.append(":");
1658                                            firstLine = false;
1659                                        }
1660                                        stack.append("\n\t at ");
1661                                    } else {
1662                                        stack.append("$");
1663                                    }
1664                                } else {
1665                                    tag.append(" ");
1666                                    stack.append("$");
1667                                }
1668                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1669                                    appendMemBucket(tag, mi.pss, mi.name, false);
1670                                }
1671                                appendMemBucket(stack, mi.pss, mi.name, true);
1672                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1673                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1674                                    stack.append("(");
1675                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1676                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1677                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1678                                            stack.append(":");
1679                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1680                                        }
1681                                    }
1682                                    stack.append(")");
1683                                }
1684                            }
1685
1686                            logBuilder.append("  ");
1687                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1688                            logBuilder.append(' ');
1689                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1690                            logBuilder.append(' ');
1691                            ProcessList.appendRamKb(logBuilder, mi.pss);
1692                            logBuilder.append(" kB: ");
1693                            logBuilder.append(mi.name);
1694                            logBuilder.append(" (");
1695                            logBuilder.append(mi.pid);
1696                            logBuilder.append(") ");
1697                            logBuilder.append(mi.adjType);
1698                            logBuilder.append('\n');
1699                            if (mi.adjReason != null) {
1700                                logBuilder.append("                      ");
1701                                logBuilder.append(mi.adjReason);
1702                                logBuilder.append('\n');
1703                            }
1704                        }
1705
1706                        logBuilder.append("           ");
1707                        ProcessList.appendRamKb(logBuilder, totalPss);
1708                        logBuilder.append(" kB: TOTAL\n");
1709
1710                        long[] infos = new long[Debug.MEMINFO_COUNT];
1711                        Debug.getMemInfo(infos);
1712                        logBuilder.append("  MemInfo: ");
1713                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1715                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1716                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1717                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1718                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1719                            logBuilder.append("  ZRAM: ");
1720                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1721                            logBuilder.append(" kB RAM, ");
1722                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1723                            logBuilder.append(" kB swap total, ");
1724                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1725                            logBuilder.append(" kB swap free\n");
1726                        }
1727                        Slog.i(TAG, logBuilder.toString());
1728
1729                        StringBuilder dropBuilder = new StringBuilder(1024);
1730                        /*
1731                        StringWriter oomSw = new StringWriter();
1732                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1733                        StringWriter catSw = new StringWriter();
1734                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1735                        String[] emptyArgs = new String[] { };
1736                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1737                        oomPw.flush();
1738                        String oomString = oomSw.toString();
1739                        */
1740                        dropBuilder.append(stack);
1741                        dropBuilder.append('\n');
1742                        dropBuilder.append('\n');
1743                        dropBuilder.append(logBuilder);
1744                        dropBuilder.append('\n');
1745                        /*
1746                        dropBuilder.append(oomString);
1747                        dropBuilder.append('\n');
1748                        */
1749                        StringWriter catSw = new StringWriter();
1750                        synchronized (ActivityManagerService.this) {
1751                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1752                            String[] emptyArgs = new String[] { };
1753                            catPw.println();
1754                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1755                            catPw.println();
1756                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1757                                    false, false, null);
1758                            catPw.println();
1759                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1760                            catPw.flush();
1761                        }
1762                        dropBuilder.append(catSw.toString());
1763                        addErrorToDropBox("lowmem", null, "system_server", null,
1764                                null, tag.toString(), dropBuilder.toString(), null, null);
1765                        //Slog.i(TAG, "Sent to dropbox:");
1766                        //Slog.i(TAG, dropBuilder.toString());
1767                        synchronized (ActivityManagerService.this) {
1768                            long now = SystemClock.uptimeMillis();
1769                            if (mLastMemUsageReportTime < now) {
1770                                mLastMemUsageReportTime = now;
1771                            }
1772                        }
1773                    }
1774                };
1775                thread.start();
1776                break;
1777            }
1778            case START_USER_SWITCH_MSG: {
1779                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1780                break;
1781            }
1782            case REPORT_USER_SWITCH_MSG: {
1783                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1784                break;
1785            }
1786            case CONTINUE_USER_SWITCH_MSG: {
1787                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1788                break;
1789            }
1790            case USER_SWITCH_TIMEOUT_MSG: {
1791                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1792                break;
1793            }
1794            case IMMERSIVE_MODE_LOCK_MSG: {
1795                final boolean nextState = (msg.arg1 != 0);
1796                if (mUpdateLock.isHeld() != nextState) {
1797                    if (DEBUG_IMMERSIVE) {
1798                        final ActivityRecord r = (ActivityRecord) msg.obj;
1799                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1800                    }
1801                    if (nextState) {
1802                        mUpdateLock.acquire();
1803                    } else {
1804                        mUpdateLock.release();
1805                    }
1806                }
1807                break;
1808            }
1809            case PERSIST_URI_GRANTS_MSG: {
1810                writeGrantedUriPermissions();
1811                break;
1812            }
1813            case REQUEST_ALL_PSS_MSG: {
1814                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1815                break;
1816            }
1817            case START_PROFILES_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    startProfilesLocked();
1820                }
1821                break;
1822            }
1823            case UPDATE_TIME: {
1824                synchronized (ActivityManagerService.this) {
1825                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1826                        ProcessRecord r = mLruProcesses.get(i);
1827                        if (r.thread != null) {
1828                            try {
1829                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1830                            } catch (RemoteException ex) {
1831                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1832                            }
1833                        }
1834                    }
1835                }
1836                break;
1837            }
1838            case SYSTEM_USER_START_MSG: {
1839                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1840                        Integer.toString(msg.arg1), msg.arg1);
1841                mSystemServiceManager.startUser(msg.arg1);
1842                break;
1843            }
1844            case SYSTEM_USER_CURRENT_MSG: {
1845                mBatteryStatsService.noteEvent(
1846                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1847                        Integer.toString(msg.arg2), msg.arg2);
1848                mBatteryStatsService.noteEvent(
1849                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1850                        Integer.toString(msg.arg1), msg.arg1);
1851                mSystemServiceManager.switchUser(msg.arg1);
1852                mLockToAppRequest.clearPrompt();
1853                break;
1854            }
1855            case ENTER_ANIMATION_COMPLETE_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1858                    if (r != null && r.app != null && r.app.thread != null) {
1859                        try {
1860                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1861                        } catch (RemoteException e) {
1862                        }
1863                    }
1864                }
1865                break;
1866            }
1867            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1868                enableScreenAfterBoot();
1869                break;
1870            }
1871            }
1872        }
1873    };
1874
1875    static final int COLLECT_PSS_BG_MSG = 1;
1876
1877    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1878        @Override
1879        public void handleMessage(Message msg) {
1880            switch (msg.what) {
1881            case COLLECT_PSS_BG_MSG: {
1882                long start = SystemClock.uptimeMillis();
1883                MemInfoReader memInfo = null;
1884                synchronized (ActivityManagerService.this) {
1885                    if (mFullPssPending) {
1886                        mFullPssPending = false;
1887                        memInfo = new MemInfoReader();
1888                    }
1889                }
1890                if (memInfo != null) {
1891                    updateCpuStatsNow();
1892                    long nativeTotalPss = 0;
1893                    synchronized (mProcessCpuThread) {
1894                        final int N = mProcessCpuTracker.countStats();
1895                        for (int j=0; j<N; j++) {
1896                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1897                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1898                                // This is definitely an application process; skip it.
1899                                continue;
1900                            }
1901                            synchronized (mPidsSelfLocked) {
1902                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1903                                    // This is one of our own processes; skip it.
1904                                    continue;
1905                                }
1906                            }
1907                            nativeTotalPss += Debug.getPss(st.pid, null);
1908                        }
1909                    }
1910                    memInfo.readMemInfo();
1911                    synchronized (this) {
1912                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1913                                + (SystemClock.uptimeMillis()-start) + "ms");
1914                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1915                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1916                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1917                                        +memInfo.getSlabSizeKb(),
1918                                nativeTotalPss);
1919                    }
1920                }
1921
1922                int i=0, num=0;
1923                long[] tmp = new long[1];
1924                do {
1925                    ProcessRecord proc;
1926                    int procState;
1927                    int pid;
1928                    synchronized (ActivityManagerService.this) {
1929                        if (i >= mPendingPssProcesses.size()) {
1930                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1931                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1932                            mPendingPssProcesses.clear();
1933                            return;
1934                        }
1935                        proc = mPendingPssProcesses.get(i);
1936                        procState = proc.pssProcState;
1937                        if (proc.thread != null && procState == proc.setProcState) {
1938                            pid = proc.pid;
1939                        } else {
1940                            proc = null;
1941                            pid = 0;
1942                        }
1943                        i++;
1944                    }
1945                    if (proc != null) {
1946                        long pss = Debug.getPss(pid, tmp);
1947                        synchronized (ActivityManagerService.this) {
1948                            if (proc.thread != null && proc.setProcState == procState
1949                                    && proc.pid == pid) {
1950                                num++;
1951                                proc.lastPssTime = SystemClock.uptimeMillis();
1952                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1953                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1954                                        + ": " + pss + " lastPss=" + proc.lastPss
1955                                        + " state=" + ProcessList.makeProcStateString(procState));
1956                                if (proc.initialIdlePss == 0) {
1957                                    proc.initialIdlePss = pss;
1958                                }
1959                                proc.lastPss = pss;
1960                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1961                                    proc.lastCachedPss = pss;
1962                                }
1963                            }
1964                        }
1965                    }
1966                } while (true);
1967            }
1968            }
1969        }
1970    };
1971
1972    /**
1973     * Monitor for package changes and update our internal state.
1974     */
1975    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1976        @Override
1977        public void onPackageRemoved(String packageName, int uid) {
1978            // Remove all tasks with activities in the specified package from the list of recent tasks
1979            synchronized (ActivityManagerService.this) {
1980                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1981                    TaskRecord tr = mRecentTasks.get(i);
1982                    ComponentName cn = tr.intent.getComponent();
1983                    if (cn != null && cn.getPackageName().equals(packageName)) {
1984                        // If the package name matches, remove the task and kill the process
1985                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1986                    }
1987                }
1988            }
1989        }
1990
1991        @Override
1992        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1993            onPackageModified(packageName);
1994            return true;
1995        }
1996
1997        @Override
1998        public void onPackageModified(String packageName) {
1999            final PackageManager pm = mContext.getPackageManager();
2000            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2001                    new ArrayList<Pair<Intent, Integer>>();
2002            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2003            // Copy the list of recent tasks so that we don't hold onto the lock on
2004            // ActivityManagerService for long periods while checking if components exist.
2005            synchronized (ActivityManagerService.this) {
2006                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2007                    TaskRecord tr = mRecentTasks.get(i);
2008                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2009                }
2010            }
2011            // Check the recent tasks and filter out all tasks with components that no longer exist.
2012            Intent tmpI = new Intent();
2013            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2014                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2015                ComponentName cn = p.first.getComponent();
2016                if (cn != null && cn.getPackageName().equals(packageName)) {
2017                    try {
2018                        // Add the task to the list to remove if the component no longer exists
2019                        tmpI.setComponent(cn);
2020                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2021                            tasksToRemove.add(p.second);
2022                        }
2023                    } catch (Exception e) {}
2024                }
2025            }
2026            // Prune all the tasks with removed components from the list of recent tasks
2027            synchronized (ActivityManagerService.this) {
2028                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2029                    // Remove the task but don't kill the process (since other components in that
2030                    // package may still be running and in the background)
2031                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2032                }
2033            }
2034        }
2035
2036        @Override
2037        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2038            // Force stop the specified packages
2039            if (packages != null) {
2040                for (String pkg : packages) {
2041                    synchronized (ActivityManagerService.this) {
2042                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2043                                "finished booting")) {
2044                            return true;
2045                        }
2046                    }
2047                }
2048            }
2049            return false;
2050        }
2051    };
2052
2053    public void setSystemProcess() {
2054        try {
2055            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2056            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2057            ServiceManager.addService("meminfo", new MemBinder(this));
2058            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2059            ServiceManager.addService("dbinfo", new DbBinder(this));
2060            if (MONITOR_CPU_USAGE) {
2061                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2062            }
2063            ServiceManager.addService("permission", new PermissionController(this));
2064
2065            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2066                    "android", STOCK_PM_FLAGS);
2067            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2068
2069            synchronized (this) {
2070                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2071                app.persistent = true;
2072                app.pid = MY_PID;
2073                app.maxAdj = ProcessList.SYSTEM_ADJ;
2074                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2075                mProcessNames.put(app.processName, app.uid, app);
2076                synchronized (mPidsSelfLocked) {
2077                    mPidsSelfLocked.put(app.pid, app);
2078                }
2079                updateLruProcessLocked(app, false, null);
2080                updateOomAdjLocked();
2081            }
2082        } catch (PackageManager.NameNotFoundException e) {
2083            throw new RuntimeException(
2084                    "Unable to find android system package", e);
2085        }
2086    }
2087
2088    public void setWindowManager(WindowManagerService wm) {
2089        mWindowManager = wm;
2090        mStackSupervisor.setWindowManager(wm);
2091    }
2092
2093    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2094        mUsageStatsService = usageStatsManager;
2095    }
2096
2097    public void startObservingNativeCrashes() {
2098        final NativeCrashListener ncl = new NativeCrashListener(this);
2099        ncl.start();
2100    }
2101
2102    public IAppOpsService getAppOpsService() {
2103        return mAppOpsService;
2104    }
2105
2106    static class MemBinder extends Binder {
2107        ActivityManagerService mActivityManagerService;
2108        MemBinder(ActivityManagerService activityManagerService) {
2109            mActivityManagerService = activityManagerService;
2110        }
2111
2112        @Override
2113        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2114            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2115                    != PackageManager.PERMISSION_GRANTED) {
2116                pw.println("Permission Denial: can't dump meminfo from from pid="
2117                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2118                        + " without permission " + android.Manifest.permission.DUMP);
2119                return;
2120            }
2121
2122            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2123        }
2124    }
2125
2126    static class GraphicsBinder extends Binder {
2127        ActivityManagerService mActivityManagerService;
2128        GraphicsBinder(ActivityManagerService activityManagerService) {
2129            mActivityManagerService = activityManagerService;
2130        }
2131
2132        @Override
2133        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2134            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2135                    != PackageManager.PERMISSION_GRANTED) {
2136                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2137                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2138                        + " without permission " + android.Manifest.permission.DUMP);
2139                return;
2140            }
2141
2142            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2143        }
2144    }
2145
2146    static class DbBinder extends Binder {
2147        ActivityManagerService mActivityManagerService;
2148        DbBinder(ActivityManagerService activityManagerService) {
2149            mActivityManagerService = activityManagerService;
2150        }
2151
2152        @Override
2153        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2154            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2155                    != PackageManager.PERMISSION_GRANTED) {
2156                pw.println("Permission Denial: can't dump dbinfo from from pid="
2157                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2158                        + " without permission " + android.Manifest.permission.DUMP);
2159                return;
2160            }
2161
2162            mActivityManagerService.dumpDbInfo(fd, pw, args);
2163        }
2164    }
2165
2166    static class CpuBinder extends Binder {
2167        ActivityManagerService mActivityManagerService;
2168        CpuBinder(ActivityManagerService activityManagerService) {
2169            mActivityManagerService = activityManagerService;
2170        }
2171
2172        @Override
2173        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2174            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2175                    != PackageManager.PERMISSION_GRANTED) {
2176                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2177                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2178                        + " without permission " + android.Manifest.permission.DUMP);
2179                return;
2180            }
2181
2182            synchronized (mActivityManagerService.mProcessCpuThread) {
2183                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2184                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2185                        SystemClock.uptimeMillis()));
2186            }
2187        }
2188    }
2189
2190    public static final class Lifecycle extends SystemService {
2191        private final ActivityManagerService mService;
2192
2193        public Lifecycle(Context context) {
2194            super(context);
2195            mService = new ActivityManagerService(context);
2196        }
2197
2198        @Override
2199        public void onStart() {
2200            mService.start();
2201        }
2202
2203        public ActivityManagerService getService() {
2204            return mService;
2205        }
2206    }
2207
2208    // Note: This method is invoked on the main thread but may need to attach various
2209    // handlers to other threads.  So take care to be explicit about the looper.
2210    public ActivityManagerService(Context systemContext) {
2211        mContext = systemContext;
2212        mFactoryTest = FactoryTest.getMode();
2213        mSystemThread = ActivityThread.currentActivityThread();
2214
2215        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2216
2217        mHandlerThread = new ServiceThread(TAG,
2218                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2219        mHandlerThread.start();
2220        mHandler = new MainHandler(mHandlerThread.getLooper());
2221
2222        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2223                "foreground", BROADCAST_FG_TIMEOUT, false);
2224        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2225                "background", BROADCAST_BG_TIMEOUT, true);
2226        mBroadcastQueues[0] = mFgBroadcastQueue;
2227        mBroadcastQueues[1] = mBgBroadcastQueue;
2228
2229        mServices = new ActiveServices(this);
2230        mProviderMap = new ProviderMap(this);
2231
2232        // TODO: Move creation of battery stats service outside of activity manager service.
2233        File dataDir = Environment.getDataDirectory();
2234        File systemDir = new File(dataDir, "system");
2235        systemDir.mkdirs();
2236        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2237        mBatteryStatsService.getActiveStatistics().readLocked();
2238        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2239        mOnBattery = DEBUG_POWER ? true
2240                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2241        mBatteryStatsService.getActiveStatistics().setCallback(this);
2242
2243        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2244
2245        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2246
2247        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2248
2249        // User 0 is the first and only user that runs at boot.
2250        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2251        mUserLru.add(Integer.valueOf(0));
2252        updateStartedUserArrayLocked();
2253
2254        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2255            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2256
2257        mConfiguration.setToDefaults();
2258        mConfiguration.setLocale(Locale.getDefault());
2259
2260        mConfigurationSeq = mConfiguration.seq = 1;
2261        mProcessCpuTracker.init();
2262
2263        final Resources res = mContext.getResources();
2264        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2265        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2266        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2267
2268        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2269        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2270        mStackSupervisor = new ActivityStackSupervisor(this);
2271        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2272
2273        mProcessCpuThread = new Thread("CpuTracker") {
2274            @Override
2275            public void run() {
2276                while (true) {
2277                    try {
2278                        try {
2279                            synchronized(this) {
2280                                final long now = SystemClock.uptimeMillis();
2281                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2282                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2283                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2284                                //        + ", write delay=" + nextWriteDelay);
2285                                if (nextWriteDelay < nextCpuDelay) {
2286                                    nextCpuDelay = nextWriteDelay;
2287                                }
2288                                if (nextCpuDelay > 0) {
2289                                    mProcessCpuMutexFree.set(true);
2290                                    this.wait(nextCpuDelay);
2291                                }
2292                            }
2293                        } catch (InterruptedException e) {
2294                        }
2295                        updateCpuStatsNow();
2296                    } catch (Exception e) {
2297                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2298                    }
2299                }
2300            }
2301        };
2302
2303        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2304
2305        Watchdog.getInstance().addMonitor(this);
2306        Watchdog.getInstance().addThread(mHandler);
2307    }
2308
2309    public void setSystemServiceManager(SystemServiceManager mgr) {
2310        mSystemServiceManager = mgr;
2311    }
2312
2313    private void start() {
2314        Process.removeAllProcessGroups();
2315        mProcessCpuThread.start();
2316
2317        mBatteryStatsService.publish(mContext);
2318        mAppOpsService.publish(mContext);
2319        Slog.d("AppOps", "AppOpsService published");
2320        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2321    }
2322
2323    public void initPowerManagement() {
2324        mStackSupervisor.initPowerManagement();
2325        mBatteryStatsService.initPowerManagement();
2326    }
2327
2328    @Override
2329    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2330            throws RemoteException {
2331        if (code == SYSPROPS_TRANSACTION) {
2332            // We need to tell all apps about the system property change.
2333            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2334            synchronized(this) {
2335                final int NP = mProcessNames.getMap().size();
2336                for (int ip=0; ip<NP; ip++) {
2337                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2338                    final int NA = apps.size();
2339                    for (int ia=0; ia<NA; ia++) {
2340                        ProcessRecord app = apps.valueAt(ia);
2341                        if (app.thread != null) {
2342                            procs.add(app.thread.asBinder());
2343                        }
2344                    }
2345                }
2346            }
2347
2348            int N = procs.size();
2349            for (int i=0; i<N; i++) {
2350                Parcel data2 = Parcel.obtain();
2351                try {
2352                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2353                } catch (RemoteException e) {
2354                }
2355                data2.recycle();
2356            }
2357        }
2358        try {
2359            return super.onTransact(code, data, reply, flags);
2360        } catch (RuntimeException e) {
2361            // The activity manager only throws security exceptions, so let's
2362            // log all others.
2363            if (!(e instanceof SecurityException)) {
2364                Slog.wtf(TAG, "Activity Manager Crash", e);
2365            }
2366            throw e;
2367        }
2368    }
2369
2370    void updateCpuStats() {
2371        final long now = SystemClock.uptimeMillis();
2372        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2373            return;
2374        }
2375        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2376            synchronized (mProcessCpuThread) {
2377                mProcessCpuThread.notify();
2378            }
2379        }
2380    }
2381
2382    void updateCpuStatsNow() {
2383        synchronized (mProcessCpuThread) {
2384            mProcessCpuMutexFree.set(false);
2385            final long now = SystemClock.uptimeMillis();
2386            boolean haveNewCpuStats = false;
2387
2388            if (MONITOR_CPU_USAGE &&
2389                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2390                mLastCpuTime.set(now);
2391                haveNewCpuStats = true;
2392                mProcessCpuTracker.update();
2393                //Slog.i(TAG, mProcessCpu.printCurrentState());
2394                //Slog.i(TAG, "Total CPU usage: "
2395                //        + mProcessCpu.getTotalCpuPercent() + "%");
2396
2397                // Slog the cpu usage if the property is set.
2398                if ("true".equals(SystemProperties.get("events.cpu"))) {
2399                    int user = mProcessCpuTracker.getLastUserTime();
2400                    int system = mProcessCpuTracker.getLastSystemTime();
2401                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2402                    int irq = mProcessCpuTracker.getLastIrqTime();
2403                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2404                    int idle = mProcessCpuTracker.getLastIdleTime();
2405
2406                    int total = user + system + iowait + irq + softIrq + idle;
2407                    if (total == 0) total = 1;
2408
2409                    EventLog.writeEvent(EventLogTags.CPU,
2410                            ((user+system+iowait+irq+softIrq) * 100) / total,
2411                            (user * 100) / total,
2412                            (system * 100) / total,
2413                            (iowait * 100) / total,
2414                            (irq * 100) / total,
2415                            (softIrq * 100) / total);
2416                }
2417            }
2418
2419            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2420            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2421            synchronized(bstats) {
2422                synchronized(mPidsSelfLocked) {
2423                    if (haveNewCpuStats) {
2424                        if (mOnBattery) {
2425                            int perc = bstats.startAddingCpuLocked();
2426                            int totalUTime = 0;
2427                            int totalSTime = 0;
2428                            final int N = mProcessCpuTracker.countStats();
2429                            for (int i=0; i<N; i++) {
2430                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2431                                if (!st.working) {
2432                                    continue;
2433                                }
2434                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2435                                int otherUTime = (st.rel_utime*perc)/100;
2436                                int otherSTime = (st.rel_stime*perc)/100;
2437                                totalUTime += otherUTime;
2438                                totalSTime += otherSTime;
2439                                if (pr != null) {
2440                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2441                                    if (ps == null || !ps.isActive()) {
2442                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2443                                                pr.info.uid, pr.processName);
2444                                    }
2445                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2446                                            st.rel_stime-otherSTime);
2447                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2448                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2449                                } else {
2450                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2451                                    if (ps == null || !ps.isActive()) {
2452                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2453                                                bstats.mapUid(st.uid), st.name);
2454                                    }
2455                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2456                                            st.rel_stime-otherSTime);
2457                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2458                                }
2459                            }
2460                            bstats.finishAddingCpuLocked(perc, totalUTime,
2461                                    totalSTime, cpuSpeedTimes);
2462                        }
2463                    }
2464                }
2465
2466                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2467                    mLastWriteTime = now;
2468                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2469                }
2470            }
2471        }
2472    }
2473
2474    @Override
2475    public void batteryNeedsCpuUpdate() {
2476        updateCpuStatsNow();
2477    }
2478
2479    @Override
2480    public void batteryPowerChanged(boolean onBattery) {
2481        // When plugging in, update the CPU stats first before changing
2482        // the plug state.
2483        updateCpuStatsNow();
2484        synchronized (this) {
2485            synchronized(mPidsSelfLocked) {
2486                mOnBattery = DEBUG_POWER ? true : onBattery;
2487            }
2488        }
2489    }
2490
2491    /**
2492     * Initialize the application bind args. These are passed to each
2493     * process when the bindApplication() IPC is sent to the process. They're
2494     * lazily setup to make sure the services are running when they're asked for.
2495     */
2496    private HashMap<String, IBinder> getCommonServicesLocked() {
2497        if (mAppBindArgs == null) {
2498            mAppBindArgs = new HashMap<String, IBinder>();
2499
2500            // Setup the application init args
2501            mAppBindArgs.put("package", ServiceManager.getService("package"));
2502            mAppBindArgs.put("window", ServiceManager.getService("window"));
2503            mAppBindArgs.put(Context.ALARM_SERVICE,
2504                    ServiceManager.getService(Context.ALARM_SERVICE));
2505        }
2506        return mAppBindArgs;
2507    }
2508
2509    final void setFocusedActivityLocked(ActivityRecord r) {
2510        if (mFocusedActivity != r) {
2511            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2512            mFocusedActivity = r;
2513            if (r.task != null && r.task.voiceInteractor != null) {
2514                startRunningVoiceLocked();
2515            } else {
2516                finishRunningVoiceLocked();
2517            }
2518            mStackSupervisor.setFocusedStack(r);
2519            if (r != null) {
2520                mWindowManager.setFocusedApp(r.appToken, true);
2521            }
2522            applyUpdateLockStateLocked(r);
2523        }
2524    }
2525
2526    final void clearFocusedActivity(ActivityRecord r) {
2527        if (mFocusedActivity == r) {
2528            mFocusedActivity = null;
2529        }
2530    }
2531
2532    @Override
2533    public void setFocusedStack(int stackId) {
2534        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2535        synchronized (ActivityManagerService.this) {
2536            ActivityStack stack = mStackSupervisor.getStack(stackId);
2537            if (stack != null) {
2538                ActivityRecord r = stack.topRunningActivityLocked(null);
2539                if (r != null) {
2540                    setFocusedActivityLocked(r);
2541                }
2542            }
2543        }
2544    }
2545
2546    @Override
2547    public void notifyActivityDrawn(IBinder token) {
2548        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2549        synchronized (this) {
2550            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2551            if (r != null) {
2552                r.task.stack.notifyActivityDrawnLocked(r);
2553            }
2554        }
2555    }
2556
2557    final void applyUpdateLockStateLocked(ActivityRecord r) {
2558        // Modifications to the UpdateLock state are done on our handler, outside
2559        // the activity manager's locks.  The new state is determined based on the
2560        // state *now* of the relevant activity record.  The object is passed to
2561        // the handler solely for logging detail, not to be consulted/modified.
2562        final boolean nextState = r != null && r.immersive;
2563        mHandler.sendMessage(
2564                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2565    }
2566
2567    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2568        Message msg = Message.obtain();
2569        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2570        msg.obj = r.task.askedCompatMode ? null : r;
2571        mHandler.sendMessage(msg);
2572    }
2573
2574    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2575            String what, Object obj, ProcessRecord srcApp) {
2576        app.lastActivityTime = now;
2577
2578        if (app.activities.size() > 0) {
2579            // Don't want to touch dependent processes that are hosting activities.
2580            return index;
2581        }
2582
2583        int lrui = mLruProcesses.lastIndexOf(app);
2584        if (lrui < 0) {
2585            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2586                    + what + " " + obj + " from " + srcApp);
2587            return index;
2588        }
2589
2590        if (lrui >= index) {
2591            // Don't want to cause this to move dependent processes *back* in the
2592            // list as if they were less frequently used.
2593            return index;
2594        }
2595
2596        if (lrui >= mLruProcessActivityStart) {
2597            // Don't want to touch dependent processes that are hosting activities.
2598            return index;
2599        }
2600
2601        mLruProcesses.remove(lrui);
2602        if (index > 0) {
2603            index--;
2604        }
2605        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2606                + " in LRU list: " + app);
2607        mLruProcesses.add(index, app);
2608        return index;
2609    }
2610
2611    final void removeLruProcessLocked(ProcessRecord app) {
2612        int lrui = mLruProcesses.lastIndexOf(app);
2613        if (lrui >= 0) {
2614            if (lrui <= mLruProcessActivityStart) {
2615                mLruProcessActivityStart--;
2616            }
2617            if (lrui <= mLruProcessServiceStart) {
2618                mLruProcessServiceStart--;
2619            }
2620            mLruProcesses.remove(lrui);
2621        }
2622    }
2623
2624    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2625            ProcessRecord client) {
2626        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2627                || app.treatLikeActivity;
2628        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2629        if (!activityChange && hasActivity) {
2630            // The process has activities, so we are only allowing activity-based adjustments
2631            // to move it.  It should be kept in the front of the list with other
2632            // processes that have activities, and we don't want those to change their
2633            // order except due to activity operations.
2634            return;
2635        }
2636
2637        mLruSeq++;
2638        final long now = SystemClock.uptimeMillis();
2639        app.lastActivityTime = now;
2640
2641        // First a quick reject: if the app is already at the position we will
2642        // put it, then there is nothing to do.
2643        if (hasActivity) {
2644            final int N = mLruProcesses.size();
2645            if (N > 0 && mLruProcesses.get(N-1) == app) {
2646                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2647                return;
2648            }
2649        } else {
2650            if (mLruProcessServiceStart > 0
2651                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2652                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2653                return;
2654            }
2655        }
2656
2657        int lrui = mLruProcesses.lastIndexOf(app);
2658
2659        if (app.persistent && lrui >= 0) {
2660            // We don't care about the position of persistent processes, as long as
2661            // they are in the list.
2662            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2663            return;
2664        }
2665
2666        /* In progress: compute new position first, so we can avoid doing work
2667           if the process is not actually going to move.  Not yet working.
2668        int addIndex;
2669        int nextIndex;
2670        boolean inActivity = false, inService = false;
2671        if (hasActivity) {
2672            // Process has activities, put it at the very tipsy-top.
2673            addIndex = mLruProcesses.size();
2674            nextIndex = mLruProcessServiceStart;
2675            inActivity = true;
2676        } else if (hasService) {
2677            // Process has services, put it at the top of the service list.
2678            addIndex = mLruProcessActivityStart;
2679            nextIndex = mLruProcessServiceStart;
2680            inActivity = true;
2681            inService = true;
2682        } else  {
2683            // Process not otherwise of interest, it goes to the top of the non-service area.
2684            addIndex = mLruProcessServiceStart;
2685            if (client != null) {
2686                int clientIndex = mLruProcesses.lastIndexOf(client);
2687                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2688                        + app);
2689                if (clientIndex >= 0 && addIndex > clientIndex) {
2690                    addIndex = clientIndex;
2691                }
2692            }
2693            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2694        }
2695
2696        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2697                + mLruProcessActivityStart + "): " + app);
2698        */
2699
2700        if (lrui >= 0) {
2701            if (lrui < mLruProcessActivityStart) {
2702                mLruProcessActivityStart--;
2703            }
2704            if (lrui < mLruProcessServiceStart) {
2705                mLruProcessServiceStart--;
2706            }
2707            /*
2708            if (addIndex > lrui) {
2709                addIndex--;
2710            }
2711            if (nextIndex > lrui) {
2712                nextIndex--;
2713            }
2714            */
2715            mLruProcesses.remove(lrui);
2716        }
2717
2718        /*
2719        mLruProcesses.add(addIndex, app);
2720        if (inActivity) {
2721            mLruProcessActivityStart++;
2722        }
2723        if (inService) {
2724            mLruProcessActivityStart++;
2725        }
2726        */
2727
2728        int nextIndex;
2729        if (hasActivity) {
2730            final int N = mLruProcesses.size();
2731            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2732                // Process doesn't have activities, but has clients with
2733                // activities...  move it up, but one below the top (the top
2734                // should always have a real activity).
2735                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2736                mLruProcesses.add(N-1, app);
2737                // To keep it from spamming the LRU list (by making a bunch of clients),
2738                // we will push down any other entries owned by the app.
2739                final int uid = app.info.uid;
2740                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2741                    ProcessRecord subProc = mLruProcesses.get(i);
2742                    if (subProc.info.uid == uid) {
2743                        // We want to push this one down the list.  If the process after
2744                        // it is for the same uid, however, don't do so, because we don't
2745                        // want them internally to be re-ordered.
2746                        if (mLruProcesses.get(i-1).info.uid != uid) {
2747                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2748                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2749                            ProcessRecord tmp = mLruProcesses.get(i);
2750                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2751                            mLruProcesses.set(i-1, tmp);
2752                            i--;
2753                        }
2754                    } else {
2755                        // A gap, we can stop here.
2756                        break;
2757                    }
2758                }
2759            } else {
2760                // Process has activities, put it at the very tipsy-top.
2761                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2762                mLruProcesses.add(app);
2763            }
2764            nextIndex = mLruProcessServiceStart;
2765        } else if (hasService) {
2766            // Process has services, put it at the top of the service list.
2767            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2768            mLruProcesses.add(mLruProcessActivityStart, app);
2769            nextIndex = mLruProcessServiceStart;
2770            mLruProcessActivityStart++;
2771        } else  {
2772            // Process not otherwise of interest, it goes to the top of the non-service area.
2773            int index = mLruProcessServiceStart;
2774            if (client != null) {
2775                // If there is a client, don't allow the process to be moved up higher
2776                // in the list than that client.
2777                int clientIndex = mLruProcesses.lastIndexOf(client);
2778                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2779                        + " when updating " + app);
2780                if (clientIndex <= lrui) {
2781                    // Don't allow the client index restriction to push it down farther in the
2782                    // list than it already is.
2783                    clientIndex = lrui;
2784                }
2785                if (clientIndex >= 0 && index > clientIndex) {
2786                    index = clientIndex;
2787                }
2788            }
2789            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2790            mLruProcesses.add(index, app);
2791            nextIndex = index-1;
2792            mLruProcessActivityStart++;
2793            mLruProcessServiceStart++;
2794        }
2795
2796        // If the app is currently using a content provider or service,
2797        // bump those processes as well.
2798        for (int j=app.connections.size()-1; j>=0; j--) {
2799            ConnectionRecord cr = app.connections.valueAt(j);
2800            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2801                    && cr.binding.service.app != null
2802                    && cr.binding.service.app.lruSeq != mLruSeq
2803                    && !cr.binding.service.app.persistent) {
2804                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2805                        "service connection", cr, app);
2806            }
2807        }
2808        for (int j=app.conProviders.size()-1; j>=0; j--) {
2809            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2810            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2811                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2812                        "provider reference", cpr, app);
2813            }
2814        }
2815    }
2816
2817    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2818        if (uid == Process.SYSTEM_UID) {
2819            // The system gets to run in any process.  If there are multiple
2820            // processes with the same uid, just pick the first (this
2821            // should never happen).
2822            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2823            if (procs == null) return null;
2824            final int N = procs.size();
2825            for (int i = 0; i < N; i++) {
2826                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2827            }
2828        }
2829        ProcessRecord proc = mProcessNames.get(processName, uid);
2830        if (false && proc != null && !keepIfLarge
2831                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2832                && proc.lastCachedPss >= 4000) {
2833            // Turn this condition on to cause killing to happen regularly, for testing.
2834            if (proc.baseProcessTracker != null) {
2835                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2836            }
2837            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2838        } else if (proc != null && !keepIfLarge
2839                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2840                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2841            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2842            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2843                if (proc.baseProcessTracker != null) {
2844                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2845                }
2846                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2847            }
2848        }
2849        return proc;
2850    }
2851
2852    void ensurePackageDexOpt(String packageName) {
2853        IPackageManager pm = AppGlobals.getPackageManager();
2854        try {
2855            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2856                mDidDexOpt = true;
2857            }
2858        } catch (RemoteException e) {
2859        }
2860    }
2861
2862    boolean isNextTransitionForward() {
2863        int transit = mWindowManager.getPendingAppTransition();
2864        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2865                || transit == AppTransition.TRANSIT_TASK_OPEN
2866                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2867    }
2868
2869    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2870            String processName, String abiOverride, int uid, Runnable crashHandler) {
2871        synchronized(this) {
2872            ApplicationInfo info = new ApplicationInfo();
2873            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2874            // For isolated processes, the former contains the parent's uid and the latter the
2875            // actual uid of the isolated process.
2876            // In the special case introduced by this method (which is, starting an isolated
2877            // process directly from the SystemServer without an actual parent app process) the
2878            // closest thing to a parent's uid is SYSTEM_UID.
2879            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2880            // the |isolated| logic in the ProcessRecord constructor.
2881            info.uid = Process.SYSTEM_UID;
2882            info.processName = processName;
2883            info.className = entryPoint;
2884            info.packageName = "android";
2885            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2886                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2887                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2888                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2889                    crashHandler);
2890            return proc != null ? proc.pid : 0;
2891        }
2892    }
2893
2894    final ProcessRecord startProcessLocked(String processName,
2895            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2896            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2897            boolean isolated, boolean keepIfLarge) {
2898        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2899                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2900                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2901                null /* crashHandler */);
2902    }
2903
2904    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2905            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2906            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2907            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2908        ProcessRecord app;
2909        if (!isolated) {
2910            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2911        } else {
2912            // If this is an isolated process, it can't re-use an existing process.
2913            app = null;
2914        }
2915        // We don't have to do anything more if:
2916        // (1) There is an existing application record; and
2917        // (2) The caller doesn't think it is dead, OR there is no thread
2918        //     object attached to it so we know it couldn't have crashed; and
2919        // (3) There is a pid assigned to it, so it is either starting or
2920        //     already running.
2921        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2922                + " app=" + app + " knownToBeDead=" + knownToBeDead
2923                + " thread=" + (app != null ? app.thread : null)
2924                + " pid=" + (app != null ? app.pid : -1));
2925        if (app != null && app.pid > 0) {
2926            if (!knownToBeDead || app.thread == null) {
2927                // We already have the app running, or are waiting for it to
2928                // come up (we have a pid but not yet its thread), so keep it.
2929                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2930                // If this is a new package in the process, add the package to the list
2931                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2932                return app;
2933            }
2934
2935            // An application record is attached to a previous process,
2936            // clean it up now.
2937            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2938            Process.killProcessGroup(app.info.uid, app.pid);
2939            handleAppDiedLocked(app, true, true);
2940        }
2941
2942        String hostingNameStr = hostingName != null
2943                ? hostingName.flattenToShortString() : null;
2944
2945        if (!isolated) {
2946            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2947                // If we are in the background, then check to see if this process
2948                // is bad.  If so, we will just silently fail.
2949                if (mBadProcesses.get(info.processName, info.uid) != null) {
2950                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2951                            + "/" + info.processName);
2952                    return null;
2953                }
2954            } else {
2955                // When the user is explicitly starting a process, then clear its
2956                // crash count so that we won't make it bad until they see at
2957                // least one crash dialog again, and make the process good again
2958                // if it had been bad.
2959                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2960                        + "/" + info.processName);
2961                mProcessCrashTimes.remove(info.processName, info.uid);
2962                if (mBadProcesses.get(info.processName, info.uid) != null) {
2963                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2964                            UserHandle.getUserId(info.uid), info.uid,
2965                            info.processName);
2966                    mBadProcesses.remove(info.processName, info.uid);
2967                    if (app != null) {
2968                        app.bad = false;
2969                    }
2970                }
2971            }
2972        }
2973
2974        if (app == null) {
2975            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2976            app.crashHandler = crashHandler;
2977            if (app == null) {
2978                Slog.w(TAG, "Failed making new process record for "
2979                        + processName + "/" + info.uid + " isolated=" + isolated);
2980                return null;
2981            }
2982            mProcessNames.put(processName, app.uid, app);
2983            if (isolated) {
2984                mIsolatedProcesses.put(app.uid, app);
2985            }
2986        } else {
2987            // If this is a new package in the process, add the package to the list
2988            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2989        }
2990
2991        // If the system is not ready yet, then hold off on starting this
2992        // process until it is.
2993        if (!mProcessesReady
2994                && !isAllowedWhileBooting(info)
2995                && !allowWhileBooting) {
2996            if (!mProcessesOnHold.contains(app)) {
2997                mProcessesOnHold.add(app);
2998            }
2999            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3000            return app;
3001        }
3002
3003        startProcessLocked(
3004                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3005        return (app.pid != 0) ? app : null;
3006    }
3007
3008    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3009        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3010    }
3011
3012    private final void startProcessLocked(ProcessRecord app,
3013            String hostingType, String hostingNameStr) {
3014        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3015                null /* entryPoint */, null /* entryPointArgs */);
3016    }
3017
3018    private final void startProcessLocked(ProcessRecord app, String hostingType,
3019            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3020        if (app.pid > 0 && app.pid != MY_PID) {
3021            synchronized (mPidsSelfLocked) {
3022                mPidsSelfLocked.remove(app.pid);
3023                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3024            }
3025            app.setPid(0);
3026        }
3027
3028        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3029                "startProcessLocked removing on hold: " + app);
3030        mProcessesOnHold.remove(app);
3031
3032        updateCpuStats();
3033
3034        try {
3035            int uid = app.uid;
3036
3037            int[] gids = null;
3038            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3039            if (!app.isolated) {
3040                int[] permGids = null;
3041                try {
3042                    final PackageManager pm = mContext.getPackageManager();
3043                    permGids = pm.getPackageGids(app.info.packageName);
3044
3045                    if (Environment.isExternalStorageEmulated()) {
3046                        if (pm.checkPermission(
3047                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3048                                app.info.packageName) == PERMISSION_GRANTED) {
3049                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3050                        } else {
3051                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3052                        }
3053                    }
3054                } catch (PackageManager.NameNotFoundException e) {
3055                    Slog.w(TAG, "Unable to retrieve gids", e);
3056                }
3057
3058                /*
3059                 * Add shared application and profile GIDs so applications can share some
3060                 * resources like shared libraries and access user-wide resources
3061                 */
3062                if (permGids == null) {
3063                    gids = new int[2];
3064                } else {
3065                    gids = new int[permGids.length + 2];
3066                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3067                }
3068                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3069                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3070            }
3071            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3072                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3073                        && mTopComponent != null
3074                        && app.processName.equals(mTopComponent.getPackageName())) {
3075                    uid = 0;
3076                }
3077                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3078                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3079                    uid = 0;
3080                }
3081            }
3082            int debugFlags = 0;
3083            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3084                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3085                // Also turn on CheckJNI for debuggable apps. It's quite
3086                // awkward to turn on otherwise.
3087                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3088            }
3089            // Run the app in safe mode if its manifest requests so or the
3090            // system is booted in safe mode.
3091            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3092                mSafeMode == true) {
3093                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3094            }
3095            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3096                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3097            }
3098            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3099                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3100            }
3101            if ("1".equals(SystemProperties.get("debug.assert"))) {
3102                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3103            }
3104
3105            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3106            if (requiredAbi == null) {
3107                requiredAbi = Build.SUPPORTED_ABIS[0];
3108            }
3109
3110            // Start the process.  It will either succeed and return a result containing
3111            // the PID of the new process, or else throw a RuntimeException.
3112            boolean isActivityProcess = (entryPoint == null);
3113            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3114            Process.ProcessStartResult startResult = Process.start(entryPoint,
3115                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3116                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3117
3118            if (app.isolated) {
3119                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3120            }
3121            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3122
3123            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3124                    UserHandle.getUserId(uid), startResult.pid, uid,
3125                    app.processName, hostingType,
3126                    hostingNameStr != null ? hostingNameStr : "");
3127
3128            if (app.persistent) {
3129                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3130            }
3131
3132            StringBuilder buf = mStringBuilder;
3133            buf.setLength(0);
3134            buf.append("Start proc ");
3135            buf.append(app.processName);
3136            if (!isActivityProcess) {
3137                buf.append(" [");
3138                buf.append(entryPoint);
3139                buf.append("]");
3140            }
3141            buf.append(" for ");
3142            buf.append(hostingType);
3143            if (hostingNameStr != null) {
3144                buf.append(" ");
3145                buf.append(hostingNameStr);
3146            }
3147            buf.append(": pid=");
3148            buf.append(startResult.pid);
3149            buf.append(" uid=");
3150            buf.append(uid);
3151            buf.append(" gids={");
3152            if (gids != null) {
3153                for (int gi=0; gi<gids.length; gi++) {
3154                    if (gi != 0) buf.append(", ");
3155                    buf.append(gids[gi]);
3156
3157                }
3158            }
3159            buf.append("}");
3160            if (requiredAbi != null) {
3161                buf.append(" abi=");
3162                buf.append(requiredAbi);
3163            }
3164            Slog.i(TAG, buf.toString());
3165            app.setPid(startResult.pid);
3166            app.usingWrapper = startResult.usingWrapper;
3167            app.removed = false;
3168            app.killedByAm = false;
3169            synchronized (mPidsSelfLocked) {
3170                this.mPidsSelfLocked.put(startResult.pid, app);
3171                if (isActivityProcess) {
3172                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3173                    msg.obj = app;
3174                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3175                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3176                }
3177            }
3178        } catch (RuntimeException e) {
3179            // XXX do better error recovery.
3180            app.setPid(0);
3181            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3182            if (app.isolated) {
3183                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3184            }
3185            Slog.e(TAG, "Failure starting process " + app.processName, e);
3186        }
3187    }
3188
3189    void updateUsageStats(ActivityRecord component, boolean resumed) {
3190        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3191        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3192        if (resumed) {
3193            if (mUsageStatsService != null) {
3194                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3195                        System.currentTimeMillis(),
3196                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3197            }
3198            synchronized (stats) {
3199                stats.noteActivityResumedLocked(component.app.uid);
3200            }
3201        } else {
3202            if (mUsageStatsService != null) {
3203                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3204                        System.currentTimeMillis(),
3205                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3206            }
3207            synchronized (stats) {
3208                stats.noteActivityPausedLocked(component.app.uid);
3209            }
3210        }
3211    }
3212
3213    Intent getHomeIntent() {
3214        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3215        intent.setComponent(mTopComponent);
3216        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3217            intent.addCategory(Intent.CATEGORY_HOME);
3218        }
3219        return intent;
3220    }
3221
3222    boolean startHomeActivityLocked(int userId) {
3223        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3224                && mTopAction == null) {
3225            // We are running in factory test mode, but unable to find
3226            // the factory test app, so just sit around displaying the
3227            // error message and don't try to start anything.
3228            return false;
3229        }
3230        Intent intent = getHomeIntent();
3231        ActivityInfo aInfo =
3232            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3233        if (aInfo != null) {
3234            intent.setComponent(new ComponentName(
3235                    aInfo.applicationInfo.packageName, aInfo.name));
3236            // Don't do this if the home app is currently being
3237            // instrumented.
3238            aInfo = new ActivityInfo(aInfo);
3239            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3240            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3241                    aInfo.applicationInfo.uid, true);
3242            if (app == null || app.instrumentationClass == null) {
3243                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3244                mStackSupervisor.startHomeActivity(intent, aInfo);
3245            }
3246        }
3247
3248        return true;
3249    }
3250
3251    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3252        ActivityInfo ai = null;
3253        ComponentName comp = intent.getComponent();
3254        try {
3255            if (comp != null) {
3256                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3257            } else {
3258                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3259                        intent,
3260                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3261                            flags, userId);
3262
3263                if (info != null) {
3264                    ai = info.activityInfo;
3265                }
3266            }
3267        } catch (RemoteException e) {
3268            // ignore
3269        }
3270
3271        return ai;
3272    }
3273
3274    /**
3275     * Starts the "new version setup screen" if appropriate.
3276     */
3277    void startSetupActivityLocked() {
3278        // Only do this once per boot.
3279        if (mCheckedForSetup) {
3280            return;
3281        }
3282
3283        // We will show this screen if the current one is a different
3284        // version than the last one shown, and we are not running in
3285        // low-level factory test mode.
3286        final ContentResolver resolver = mContext.getContentResolver();
3287        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3288                Settings.Global.getInt(resolver,
3289                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3290            mCheckedForSetup = true;
3291
3292            // See if we should be showing the platform update setup UI.
3293            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3294            List<ResolveInfo> ris = mContext.getPackageManager()
3295                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3296
3297            // We don't allow third party apps to replace this.
3298            ResolveInfo ri = null;
3299            for (int i=0; ris != null && i<ris.size(); i++) {
3300                if ((ris.get(i).activityInfo.applicationInfo.flags
3301                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3302                    ri = ris.get(i);
3303                    break;
3304                }
3305            }
3306
3307            if (ri != null) {
3308                String vers = ri.activityInfo.metaData != null
3309                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3310                        : null;
3311                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3312                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3313                            Intent.METADATA_SETUP_VERSION);
3314                }
3315                String lastVers = Settings.Secure.getString(
3316                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3317                if (vers != null && !vers.equals(lastVers)) {
3318                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3319                    intent.setComponent(new ComponentName(
3320                            ri.activityInfo.packageName, ri.activityInfo.name));
3321                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3322                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3323                            null);
3324                }
3325            }
3326        }
3327    }
3328
3329    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3330        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3331    }
3332
3333    void enforceNotIsolatedCaller(String caller) {
3334        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3335            throw new SecurityException("Isolated process not allowed to call " + caller);
3336        }
3337    }
3338
3339    @Override
3340    public int getFrontActivityScreenCompatMode() {
3341        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3342        synchronized (this) {
3343            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3344        }
3345    }
3346
3347    @Override
3348    public void setFrontActivityScreenCompatMode(int mode) {
3349        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3350                "setFrontActivityScreenCompatMode");
3351        synchronized (this) {
3352            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3353        }
3354    }
3355
3356    @Override
3357    public int getPackageScreenCompatMode(String packageName) {
3358        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3359        synchronized (this) {
3360            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3361        }
3362    }
3363
3364    @Override
3365    public void setPackageScreenCompatMode(String packageName, int mode) {
3366        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3367                "setPackageScreenCompatMode");
3368        synchronized (this) {
3369            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3370        }
3371    }
3372
3373    @Override
3374    public boolean getPackageAskScreenCompat(String packageName) {
3375        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3376        synchronized (this) {
3377            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3378        }
3379    }
3380
3381    @Override
3382    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3383        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3384                "setPackageAskScreenCompat");
3385        synchronized (this) {
3386            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3387        }
3388    }
3389
3390    private void dispatchProcessesChanged() {
3391        int N;
3392        synchronized (this) {
3393            N = mPendingProcessChanges.size();
3394            if (mActiveProcessChanges.length < N) {
3395                mActiveProcessChanges = new ProcessChangeItem[N];
3396            }
3397            mPendingProcessChanges.toArray(mActiveProcessChanges);
3398            mAvailProcessChanges.addAll(mPendingProcessChanges);
3399            mPendingProcessChanges.clear();
3400            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3401        }
3402
3403        int i = mProcessObservers.beginBroadcast();
3404        while (i > 0) {
3405            i--;
3406            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3407            if (observer != null) {
3408                try {
3409                    for (int j=0; j<N; j++) {
3410                        ProcessChangeItem item = mActiveProcessChanges[j];
3411                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3412                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3413                                    + item.pid + " uid=" + item.uid + ": "
3414                                    + item.foregroundActivities);
3415                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3416                                    item.foregroundActivities);
3417                        }
3418                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3419                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3420                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3421                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3422                        }
3423                    }
3424                } catch (RemoteException e) {
3425                }
3426            }
3427        }
3428        mProcessObservers.finishBroadcast();
3429    }
3430
3431    private void dispatchProcessDied(int pid, int uid) {
3432        int i = mProcessObservers.beginBroadcast();
3433        while (i > 0) {
3434            i--;
3435            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3436            if (observer != null) {
3437                try {
3438                    observer.onProcessDied(pid, uid);
3439                } catch (RemoteException e) {
3440                }
3441            }
3442        }
3443        mProcessObservers.finishBroadcast();
3444    }
3445
3446    @Override
3447    public final int startActivity(IApplicationThread caller, String callingPackage,
3448            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3449            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3450        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3451            resultWho, requestCode, startFlags, profilerInfo, options,
3452            UserHandle.getCallingUserId());
3453    }
3454
3455    @Override
3456    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3457            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3458            int startFlags, ProfilerInfo profilerInfo, 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,
3464                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3465                profilerInfo, 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, String resultWho, int requestCode,
3471            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3472
3473        // This is very dangerous -- it allows you to perform a start activity (including
3474        // permission grants) as any app that may launch one of your own activities.  So
3475        // we will only allow this to be done from activities that are part of the core framework,
3476        // and then only when they are running as the system.
3477        final ActivityRecord sourceRecord;
3478        final int targetUid;
3479        final String targetPackage;
3480        synchronized (this) {
3481            if (resultTo == null) {
3482                throw new SecurityException("Must be called from an activity");
3483            }
3484            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3485            if (sourceRecord == null) {
3486                throw new SecurityException("Called with bad activity token: " + resultTo);
3487            }
3488            if (!sourceRecord.info.packageName.equals("android")) {
3489                throw new SecurityException(
3490                        "Must be called from an activity that is declared in the android package");
3491            }
3492            if (sourceRecord.app == null) {
3493                throw new SecurityException("Called without a process attached to activity");
3494            }
3495            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3496                // This is still okay, as long as this activity is running under the
3497                // uid of the original calling activity.
3498                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3499                    throw new SecurityException(
3500                            "Calling activity in uid " + sourceRecord.app.uid
3501                                    + " must be system uid or original calling uid "
3502                                    + sourceRecord.launchedFromUid);
3503                }
3504            }
3505            targetUid = sourceRecord.launchedFromUid;
3506            targetPackage = sourceRecord.launchedFromPackage;
3507        }
3508
3509        // TODO: Switch to user app stacks here.
3510        try {
3511            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3512                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3513                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3514            return ret;
3515        } catch (SecurityException e) {
3516            // XXX need to figure out how to propagate to original app.
3517            // A SecurityException here is generally actually a fault of the original
3518            // calling activity (such as a fairly granting permissions), so propagate it
3519            // back to them.
3520            /*
3521            StringBuilder msg = new StringBuilder();
3522            msg.append("While launching");
3523            msg.append(intent.toString());
3524            msg.append(": ");
3525            msg.append(e.getMessage());
3526            */
3527            throw e;
3528        }
3529    }
3530
3531    @Override
3532    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3533            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3534            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3535        enforceNotIsolatedCaller("startActivityAndWait");
3536        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3537                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3538        WaitResult res = new WaitResult();
3539        // TODO: Switch to user app stacks here.
3540        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3541                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3542                options, userId, null, null);
3543        return res;
3544    }
3545
3546    @Override
3547    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3548            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3549            int startFlags, Configuration config, Bundle options, int userId) {
3550        enforceNotIsolatedCaller("startActivityWithConfig");
3551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3552                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3553        // TODO: Switch to user app stacks here.
3554        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3555                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3556                null, null, config, options, userId, null, null);
3557        return ret;
3558    }
3559
3560    @Override
3561    public int startActivityIntentSender(IApplicationThread caller,
3562            IntentSender intent, Intent fillInIntent, String resolvedType,
3563            IBinder resultTo, String resultWho, int requestCode,
3564            int flagsMask, int flagsValues, Bundle options) {
3565        enforceNotIsolatedCaller("startActivityIntentSender");
3566        // Refuse possible leaked file descriptors
3567        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3568            throw new IllegalArgumentException("File descriptors passed in Intent");
3569        }
3570
3571        IIntentSender sender = intent.getTarget();
3572        if (!(sender instanceof PendingIntentRecord)) {
3573            throw new IllegalArgumentException("Bad PendingIntent object");
3574        }
3575
3576        PendingIntentRecord pir = (PendingIntentRecord)sender;
3577
3578        synchronized (this) {
3579            // If this is coming from the currently resumed activity, it is
3580            // effectively saying that app switches are allowed at this point.
3581            final ActivityStack stack = getFocusedStack();
3582            if (stack.mResumedActivity != null &&
3583                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3584                mAppSwitchesAllowedTime = 0;
3585            }
3586        }
3587        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3588                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3589        return ret;
3590    }
3591
3592    @Override
3593    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3594            Intent intent, String resolvedType, IVoiceInteractionSession session,
3595            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3596            Bundle options, int userId) {
3597        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3598                != PackageManager.PERMISSION_GRANTED) {
3599            String msg = "Permission Denial: startVoiceActivity() from pid="
3600                    + Binder.getCallingPid()
3601                    + ", uid=" + Binder.getCallingUid()
3602                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3603            Slog.w(TAG, msg);
3604            throw new SecurityException(msg);
3605        }
3606        if (session == null || interactor == null) {
3607            throw new NullPointerException("null session or interactor");
3608        }
3609        userId = handleIncomingUser(callingPid, callingUid, userId,
3610                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3611        // TODO: Switch to user app stacks here.
3612        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3613                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3614                null, options, userId, null, null);
3615    }
3616
3617    @Override
3618    public boolean startNextMatchingActivity(IBinder callingActivity,
3619            Intent intent, Bundle options) {
3620        // Refuse possible leaked file descriptors
3621        if (intent != null && intent.hasFileDescriptors() == true) {
3622            throw new IllegalArgumentException("File descriptors passed in Intent");
3623        }
3624
3625        synchronized (this) {
3626            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3627            if (r == null) {
3628                ActivityOptions.abort(options);
3629                return false;
3630            }
3631            if (r.app == null || r.app.thread == null) {
3632                // The caller is not running...  d'oh!
3633                ActivityOptions.abort(options);
3634                return false;
3635            }
3636            intent = new Intent(intent);
3637            // The caller is not allowed to change the data.
3638            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3639            // And we are resetting to find the next component...
3640            intent.setComponent(null);
3641
3642            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3643
3644            ActivityInfo aInfo = null;
3645            try {
3646                List<ResolveInfo> resolves =
3647                    AppGlobals.getPackageManager().queryIntentActivities(
3648                            intent, r.resolvedType,
3649                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3650                            UserHandle.getCallingUserId());
3651
3652                // Look for the original activity in the list...
3653                final int N = resolves != null ? resolves.size() : 0;
3654                for (int i=0; i<N; i++) {
3655                    ResolveInfo rInfo = resolves.get(i);
3656                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3657                            && rInfo.activityInfo.name.equals(r.info.name)) {
3658                        // We found the current one...  the next matching is
3659                        // after it.
3660                        i++;
3661                        if (i<N) {
3662                            aInfo = resolves.get(i).activityInfo;
3663                        }
3664                        if (debug) {
3665                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3666                                    + "/" + r.info.name);
3667                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3668                                    + "/" + aInfo.name);
3669                        }
3670                        break;
3671                    }
3672                }
3673            } catch (RemoteException e) {
3674            }
3675
3676            if (aInfo == null) {
3677                // Nobody who is next!
3678                ActivityOptions.abort(options);
3679                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3680                return false;
3681            }
3682
3683            intent.setComponent(new ComponentName(
3684                    aInfo.applicationInfo.packageName, aInfo.name));
3685            intent.setFlags(intent.getFlags()&~(
3686                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3687                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3688                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3689                    Intent.FLAG_ACTIVITY_NEW_TASK));
3690
3691            // Okay now we need to start the new activity, replacing the
3692            // currently running activity.  This is a little tricky because
3693            // we want to start the new one as if the current one is finished,
3694            // but not finish the current one first so that there is no flicker.
3695            // And thus...
3696            final boolean wasFinishing = r.finishing;
3697            r.finishing = true;
3698
3699            // Propagate reply information over to the new activity.
3700            final ActivityRecord resultTo = r.resultTo;
3701            final String resultWho = r.resultWho;
3702            final int requestCode = r.requestCode;
3703            r.resultTo = null;
3704            if (resultTo != null) {
3705                resultTo.removeResultsLocked(r, resultWho, requestCode);
3706            }
3707
3708            final long origId = Binder.clearCallingIdentity();
3709            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3710                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3711                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3712                    options, false, null, null, null);
3713            Binder.restoreCallingIdentity(origId);
3714
3715            r.finishing = wasFinishing;
3716            if (res != ActivityManager.START_SUCCESS) {
3717                return false;
3718            }
3719            return true;
3720        }
3721    }
3722
3723    @Override
3724    public final int startActivityFromRecents(int taskId, Bundle options) {
3725        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3726            String msg = "Permission Denial: startActivityFromRecents called without " +
3727                    START_TASKS_FROM_RECENTS;
3728            Slog.w(TAG, msg);
3729            throw new SecurityException(msg);
3730        }
3731        return startActivityFromRecentsInner(taskId, options);
3732    }
3733
3734    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3735        final TaskRecord task;
3736        final int callingUid;
3737        final String callingPackage;
3738        final Intent intent;
3739        final int userId;
3740        synchronized (this) {
3741            task = recentTaskForIdLocked(taskId);
3742            if (task == null) {
3743                throw new IllegalArgumentException("Task " + taskId + " not found.");
3744            }
3745            callingUid = task.mCallingUid;
3746            callingPackage = task.mCallingPackage;
3747            intent = task.intent;
3748            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3749            userId = task.userId;
3750        }
3751        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3752                options, userId, null, task);
3753    }
3754
3755    final int startActivityInPackage(int uid, String callingPackage,
3756            Intent intent, String resolvedType, IBinder resultTo,
3757            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3758            IActivityContainer container, TaskRecord inTask) {
3759
3760        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3761                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3762
3763        // TODO: Switch to user app stacks here.
3764        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3765                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3766                null, null, null, options, userId, container, inTask);
3767        return ret;
3768    }
3769
3770    @Override
3771    public final int startActivities(IApplicationThread caller, String callingPackage,
3772            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3773            int userId) {
3774        enforceNotIsolatedCaller("startActivities");
3775        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3776                false, ALLOW_FULL_ONLY, "startActivity", null);
3777        // TODO: Switch to user app stacks here.
3778        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3779                resolvedTypes, resultTo, options, userId);
3780        return ret;
3781    }
3782
3783    final int startActivitiesInPackage(int uid, String callingPackage,
3784            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3785            Bundle options, int userId) {
3786
3787        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3788                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3789        // TODO: Switch to user app stacks here.
3790        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3791                resultTo, options, userId);
3792        return ret;
3793    }
3794
3795    //explicitly remove thd old information in mRecentTasks when removing existing user.
3796    private void removeRecentTasksForUserLocked(int userId) {
3797        if(userId <= 0) {
3798            Slog.i(TAG, "Can't remove recent task on user " + userId);
3799            return;
3800        }
3801
3802        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3803            TaskRecord tr = mRecentTasks.get(i);
3804            if (tr.userId == userId) {
3805                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3806                        + " when finishing user" + userId);
3807                tr.disposeThumbnail();
3808                mRecentTasks.remove(i);
3809            }
3810        }
3811
3812        // Remove tasks from persistent storage.
3813        mTaskPersister.wakeup(null, true);
3814    }
3815
3816    final void addRecentTaskLocked(TaskRecord task) {
3817        final int N = mRecentTasks.size();
3818        // Quick case: check if the top-most recent task is the same.
3819        if (N > 0 && mRecentTasks.get(0) == task) {
3820            return;
3821        }
3822        // Another quick case: never add voice sessions.
3823        if (task.voiceSession != null) {
3824            return;
3825        }
3826
3827        trimRecentsForTask(task, true);
3828
3829        if (N >= MAX_RECENT_TASKS) {
3830            final TaskRecord tr = mRecentTasks.remove(N - 1);
3831            tr.disposeThumbnail();
3832            tr.closeRecentsChain();
3833        }
3834        mRecentTasks.add(0, task);
3835    }
3836
3837    /**
3838     * If needed, remove oldest existing entries in recents that are for the same kind
3839     * of task as the given one.
3840     */
3841    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
3842        int N = mRecentTasks.size();
3843        final Intent intent = task.intent;
3844        final boolean document = intent != null && intent.isDocument();
3845
3846        int maxRecents = task.maxRecents - 1;
3847        for (int i=0; i<N; i++) {
3848            final TaskRecord tr = mRecentTasks.get(i);
3849            if (task != tr) {
3850                if (task.userId != tr.userId) {
3851                    continue;
3852                }
3853                if (i > MAX_RECENT_BITMAPS) {
3854                    tr.freeLastThumbnail();
3855                }
3856                final Intent trIntent = tr.intent;
3857                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3858                    (intent == null || !intent.filterEquals(trIntent))) {
3859                    continue;
3860                }
3861                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3862                if (document && trIsDocument) {
3863                    // These are the same document activity (not necessarily the same doc).
3864                    if (maxRecents > 0) {
3865                        --maxRecents;
3866                        continue;
3867                    }
3868                    // Hit the maximum number of documents for this task. Fall through
3869                    // and remove this document from recents.
3870                } else if (document || trIsDocument) {
3871                    // Only one of these is a document. Not the droid we're looking for.
3872                    continue;
3873                }
3874            }
3875
3876            if (!doTrim) {
3877                // If the caller is not actually asking for a trim, just tell them we reached
3878                // a point where the trim would happen.
3879                return i;
3880            }
3881
3882            // Either task and tr are the same or, their affinities match or their intents match
3883            // and neither of them is a document, or they are documents using the same activity
3884            // and their maxRecents has been reached.
3885            tr.disposeThumbnail();
3886            mRecentTasks.remove(i);
3887            if (task != tr) {
3888                tr.closeRecentsChain();
3889            }
3890            i--;
3891            N--;
3892            if (task.intent == null) {
3893                // If the new recent task we are adding is not fully
3894                // specified, then replace it with the existing recent task.
3895                task = tr;
3896            }
3897            notifyTaskPersisterLocked(tr, false);
3898        }
3899
3900        return -1;
3901    }
3902
3903    @Override
3904    public void reportActivityFullyDrawn(IBinder token) {
3905        synchronized (this) {
3906            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3907            if (r == null) {
3908                return;
3909            }
3910            r.reportFullyDrawnLocked();
3911        }
3912    }
3913
3914    @Override
3915    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3916        synchronized (this) {
3917            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3918            if (r == null) {
3919                return;
3920            }
3921            final long origId = Binder.clearCallingIdentity();
3922            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3923            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3924                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3925            if (config != null) {
3926                r.frozenBeforeDestroy = true;
3927                if (!updateConfigurationLocked(config, r, false, false)) {
3928                    mStackSupervisor.resumeTopActivitiesLocked();
3929                }
3930            }
3931            Binder.restoreCallingIdentity(origId);
3932        }
3933    }
3934
3935    @Override
3936    public int getRequestedOrientation(IBinder token) {
3937        synchronized (this) {
3938            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3939            if (r == null) {
3940                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3941            }
3942            return mWindowManager.getAppOrientation(r.appToken);
3943        }
3944    }
3945
3946    /**
3947     * This is the internal entry point for handling Activity.finish().
3948     *
3949     * @param token The Binder token referencing the Activity we want to finish.
3950     * @param resultCode Result code, if any, from this Activity.
3951     * @param resultData Result data (Intent), if any, from this Activity.
3952     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3953     *            the root Activity in the task.
3954     *
3955     * @return Returns true if the activity successfully finished, or false if it is still running.
3956     */
3957    @Override
3958    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3959            boolean finishTask) {
3960        // Refuse possible leaked file descriptors
3961        if (resultData != null && resultData.hasFileDescriptors() == true) {
3962            throw new IllegalArgumentException("File descriptors passed in Intent");
3963        }
3964
3965        synchronized(this) {
3966            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3967            if (r == null) {
3968                return true;
3969            }
3970            // Keep track of the root activity of the task before we finish it
3971            TaskRecord tr = r.task;
3972            ActivityRecord rootR = tr.getRootActivity();
3973            // Do not allow task to finish in Lock Task mode.
3974            if (tr == mStackSupervisor.mLockTaskModeTask) {
3975                if (rootR == r) {
3976                    mStackSupervisor.showLockTaskToast();
3977                    return false;
3978                }
3979            }
3980            if (mController != null) {
3981                // Find the first activity that is not finishing.
3982                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3983                if (next != null) {
3984                    // ask watcher if this is allowed
3985                    boolean resumeOK = true;
3986                    try {
3987                        resumeOK = mController.activityResuming(next.packageName);
3988                    } catch (RemoteException e) {
3989                        mController = null;
3990                        Watchdog.getInstance().setActivityController(null);
3991                    }
3992
3993                    if (!resumeOK) {
3994                        return false;
3995                    }
3996                }
3997            }
3998            final long origId = Binder.clearCallingIdentity();
3999            try {
4000                boolean res;
4001                if (finishTask && r == rootR) {
4002                    // If requested, remove the task that is associated to this activity only if it
4003                    // was the root activity in the task.  The result code and data is ignored because
4004                    // we don't support returning them across task boundaries.
4005                    res = removeTaskByIdLocked(tr.taskId, 0);
4006                } else {
4007                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4008                            resultData, "app-request", true);
4009                }
4010                return res;
4011            } finally {
4012                Binder.restoreCallingIdentity(origId);
4013            }
4014        }
4015    }
4016
4017    @Override
4018    public final void finishHeavyWeightApp() {
4019        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4020                != PackageManager.PERMISSION_GRANTED) {
4021            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4022                    + Binder.getCallingPid()
4023                    + ", uid=" + Binder.getCallingUid()
4024                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4025            Slog.w(TAG, msg);
4026            throw new SecurityException(msg);
4027        }
4028
4029        synchronized(this) {
4030            if (mHeavyWeightProcess == null) {
4031                return;
4032            }
4033
4034            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4035                    mHeavyWeightProcess.activities);
4036            for (int i=0; i<activities.size(); i++) {
4037                ActivityRecord r = activities.get(i);
4038                if (!r.finishing) {
4039                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4040                            null, "finish-heavy", true);
4041                }
4042            }
4043
4044            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4045                    mHeavyWeightProcess.userId, 0));
4046            mHeavyWeightProcess = null;
4047        }
4048    }
4049
4050    @Override
4051    public void crashApplication(int uid, int initialPid, String packageName,
4052            String message) {
4053        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4054                != PackageManager.PERMISSION_GRANTED) {
4055            String msg = "Permission Denial: crashApplication() from pid="
4056                    + Binder.getCallingPid()
4057                    + ", uid=" + Binder.getCallingUid()
4058                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4059            Slog.w(TAG, msg);
4060            throw new SecurityException(msg);
4061        }
4062
4063        synchronized(this) {
4064            ProcessRecord proc = null;
4065
4066            // Figure out which process to kill.  We don't trust that initialPid
4067            // still has any relation to current pids, so must scan through the
4068            // list.
4069            synchronized (mPidsSelfLocked) {
4070                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4071                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4072                    if (p.uid != uid) {
4073                        continue;
4074                    }
4075                    if (p.pid == initialPid) {
4076                        proc = p;
4077                        break;
4078                    }
4079                    if (p.pkgList.containsKey(packageName)) {
4080                        proc = p;
4081                    }
4082                }
4083            }
4084
4085            if (proc == null) {
4086                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4087                        + " initialPid=" + initialPid
4088                        + " packageName=" + packageName);
4089                return;
4090            }
4091
4092            if (proc.thread != null) {
4093                if (proc.pid == Process.myPid()) {
4094                    Log.w(TAG, "crashApplication: trying to crash self!");
4095                    return;
4096                }
4097                long ident = Binder.clearCallingIdentity();
4098                try {
4099                    proc.thread.scheduleCrash(message);
4100                } catch (RemoteException e) {
4101                }
4102                Binder.restoreCallingIdentity(ident);
4103            }
4104        }
4105    }
4106
4107    @Override
4108    public final void finishSubActivity(IBinder token, String resultWho,
4109            int requestCode) {
4110        synchronized(this) {
4111            final long origId = Binder.clearCallingIdentity();
4112            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4113            if (r != null) {
4114                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4115            }
4116            Binder.restoreCallingIdentity(origId);
4117        }
4118    }
4119
4120    @Override
4121    public boolean finishActivityAffinity(IBinder token) {
4122        synchronized(this) {
4123            final long origId = Binder.clearCallingIdentity();
4124            try {
4125                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4126
4127                ActivityRecord rootR = r.task.getRootActivity();
4128                // Do not allow task to finish in Lock Task mode.
4129                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4130                    if (rootR == r) {
4131                        mStackSupervisor.showLockTaskToast();
4132                        return false;
4133                    }
4134                }
4135                boolean res = false;
4136                if (r != null) {
4137                    res = r.task.stack.finishActivityAffinityLocked(r);
4138                }
4139                return res;
4140            } finally {
4141                Binder.restoreCallingIdentity(origId);
4142            }
4143        }
4144    }
4145
4146    @Override
4147    public void finishVoiceTask(IVoiceInteractionSession session) {
4148        synchronized(this) {
4149            final long origId = Binder.clearCallingIdentity();
4150            try {
4151                mStackSupervisor.finishVoiceTask(session);
4152            } finally {
4153                Binder.restoreCallingIdentity(origId);
4154            }
4155        }
4156
4157    }
4158
4159    @Override
4160    public boolean releaseActivityInstance(IBinder token) {
4161        synchronized(this) {
4162            final long origId = Binder.clearCallingIdentity();
4163            try {
4164                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4165                if (r.task == null || r.task.stack == null) {
4166                    return false;
4167                }
4168                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4169            } finally {
4170                Binder.restoreCallingIdentity(origId);
4171            }
4172        }
4173    }
4174
4175    @Override
4176    public void releaseSomeActivities(IApplicationThread appInt) {
4177        synchronized(this) {
4178            final long origId = Binder.clearCallingIdentity();
4179            try {
4180                ProcessRecord app = getRecordForAppLocked(appInt);
4181                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4182            } finally {
4183                Binder.restoreCallingIdentity(origId);
4184            }
4185        }
4186    }
4187
4188    @Override
4189    public boolean willActivityBeVisible(IBinder token) {
4190        synchronized(this) {
4191            ActivityStack stack = ActivityRecord.getStackLocked(token);
4192            if (stack != null) {
4193                return stack.willActivityBeVisibleLocked(token);
4194            }
4195            return false;
4196        }
4197    }
4198
4199    @Override
4200    public void overridePendingTransition(IBinder token, String packageName,
4201            int enterAnim, int exitAnim) {
4202        synchronized(this) {
4203            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4204            if (self == null) {
4205                return;
4206            }
4207
4208            final long origId = Binder.clearCallingIdentity();
4209
4210            if (self.state == ActivityState.RESUMED
4211                    || self.state == ActivityState.PAUSING) {
4212                mWindowManager.overridePendingAppTransition(packageName,
4213                        enterAnim, exitAnim, null);
4214            }
4215
4216            Binder.restoreCallingIdentity(origId);
4217        }
4218    }
4219
4220    /**
4221     * Main function for removing an existing process from the activity manager
4222     * as a result of that process going away.  Clears out all connections
4223     * to the process.
4224     */
4225    private final void handleAppDiedLocked(ProcessRecord app,
4226            boolean restarting, boolean allowRestart) {
4227        int pid = app.pid;
4228        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4229        if (!restarting) {
4230            removeLruProcessLocked(app);
4231            if (pid > 0) {
4232                ProcessList.remove(pid);
4233            }
4234        }
4235
4236        if (mProfileProc == app) {
4237            clearProfilerLocked();
4238        }
4239
4240        // Remove this application's activities from active lists.
4241        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4242
4243        app.activities.clear();
4244
4245        if (app.instrumentationClass != null) {
4246            Slog.w(TAG, "Crash of app " + app.processName
4247                  + " running instrumentation " + app.instrumentationClass);
4248            Bundle info = new Bundle();
4249            info.putString("shortMsg", "Process crashed.");
4250            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4251        }
4252
4253        if (!restarting) {
4254            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4255                // If there was nothing to resume, and we are not already
4256                // restarting this process, but there is a visible activity that
4257                // is hosted by the process...  then make sure all visible
4258                // activities are running, taking care of restarting this
4259                // process.
4260                if (hasVisibleActivities) {
4261                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4262                }
4263            }
4264        }
4265    }
4266
4267    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4268        IBinder threadBinder = thread.asBinder();
4269        // Find the application record.
4270        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4271            ProcessRecord rec = mLruProcesses.get(i);
4272            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4273                return i;
4274            }
4275        }
4276        return -1;
4277    }
4278
4279    final ProcessRecord getRecordForAppLocked(
4280            IApplicationThread thread) {
4281        if (thread == null) {
4282            return null;
4283        }
4284
4285        int appIndex = getLRURecordIndexForAppLocked(thread);
4286        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4287    }
4288
4289    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4290        // If there are no longer any background processes running,
4291        // and the app that died was not running instrumentation,
4292        // then tell everyone we are now low on memory.
4293        boolean haveBg = false;
4294        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4295            ProcessRecord rec = mLruProcesses.get(i);
4296            if (rec.thread != null
4297                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4298                haveBg = true;
4299                break;
4300            }
4301        }
4302
4303        if (!haveBg) {
4304            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4305            if (doReport) {
4306                long now = SystemClock.uptimeMillis();
4307                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4308                    doReport = false;
4309                } else {
4310                    mLastMemUsageReportTime = now;
4311                }
4312            }
4313            final ArrayList<ProcessMemInfo> memInfos
4314                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4315            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4316            long now = SystemClock.uptimeMillis();
4317            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4318                ProcessRecord rec = mLruProcesses.get(i);
4319                if (rec == dyingProc || rec.thread == null) {
4320                    continue;
4321                }
4322                if (doReport) {
4323                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4324                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4325                }
4326                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4327                    // The low memory report is overriding any current
4328                    // state for a GC request.  Make sure to do
4329                    // heavy/important/visible/foreground processes first.
4330                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4331                        rec.lastRequestedGc = 0;
4332                    } else {
4333                        rec.lastRequestedGc = rec.lastLowMemory;
4334                    }
4335                    rec.reportLowMemory = true;
4336                    rec.lastLowMemory = now;
4337                    mProcessesToGc.remove(rec);
4338                    addProcessToGcListLocked(rec);
4339                }
4340            }
4341            if (doReport) {
4342                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4343                mHandler.sendMessage(msg);
4344            }
4345            scheduleAppGcsLocked();
4346        }
4347    }
4348
4349    final void appDiedLocked(ProcessRecord app) {
4350       appDiedLocked(app, app.pid, app.thread);
4351    }
4352
4353    final void appDiedLocked(ProcessRecord app, int pid,
4354            IApplicationThread thread) {
4355
4356        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4357        synchronized (stats) {
4358            stats.noteProcessDiedLocked(app.info.uid, pid);
4359        }
4360
4361        Process.killProcessGroup(app.info.uid, pid);
4362
4363        // Clean up already done if the process has been re-started.
4364        if (app.pid == pid && app.thread != null &&
4365                app.thread.asBinder() == thread.asBinder()) {
4366            boolean doLowMem = app.instrumentationClass == null;
4367            boolean doOomAdj = doLowMem;
4368            if (!app.killedByAm) {
4369                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4370                        + ") has died.");
4371                mAllowLowerMemLevel = true;
4372            } else {
4373                // Note that we always want to do oom adj to update our state with the
4374                // new number of procs.
4375                mAllowLowerMemLevel = false;
4376                doLowMem = false;
4377            }
4378            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4379            if (DEBUG_CLEANUP) Slog.v(
4380                TAG, "Dying app: " + app + ", pid: " + pid
4381                + ", thread: " + thread.asBinder());
4382            handleAppDiedLocked(app, false, true);
4383
4384            if (doOomAdj) {
4385                updateOomAdjLocked();
4386            }
4387            if (doLowMem) {
4388                doLowMemReportIfNeededLocked(app);
4389            }
4390        } else if (app.pid != pid) {
4391            // A new process has already been started.
4392            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4393                    + ") has died and restarted (pid " + app.pid + ").");
4394            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4395        } else if (DEBUG_PROCESSES) {
4396            Slog.d(TAG, "Received spurious death notification for thread "
4397                    + thread.asBinder());
4398        }
4399    }
4400
4401    /**
4402     * If a stack trace dump file is configured, dump process stack traces.
4403     * @param clearTraces causes the dump file to be erased prior to the new
4404     *    traces being written, if true; when false, the new traces will be
4405     *    appended to any existing file content.
4406     * @param firstPids of dalvik VM processes to dump stack traces for first
4407     * @param lastPids of dalvik VM processes to dump stack traces for last
4408     * @param nativeProcs optional list of native process names to dump stack crawls
4409     * @return file containing stack traces, or null if no dump file is configured
4410     */
4411    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4412            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4413        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4414        if (tracesPath == null || tracesPath.length() == 0) {
4415            return null;
4416        }
4417
4418        File tracesFile = new File(tracesPath);
4419        try {
4420            File tracesDir = tracesFile.getParentFile();
4421            if (!tracesDir.exists()) {
4422                tracesFile.mkdirs();
4423                if (!SELinux.restorecon(tracesDir)) {
4424                    return null;
4425                }
4426            }
4427            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4428
4429            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4430            tracesFile.createNewFile();
4431            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4432        } catch (IOException e) {
4433            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4434            return null;
4435        }
4436
4437        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4438        return tracesFile;
4439    }
4440
4441    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4442            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4443        // Use a FileObserver to detect when traces finish writing.
4444        // The order of traces is considered important to maintain for legibility.
4445        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4446            @Override
4447            public synchronized void onEvent(int event, String path) { notify(); }
4448        };
4449
4450        try {
4451            observer.startWatching();
4452
4453            // First collect all of the stacks of the most important pids.
4454            if (firstPids != null) {
4455                try {
4456                    int num = firstPids.size();
4457                    for (int i = 0; i < num; i++) {
4458                        synchronized (observer) {
4459                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4460                            observer.wait(200);  // Wait for write-close, give up after 200msec
4461                        }
4462                    }
4463                } catch (InterruptedException e) {
4464                    Log.wtf(TAG, e);
4465                }
4466            }
4467
4468            // Next collect the stacks of the native pids
4469            if (nativeProcs != null) {
4470                int[] pids = Process.getPidsForCommands(nativeProcs);
4471                if (pids != null) {
4472                    for (int pid : pids) {
4473                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4474                    }
4475                }
4476            }
4477
4478            // Lastly, measure CPU usage.
4479            if (processCpuTracker != null) {
4480                processCpuTracker.init();
4481                System.gc();
4482                processCpuTracker.update();
4483                try {
4484                    synchronized (processCpuTracker) {
4485                        processCpuTracker.wait(500); // measure over 1/2 second.
4486                    }
4487                } catch (InterruptedException e) {
4488                }
4489                processCpuTracker.update();
4490
4491                // We'll take the stack crawls of just the top apps using CPU.
4492                final int N = processCpuTracker.countWorkingStats();
4493                int numProcs = 0;
4494                for (int i=0; i<N && numProcs<5; i++) {
4495                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4496                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4497                        numProcs++;
4498                        try {
4499                            synchronized (observer) {
4500                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4501                                observer.wait(200);  // Wait for write-close, give up after 200msec
4502                            }
4503                        } catch (InterruptedException e) {
4504                            Log.wtf(TAG, e);
4505                        }
4506
4507                    }
4508                }
4509            }
4510        } finally {
4511            observer.stopWatching();
4512        }
4513    }
4514
4515    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4516        if (true || IS_USER_BUILD) {
4517            return;
4518        }
4519        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4520        if (tracesPath == null || tracesPath.length() == 0) {
4521            return;
4522        }
4523
4524        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4525        StrictMode.allowThreadDiskWrites();
4526        try {
4527            final File tracesFile = new File(tracesPath);
4528            final File tracesDir = tracesFile.getParentFile();
4529            final File tracesTmp = new File(tracesDir, "__tmp__");
4530            try {
4531                if (!tracesDir.exists()) {
4532                    tracesFile.mkdirs();
4533                    if (!SELinux.restorecon(tracesDir.getPath())) {
4534                        return;
4535                    }
4536                }
4537                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4538
4539                if (tracesFile.exists()) {
4540                    tracesTmp.delete();
4541                    tracesFile.renameTo(tracesTmp);
4542                }
4543                StringBuilder sb = new StringBuilder();
4544                Time tobj = new Time();
4545                tobj.set(System.currentTimeMillis());
4546                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4547                sb.append(": ");
4548                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4549                sb.append(" since ");
4550                sb.append(msg);
4551                FileOutputStream fos = new FileOutputStream(tracesFile);
4552                fos.write(sb.toString().getBytes());
4553                if (app == null) {
4554                    fos.write("\n*** No application process!".getBytes());
4555                }
4556                fos.close();
4557                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4558            } catch (IOException e) {
4559                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4560                return;
4561            }
4562
4563            if (app != null) {
4564                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4565                firstPids.add(app.pid);
4566                dumpStackTraces(tracesPath, firstPids, null, null, null);
4567            }
4568
4569            File lastTracesFile = null;
4570            File curTracesFile = null;
4571            for (int i=9; i>=0; i--) {
4572                String name = String.format(Locale.US, "slow%02d.txt", i);
4573                curTracesFile = new File(tracesDir, name);
4574                if (curTracesFile.exists()) {
4575                    if (lastTracesFile != null) {
4576                        curTracesFile.renameTo(lastTracesFile);
4577                    } else {
4578                        curTracesFile.delete();
4579                    }
4580                }
4581                lastTracesFile = curTracesFile;
4582            }
4583            tracesFile.renameTo(curTracesFile);
4584            if (tracesTmp.exists()) {
4585                tracesTmp.renameTo(tracesFile);
4586            }
4587        } finally {
4588            StrictMode.setThreadPolicy(oldPolicy);
4589        }
4590    }
4591
4592    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4593            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4594        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4595        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4596
4597        if (mController != null) {
4598            try {
4599                // 0 == continue, -1 = kill process immediately
4600                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4601                if (res < 0 && app.pid != MY_PID) {
4602                    app.kill("anr", true);
4603                }
4604            } catch (RemoteException e) {
4605                mController = null;
4606                Watchdog.getInstance().setActivityController(null);
4607            }
4608        }
4609
4610        long anrTime = SystemClock.uptimeMillis();
4611        if (MONITOR_CPU_USAGE) {
4612            updateCpuStatsNow();
4613        }
4614
4615        synchronized (this) {
4616            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4617            if (mShuttingDown) {
4618                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4619                return;
4620            } else if (app.notResponding) {
4621                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4622                return;
4623            } else if (app.crashing) {
4624                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4625                return;
4626            }
4627
4628            // In case we come through here for the same app before completing
4629            // this one, mark as anring now so we will bail out.
4630            app.notResponding = true;
4631
4632            // Log the ANR to the event log.
4633            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4634                    app.processName, app.info.flags, annotation);
4635
4636            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4637            firstPids.add(app.pid);
4638
4639            int parentPid = app.pid;
4640            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4641            if (parentPid != app.pid) firstPids.add(parentPid);
4642
4643            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4644
4645            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4646                ProcessRecord r = mLruProcesses.get(i);
4647                if (r != null && r.thread != null) {
4648                    int pid = r.pid;
4649                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4650                        if (r.persistent) {
4651                            firstPids.add(pid);
4652                        } else {
4653                            lastPids.put(pid, Boolean.TRUE);
4654                        }
4655                    }
4656                }
4657            }
4658        }
4659
4660        // Log the ANR to the main log.
4661        StringBuilder info = new StringBuilder();
4662        info.setLength(0);
4663        info.append("ANR in ").append(app.processName);
4664        if (activity != null && activity.shortComponentName != null) {
4665            info.append(" (").append(activity.shortComponentName).append(")");
4666        }
4667        info.append("\n");
4668        info.append("PID: ").append(app.pid).append("\n");
4669        if (annotation != null) {
4670            info.append("Reason: ").append(annotation).append("\n");
4671        }
4672        if (parent != null && parent != activity) {
4673            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4674        }
4675
4676        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4677
4678        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4679                NATIVE_STACKS_OF_INTEREST);
4680
4681        String cpuInfo = null;
4682        if (MONITOR_CPU_USAGE) {
4683            updateCpuStatsNow();
4684            synchronized (mProcessCpuThread) {
4685                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4686            }
4687            info.append(processCpuTracker.printCurrentLoad());
4688            info.append(cpuInfo);
4689        }
4690
4691        info.append(processCpuTracker.printCurrentState(anrTime));
4692
4693        Slog.e(TAG, info.toString());
4694        if (tracesFile == null) {
4695            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4696            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4697        }
4698
4699        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4700                cpuInfo, tracesFile, null);
4701
4702        if (mController != null) {
4703            try {
4704                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4705                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4706                if (res != 0) {
4707                    if (res < 0 && app.pid != MY_PID) {
4708                        app.kill("anr", true);
4709                    } else {
4710                        synchronized (this) {
4711                            mServices.scheduleServiceTimeoutLocked(app);
4712                        }
4713                    }
4714                    return;
4715                }
4716            } catch (RemoteException e) {
4717                mController = null;
4718                Watchdog.getInstance().setActivityController(null);
4719            }
4720        }
4721
4722        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4723        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4724                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4725
4726        synchronized (this) {
4727            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4728                app.kill("bg anr", true);
4729                return;
4730            }
4731
4732            // Set the app's notResponding state, and look up the errorReportReceiver
4733            makeAppNotRespondingLocked(app,
4734                    activity != null ? activity.shortComponentName : null,
4735                    annotation != null ? "ANR " + annotation : "ANR",
4736                    info.toString());
4737
4738            // Bring up the infamous App Not Responding dialog
4739            Message msg = Message.obtain();
4740            HashMap<String, Object> map = new HashMap<String, Object>();
4741            msg.what = SHOW_NOT_RESPONDING_MSG;
4742            msg.obj = map;
4743            msg.arg1 = aboveSystem ? 1 : 0;
4744            map.put("app", app);
4745            if (activity != null) {
4746                map.put("activity", activity);
4747            }
4748
4749            mHandler.sendMessage(msg);
4750        }
4751    }
4752
4753    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4754        if (!mLaunchWarningShown) {
4755            mLaunchWarningShown = true;
4756            mHandler.post(new Runnable() {
4757                @Override
4758                public void run() {
4759                    synchronized (ActivityManagerService.this) {
4760                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4761                        d.show();
4762                        mHandler.postDelayed(new Runnable() {
4763                            @Override
4764                            public void run() {
4765                                synchronized (ActivityManagerService.this) {
4766                                    d.dismiss();
4767                                    mLaunchWarningShown = false;
4768                                }
4769                            }
4770                        }, 4000);
4771                    }
4772                }
4773            });
4774        }
4775    }
4776
4777    @Override
4778    public boolean clearApplicationUserData(final String packageName,
4779            final IPackageDataObserver observer, int userId) {
4780        enforceNotIsolatedCaller("clearApplicationUserData");
4781        int uid = Binder.getCallingUid();
4782        int pid = Binder.getCallingPid();
4783        userId = handleIncomingUser(pid, uid,
4784                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4785        long callingId = Binder.clearCallingIdentity();
4786        try {
4787            IPackageManager pm = AppGlobals.getPackageManager();
4788            int pkgUid = -1;
4789            synchronized(this) {
4790                try {
4791                    pkgUid = pm.getPackageUid(packageName, userId);
4792                } catch (RemoteException e) {
4793                }
4794                if (pkgUid == -1) {
4795                    Slog.w(TAG, "Invalid packageName: " + packageName);
4796                    if (observer != null) {
4797                        try {
4798                            observer.onRemoveCompleted(packageName, false);
4799                        } catch (RemoteException e) {
4800                            Slog.i(TAG, "Observer no longer exists.");
4801                        }
4802                    }
4803                    return false;
4804                }
4805                if (uid == pkgUid || checkComponentPermission(
4806                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4807                        pid, uid, -1, true)
4808                        == PackageManager.PERMISSION_GRANTED) {
4809                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4810                } else {
4811                    throw new SecurityException("PID " + pid + " does not have permission "
4812                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4813                                    + " of package " + packageName);
4814                }
4815
4816                // Remove all tasks match the cleared application package and user
4817                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4818                    final TaskRecord tr = mRecentTasks.get(i);
4819                    final String taskPackageName =
4820                            tr.getBaseIntent().getComponent().getPackageName();
4821                    if (tr.userId != userId) continue;
4822                    if (!taskPackageName.equals(packageName)) continue;
4823                    removeTaskByIdLocked(tr.taskId, 0);
4824                }
4825            }
4826
4827            try {
4828                // Clear application user data
4829                pm.clearApplicationUserData(packageName, observer, userId);
4830
4831                synchronized(this) {
4832                    // Remove all permissions granted from/to this package
4833                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4834                }
4835
4836                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4837                        Uri.fromParts("package", packageName, null));
4838                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4839                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4840                        null, null, 0, null, null, null, false, false, userId);
4841            } catch (RemoteException e) {
4842            }
4843        } finally {
4844            Binder.restoreCallingIdentity(callingId);
4845        }
4846        return true;
4847    }
4848
4849    @Override
4850    public void killBackgroundProcesses(final String packageName, int userId) {
4851        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4852                != PackageManager.PERMISSION_GRANTED &&
4853                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4854                        != PackageManager.PERMISSION_GRANTED) {
4855            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4856                    + Binder.getCallingPid()
4857                    + ", uid=" + Binder.getCallingUid()
4858                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4859            Slog.w(TAG, msg);
4860            throw new SecurityException(msg);
4861        }
4862
4863        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4864                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4865        long callingId = Binder.clearCallingIdentity();
4866        try {
4867            IPackageManager pm = AppGlobals.getPackageManager();
4868            synchronized(this) {
4869                int appId = -1;
4870                try {
4871                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4872                } catch (RemoteException e) {
4873                }
4874                if (appId == -1) {
4875                    Slog.w(TAG, "Invalid packageName: " + packageName);
4876                    return;
4877                }
4878                killPackageProcessesLocked(packageName, appId, userId,
4879                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4880            }
4881        } finally {
4882            Binder.restoreCallingIdentity(callingId);
4883        }
4884    }
4885
4886    @Override
4887    public void killAllBackgroundProcesses() {
4888        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4889                != PackageManager.PERMISSION_GRANTED) {
4890            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4891                    + Binder.getCallingPid()
4892                    + ", uid=" + Binder.getCallingUid()
4893                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4894            Slog.w(TAG, msg);
4895            throw new SecurityException(msg);
4896        }
4897
4898        long callingId = Binder.clearCallingIdentity();
4899        try {
4900            synchronized(this) {
4901                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4902                final int NP = mProcessNames.getMap().size();
4903                for (int ip=0; ip<NP; ip++) {
4904                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4905                    final int NA = apps.size();
4906                    for (int ia=0; ia<NA; ia++) {
4907                        ProcessRecord app = apps.valueAt(ia);
4908                        if (app.persistent) {
4909                            // we don't kill persistent processes
4910                            continue;
4911                        }
4912                        if (app.removed) {
4913                            procs.add(app);
4914                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4915                            app.removed = true;
4916                            procs.add(app);
4917                        }
4918                    }
4919                }
4920
4921                int N = procs.size();
4922                for (int i=0; i<N; i++) {
4923                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4924                }
4925                mAllowLowerMemLevel = true;
4926                updateOomAdjLocked();
4927                doLowMemReportIfNeededLocked(null);
4928            }
4929        } finally {
4930            Binder.restoreCallingIdentity(callingId);
4931        }
4932    }
4933
4934    @Override
4935    public void forceStopPackage(final String packageName, int userId) {
4936        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4937                != PackageManager.PERMISSION_GRANTED) {
4938            String msg = "Permission Denial: forceStopPackage() from pid="
4939                    + Binder.getCallingPid()
4940                    + ", uid=" + Binder.getCallingUid()
4941                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4942            Slog.w(TAG, msg);
4943            throw new SecurityException(msg);
4944        }
4945        final int callingPid = Binder.getCallingPid();
4946        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4947                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4948        long callingId = Binder.clearCallingIdentity();
4949        try {
4950            IPackageManager pm = AppGlobals.getPackageManager();
4951            synchronized(this) {
4952                int[] users = userId == UserHandle.USER_ALL
4953                        ? getUsersLocked() : new int[] { userId };
4954                for (int user : users) {
4955                    int pkgUid = -1;
4956                    try {
4957                        pkgUid = pm.getPackageUid(packageName, user);
4958                    } catch (RemoteException e) {
4959                    }
4960                    if (pkgUid == -1) {
4961                        Slog.w(TAG, "Invalid packageName: " + packageName);
4962                        continue;
4963                    }
4964                    try {
4965                        pm.setPackageStoppedState(packageName, true, user);
4966                    } catch (RemoteException e) {
4967                    } catch (IllegalArgumentException e) {
4968                        Slog.w(TAG, "Failed trying to unstop package "
4969                                + packageName + ": " + e);
4970                    }
4971                    if (isUserRunningLocked(user, false)) {
4972                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4973                    }
4974                }
4975            }
4976        } finally {
4977            Binder.restoreCallingIdentity(callingId);
4978        }
4979    }
4980
4981    @Override
4982    public void addPackageDependency(String packageName) {
4983        synchronized (this) {
4984            int callingPid = Binder.getCallingPid();
4985            if (callingPid == Process.myPid()) {
4986                //  Yeah, um, no.
4987                Slog.w(TAG, "Can't addPackageDependency on system process");
4988                return;
4989            }
4990            ProcessRecord proc;
4991            synchronized (mPidsSelfLocked) {
4992                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4993            }
4994            if (proc != null) {
4995                if (proc.pkgDeps == null) {
4996                    proc.pkgDeps = new ArraySet<String>(1);
4997                }
4998                proc.pkgDeps.add(packageName);
4999            }
5000        }
5001    }
5002
5003    /*
5004     * The pkg name and app id have to be specified.
5005     */
5006    @Override
5007    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5008        if (pkg == null) {
5009            return;
5010        }
5011        // Make sure the uid is valid.
5012        if (appid < 0) {
5013            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5014            return;
5015        }
5016        int callerUid = Binder.getCallingUid();
5017        // Only the system server can kill an application
5018        if (callerUid == Process.SYSTEM_UID) {
5019            // Post an aysnc message to kill the application
5020            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5021            msg.arg1 = appid;
5022            msg.arg2 = 0;
5023            Bundle bundle = new Bundle();
5024            bundle.putString("pkg", pkg);
5025            bundle.putString("reason", reason);
5026            msg.obj = bundle;
5027            mHandler.sendMessage(msg);
5028        } else {
5029            throw new SecurityException(callerUid + " cannot kill pkg: " +
5030                    pkg);
5031        }
5032    }
5033
5034    @Override
5035    public void closeSystemDialogs(String reason) {
5036        enforceNotIsolatedCaller("closeSystemDialogs");
5037
5038        final int pid = Binder.getCallingPid();
5039        final int uid = Binder.getCallingUid();
5040        final long origId = Binder.clearCallingIdentity();
5041        try {
5042            synchronized (this) {
5043                // Only allow this from foreground processes, so that background
5044                // applications can't abuse it to prevent system UI from being shown.
5045                if (uid >= Process.FIRST_APPLICATION_UID) {
5046                    ProcessRecord proc;
5047                    synchronized (mPidsSelfLocked) {
5048                        proc = mPidsSelfLocked.get(pid);
5049                    }
5050                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5051                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5052                                + " from background process " + proc);
5053                        return;
5054                    }
5055                }
5056                closeSystemDialogsLocked(reason);
5057            }
5058        } finally {
5059            Binder.restoreCallingIdentity(origId);
5060        }
5061    }
5062
5063    void closeSystemDialogsLocked(String reason) {
5064        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5065        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5066                | Intent.FLAG_RECEIVER_FOREGROUND);
5067        if (reason != null) {
5068            intent.putExtra("reason", reason);
5069        }
5070        mWindowManager.closeSystemDialogs(reason);
5071
5072        mStackSupervisor.closeSystemDialogsLocked();
5073
5074        broadcastIntentLocked(null, null, intent, null,
5075                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5076                Process.SYSTEM_UID, UserHandle.USER_ALL);
5077    }
5078
5079    @Override
5080    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5081        enforceNotIsolatedCaller("getProcessMemoryInfo");
5082        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5083        for (int i=pids.length-1; i>=0; i--) {
5084            ProcessRecord proc;
5085            int oomAdj;
5086            synchronized (this) {
5087                synchronized (mPidsSelfLocked) {
5088                    proc = mPidsSelfLocked.get(pids[i]);
5089                    oomAdj = proc != null ? proc.setAdj : 0;
5090                }
5091            }
5092            infos[i] = new Debug.MemoryInfo();
5093            Debug.getMemoryInfo(pids[i], infos[i]);
5094            if (proc != null) {
5095                synchronized (this) {
5096                    if (proc.thread != null && proc.setAdj == oomAdj) {
5097                        // Record this for posterity if the process has been stable.
5098                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5099                                infos[i].getTotalUss(), false, proc.pkgList);
5100                    }
5101                }
5102            }
5103        }
5104        return infos;
5105    }
5106
5107    @Override
5108    public long[] getProcessPss(int[] pids) {
5109        enforceNotIsolatedCaller("getProcessPss");
5110        long[] pss = new long[pids.length];
5111        for (int i=pids.length-1; i>=0; i--) {
5112            ProcessRecord proc;
5113            int oomAdj;
5114            synchronized (this) {
5115                synchronized (mPidsSelfLocked) {
5116                    proc = mPidsSelfLocked.get(pids[i]);
5117                    oomAdj = proc != null ? proc.setAdj : 0;
5118                }
5119            }
5120            long[] tmpUss = new long[1];
5121            pss[i] = Debug.getPss(pids[i], tmpUss);
5122            if (proc != null) {
5123                synchronized (this) {
5124                    if (proc.thread != null && proc.setAdj == oomAdj) {
5125                        // Record this for posterity if the process has been stable.
5126                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5127                    }
5128                }
5129            }
5130        }
5131        return pss;
5132    }
5133
5134    @Override
5135    public void killApplicationProcess(String processName, int uid) {
5136        if (processName == null) {
5137            return;
5138        }
5139
5140        int callerUid = Binder.getCallingUid();
5141        // Only the system server can kill an application
5142        if (callerUid == Process.SYSTEM_UID) {
5143            synchronized (this) {
5144                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5145                if (app != null && app.thread != null) {
5146                    try {
5147                        app.thread.scheduleSuicide();
5148                    } catch (RemoteException e) {
5149                        // If the other end already died, then our work here is done.
5150                    }
5151                } else {
5152                    Slog.w(TAG, "Process/uid not found attempting kill of "
5153                            + processName + " / " + uid);
5154                }
5155            }
5156        } else {
5157            throw new SecurityException(callerUid + " cannot kill app process: " +
5158                    processName);
5159        }
5160    }
5161
5162    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5163        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5164                false, true, false, false, UserHandle.getUserId(uid), reason);
5165        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5166                Uri.fromParts("package", packageName, null));
5167        if (!mProcessesReady) {
5168            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5169                    | Intent.FLAG_RECEIVER_FOREGROUND);
5170        }
5171        intent.putExtra(Intent.EXTRA_UID, uid);
5172        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5173        broadcastIntentLocked(null, null, intent,
5174                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5175                false, false,
5176                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5177    }
5178
5179    private void forceStopUserLocked(int userId, String reason) {
5180        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5181        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5182        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5183                | Intent.FLAG_RECEIVER_FOREGROUND);
5184        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5185        broadcastIntentLocked(null, null, intent,
5186                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5187                false, false,
5188                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5189    }
5190
5191    private final boolean killPackageProcessesLocked(String packageName, int appId,
5192            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5193            boolean doit, boolean evenPersistent, String reason) {
5194        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5195
5196        // Remove all processes this package may have touched: all with the
5197        // same UID (except for the system or root user), and all whose name
5198        // matches the package name.
5199        final int NP = mProcessNames.getMap().size();
5200        for (int ip=0; ip<NP; ip++) {
5201            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5202            final int NA = apps.size();
5203            for (int ia=0; ia<NA; ia++) {
5204                ProcessRecord app = apps.valueAt(ia);
5205                if (app.persistent && !evenPersistent) {
5206                    // we don't kill persistent processes
5207                    continue;
5208                }
5209                if (app.removed) {
5210                    if (doit) {
5211                        procs.add(app);
5212                    }
5213                    continue;
5214                }
5215
5216                // Skip process if it doesn't meet our oom adj requirement.
5217                if (app.setAdj < minOomAdj) {
5218                    continue;
5219                }
5220
5221                // If no package is specified, we call all processes under the
5222                // give user id.
5223                if (packageName == null) {
5224                    if (app.userId != userId) {
5225                        continue;
5226                    }
5227                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5228                        continue;
5229                    }
5230                // Package has been specified, we want to hit all processes
5231                // that match it.  We need to qualify this by the processes
5232                // that are running under the specified app and user ID.
5233                } else {
5234                    final boolean isDep = app.pkgDeps != null
5235                            && app.pkgDeps.contains(packageName);
5236                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5237                        continue;
5238                    }
5239                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5240                        continue;
5241                    }
5242                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5243                        continue;
5244                    }
5245                }
5246
5247                // Process has passed all conditions, kill it!
5248                if (!doit) {
5249                    return true;
5250                }
5251                app.removed = true;
5252                procs.add(app);
5253            }
5254        }
5255
5256        int N = procs.size();
5257        for (int i=0; i<N; i++) {
5258            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5259        }
5260        updateOomAdjLocked();
5261        return N > 0;
5262    }
5263
5264    private final boolean forceStopPackageLocked(String name, int appId,
5265            boolean callerWillRestart, boolean purgeCache, boolean doit,
5266            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5267        int i;
5268        int N;
5269
5270        if (userId == UserHandle.USER_ALL && name == null) {
5271            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5272        }
5273
5274        if (appId < 0 && name != null) {
5275            try {
5276                appId = UserHandle.getAppId(
5277                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5278            } catch (RemoteException e) {
5279            }
5280        }
5281
5282        if (doit) {
5283            if (name != null) {
5284                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5285                        + " user=" + userId + ": " + reason);
5286            } else {
5287                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5288            }
5289
5290            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5291            for (int ip=pmap.size()-1; ip>=0; ip--) {
5292                SparseArray<Long> ba = pmap.valueAt(ip);
5293                for (i=ba.size()-1; i>=0; i--) {
5294                    boolean remove = false;
5295                    final int entUid = ba.keyAt(i);
5296                    if (name != null) {
5297                        if (userId == UserHandle.USER_ALL) {
5298                            if (UserHandle.getAppId(entUid) == appId) {
5299                                remove = true;
5300                            }
5301                        } else {
5302                            if (entUid == UserHandle.getUid(userId, appId)) {
5303                                remove = true;
5304                            }
5305                        }
5306                    } else if (UserHandle.getUserId(entUid) == userId) {
5307                        remove = true;
5308                    }
5309                    if (remove) {
5310                        ba.removeAt(i);
5311                    }
5312                }
5313                if (ba.size() == 0) {
5314                    pmap.removeAt(ip);
5315                }
5316            }
5317        }
5318
5319        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5320                -100, callerWillRestart, true, doit, evenPersistent,
5321                name == null ? ("stop user " + userId) : ("stop " + name));
5322
5323        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5324            if (!doit) {
5325                return true;
5326            }
5327            didSomething = true;
5328        }
5329
5330        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5331            if (!doit) {
5332                return true;
5333            }
5334            didSomething = true;
5335        }
5336
5337        if (name == null) {
5338            // Remove all sticky broadcasts from this user.
5339            mStickyBroadcasts.remove(userId);
5340        }
5341
5342        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5343        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5344                userId, providers)) {
5345            if (!doit) {
5346                return true;
5347            }
5348            didSomething = true;
5349        }
5350        N = providers.size();
5351        for (i=0; i<N; i++) {
5352            removeDyingProviderLocked(null, providers.get(i), true);
5353        }
5354
5355        // Remove transient permissions granted from/to this package/user
5356        removeUriPermissionsForPackageLocked(name, userId, false);
5357
5358        if (name == null || uninstalling) {
5359            // Remove pending intents.  For now we only do this when force
5360            // stopping users, because we have some problems when doing this
5361            // for packages -- app widgets are not currently cleaned up for
5362            // such packages, so they can be left with bad pending intents.
5363            if (mIntentSenderRecords.size() > 0) {
5364                Iterator<WeakReference<PendingIntentRecord>> it
5365                        = mIntentSenderRecords.values().iterator();
5366                while (it.hasNext()) {
5367                    WeakReference<PendingIntentRecord> wpir = it.next();
5368                    if (wpir == null) {
5369                        it.remove();
5370                        continue;
5371                    }
5372                    PendingIntentRecord pir = wpir.get();
5373                    if (pir == null) {
5374                        it.remove();
5375                        continue;
5376                    }
5377                    if (name == null) {
5378                        // Stopping user, remove all objects for the user.
5379                        if (pir.key.userId != userId) {
5380                            // Not the same user, skip it.
5381                            continue;
5382                        }
5383                    } else {
5384                        if (UserHandle.getAppId(pir.uid) != appId) {
5385                            // Different app id, skip it.
5386                            continue;
5387                        }
5388                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5389                            // Different user, skip it.
5390                            continue;
5391                        }
5392                        if (!pir.key.packageName.equals(name)) {
5393                            // Different package, skip it.
5394                            continue;
5395                        }
5396                    }
5397                    if (!doit) {
5398                        return true;
5399                    }
5400                    didSomething = true;
5401                    it.remove();
5402                    pir.canceled = true;
5403                    if (pir.key.activity != null) {
5404                        pir.key.activity.pendingResults.remove(pir.ref);
5405                    }
5406                }
5407            }
5408        }
5409
5410        if (doit) {
5411            if (purgeCache && name != null) {
5412                AttributeCache ac = AttributeCache.instance();
5413                if (ac != null) {
5414                    ac.removePackage(name);
5415                }
5416            }
5417            if (mBooted) {
5418                mStackSupervisor.resumeTopActivitiesLocked();
5419                mStackSupervisor.scheduleIdleLocked();
5420            }
5421        }
5422
5423        return didSomething;
5424    }
5425
5426    private final boolean removeProcessLocked(ProcessRecord app,
5427            boolean callerWillRestart, boolean allowRestart, String reason) {
5428        final String name = app.processName;
5429        final int uid = app.uid;
5430        if (DEBUG_PROCESSES) Slog.d(
5431            TAG, "Force removing proc " + app.toShortString() + " (" + name
5432            + "/" + uid + ")");
5433
5434        mProcessNames.remove(name, uid);
5435        mIsolatedProcesses.remove(app.uid);
5436        if (mHeavyWeightProcess == app) {
5437            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5438                    mHeavyWeightProcess.userId, 0));
5439            mHeavyWeightProcess = null;
5440        }
5441        boolean needRestart = false;
5442        if (app.pid > 0 && app.pid != MY_PID) {
5443            int pid = app.pid;
5444            synchronized (mPidsSelfLocked) {
5445                mPidsSelfLocked.remove(pid);
5446                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5447            }
5448            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5449            if (app.isolated) {
5450                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5451            }
5452            app.kill(reason, true);
5453            handleAppDiedLocked(app, true, allowRestart);
5454            removeLruProcessLocked(app);
5455
5456            if (app.persistent && !app.isolated) {
5457                if (!callerWillRestart) {
5458                    addAppLocked(app.info, false, null /* ABI override */);
5459                } else {
5460                    needRestart = true;
5461                }
5462            }
5463        } else {
5464            mRemovedProcesses.add(app);
5465        }
5466
5467        return needRestart;
5468    }
5469
5470    private final void processStartTimedOutLocked(ProcessRecord app) {
5471        final int pid = app.pid;
5472        boolean gone = false;
5473        synchronized (mPidsSelfLocked) {
5474            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5475            if (knownApp != null && knownApp.thread == null) {
5476                mPidsSelfLocked.remove(pid);
5477                gone = true;
5478            }
5479        }
5480
5481        if (gone) {
5482            Slog.w(TAG, "Process " + app + " failed to attach");
5483            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5484                    pid, app.uid, app.processName);
5485            mProcessNames.remove(app.processName, app.uid);
5486            mIsolatedProcesses.remove(app.uid);
5487            if (mHeavyWeightProcess == app) {
5488                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5489                        mHeavyWeightProcess.userId, 0));
5490                mHeavyWeightProcess = null;
5491            }
5492            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5493            if (app.isolated) {
5494                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5495            }
5496            // Take care of any launching providers waiting for this process.
5497            checkAppInLaunchingProvidersLocked(app, true);
5498            // Take care of any services that are waiting for the process.
5499            mServices.processStartTimedOutLocked(app);
5500            app.kill("start timeout", true);
5501            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5502                Slog.w(TAG, "Unattached app died before backup, skipping");
5503                try {
5504                    IBackupManager bm = IBackupManager.Stub.asInterface(
5505                            ServiceManager.getService(Context.BACKUP_SERVICE));
5506                    bm.agentDisconnected(app.info.packageName);
5507                } catch (RemoteException e) {
5508                    // Can't happen; the backup manager is local
5509                }
5510            }
5511            if (isPendingBroadcastProcessLocked(pid)) {
5512                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5513                skipPendingBroadcastLocked(pid);
5514            }
5515        } else {
5516            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5517        }
5518    }
5519
5520    private final boolean attachApplicationLocked(IApplicationThread thread,
5521            int pid) {
5522
5523        // Find the application record that is being attached...  either via
5524        // the pid if we are running in multiple processes, or just pull the
5525        // next app record if we are emulating process with anonymous threads.
5526        ProcessRecord app;
5527        if (pid != MY_PID && pid >= 0) {
5528            synchronized (mPidsSelfLocked) {
5529                app = mPidsSelfLocked.get(pid);
5530            }
5531        } else {
5532            app = null;
5533        }
5534
5535        if (app == null) {
5536            Slog.w(TAG, "No pending application record for pid " + pid
5537                    + " (IApplicationThread " + thread + "); dropping process");
5538            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5539            if (pid > 0 && pid != MY_PID) {
5540                Process.killProcessQuiet(pid);
5541                //TODO: Process.killProcessGroup(app.info.uid, pid);
5542            } else {
5543                try {
5544                    thread.scheduleExit();
5545                } catch (Exception e) {
5546                    // Ignore exceptions.
5547                }
5548            }
5549            return false;
5550        }
5551
5552        // If this application record is still attached to a previous
5553        // process, clean it up now.
5554        if (app.thread != null) {
5555            handleAppDiedLocked(app, true, true);
5556        }
5557
5558        // Tell the process all about itself.
5559
5560        if (localLOGV) Slog.v(
5561                TAG, "Binding process pid " + pid + " to record " + app);
5562
5563        final String processName = app.processName;
5564        try {
5565            AppDeathRecipient adr = new AppDeathRecipient(
5566                    app, pid, thread);
5567            thread.asBinder().linkToDeath(adr, 0);
5568            app.deathRecipient = adr;
5569        } catch (RemoteException e) {
5570            app.resetPackageList(mProcessStats);
5571            startProcessLocked(app, "link fail", processName);
5572            return false;
5573        }
5574
5575        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5576
5577        app.makeActive(thread, mProcessStats);
5578        app.curAdj = app.setAdj = -100;
5579        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5580        app.forcingToForeground = null;
5581        updateProcessForegroundLocked(app, false, false);
5582        app.hasShownUi = false;
5583        app.debugging = false;
5584        app.cached = false;
5585
5586        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5587
5588        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5589        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5590
5591        if (!normalMode) {
5592            Slog.i(TAG, "Launching preboot mode app: " + app);
5593        }
5594
5595        if (localLOGV) Slog.v(
5596            TAG, "New app record " + app
5597            + " thread=" + thread.asBinder() + " pid=" + pid);
5598        try {
5599            int testMode = IApplicationThread.DEBUG_OFF;
5600            if (mDebugApp != null && mDebugApp.equals(processName)) {
5601                testMode = mWaitForDebugger
5602                    ? IApplicationThread.DEBUG_WAIT
5603                    : IApplicationThread.DEBUG_ON;
5604                app.debugging = true;
5605                if (mDebugTransient) {
5606                    mDebugApp = mOrigDebugApp;
5607                    mWaitForDebugger = mOrigWaitForDebugger;
5608                }
5609            }
5610            String profileFile = app.instrumentationProfileFile;
5611            ParcelFileDescriptor profileFd = null;
5612            int samplingInterval = 0;
5613            boolean profileAutoStop = false;
5614            if (mProfileApp != null && mProfileApp.equals(processName)) {
5615                mProfileProc = app;
5616                profileFile = mProfileFile;
5617                profileFd = mProfileFd;
5618                samplingInterval = mSamplingInterval;
5619                profileAutoStop = mAutoStopProfiler;
5620            }
5621            boolean enableOpenGlTrace = false;
5622            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5623                enableOpenGlTrace = true;
5624                mOpenGlTraceApp = null;
5625            }
5626
5627            // If the app is being launched for restore or full backup, set it up specially
5628            boolean isRestrictedBackupMode = false;
5629            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5630                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5631                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5632                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5633            }
5634
5635            ensurePackageDexOpt(app.instrumentationInfo != null
5636                    ? app.instrumentationInfo.packageName
5637                    : app.info.packageName);
5638            if (app.instrumentationClass != null) {
5639                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5640            }
5641            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5642                    + processName + " with config " + mConfiguration);
5643            ApplicationInfo appInfo = app.instrumentationInfo != null
5644                    ? app.instrumentationInfo : app.info;
5645            app.compat = compatibilityInfoForPackageLocked(appInfo);
5646            if (profileFd != null) {
5647                profileFd = profileFd.dup();
5648            }
5649            ProfilerInfo profilerInfo = profileFile == null ? null
5650                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5651            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5652                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5653                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5654                    isRestrictedBackupMode || !normalMode, app.persistent,
5655                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5656                    mCoreSettingsObserver.getCoreSettingsLocked());
5657            updateLruProcessLocked(app, false, null);
5658            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5659        } catch (Exception e) {
5660            // todo: Yikes!  What should we do?  For now we will try to
5661            // start another process, but that could easily get us in
5662            // an infinite loop of restarting processes...
5663            Slog.w(TAG, "Exception thrown during bind!", e);
5664
5665            app.resetPackageList(mProcessStats);
5666            app.unlinkDeathRecipient();
5667            startProcessLocked(app, "bind fail", processName);
5668            return false;
5669        }
5670
5671        // Remove this record from the list of starting applications.
5672        mPersistentStartingProcesses.remove(app);
5673        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5674                "Attach application locked removing on hold: " + app);
5675        mProcessesOnHold.remove(app);
5676
5677        boolean badApp = false;
5678        boolean didSomething = false;
5679
5680        // See if the top visible activity is waiting to run in this process...
5681        if (normalMode) {
5682            try {
5683                if (mStackSupervisor.attachApplicationLocked(app)) {
5684                    didSomething = true;
5685                }
5686            } catch (Exception e) {
5687                badApp = true;
5688            }
5689        }
5690
5691        // Find any services that should be running in this process...
5692        if (!badApp) {
5693            try {
5694                didSomething |= mServices.attachApplicationLocked(app, processName);
5695            } catch (Exception e) {
5696                badApp = true;
5697            }
5698        }
5699
5700        // Check if a next-broadcast receiver is in this process...
5701        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5702            try {
5703                didSomething |= sendPendingBroadcastsLocked(app);
5704            } catch (Exception e) {
5705                // If the app died trying to launch the receiver we declare it 'bad'
5706                badApp = true;
5707            }
5708        }
5709
5710        // Check whether the next backup agent is in this process...
5711        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5712            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5713            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5714            try {
5715                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5716                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5717                        mBackupTarget.backupMode);
5718            } catch (Exception e) {
5719                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5720                e.printStackTrace();
5721            }
5722        }
5723
5724        if (badApp) {
5725            // todo: Also need to kill application to deal with all
5726            // kinds of exceptions.
5727            handleAppDiedLocked(app, false, true);
5728            return false;
5729        }
5730
5731        if (!didSomething) {
5732            updateOomAdjLocked();
5733        }
5734
5735        return true;
5736    }
5737
5738    @Override
5739    public final void attachApplication(IApplicationThread thread) {
5740        synchronized (this) {
5741            int callingPid = Binder.getCallingPid();
5742            final long origId = Binder.clearCallingIdentity();
5743            attachApplicationLocked(thread, callingPid);
5744            Binder.restoreCallingIdentity(origId);
5745        }
5746    }
5747
5748    @Override
5749    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5750        final long origId = Binder.clearCallingIdentity();
5751        synchronized (this) {
5752            ActivityStack stack = ActivityRecord.getStackLocked(token);
5753            if (stack != null) {
5754                ActivityRecord r =
5755                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5756                if (stopProfiling) {
5757                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5758                        try {
5759                            mProfileFd.close();
5760                        } catch (IOException e) {
5761                        }
5762                        clearProfilerLocked();
5763                    }
5764                }
5765            }
5766        }
5767        Binder.restoreCallingIdentity(origId);
5768    }
5769
5770    void postEnableScreenAfterBootLocked() {
5771        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5772    }
5773
5774    void enableScreenAfterBoot() {
5775        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5776                SystemClock.uptimeMillis());
5777        mWindowManager.enableScreenAfterBoot();
5778
5779        synchronized (this) {
5780            updateEventDispatchingLocked();
5781        }
5782    }
5783
5784    @Override
5785    public void showBootMessage(final CharSequence msg, final boolean always) {
5786        enforceNotIsolatedCaller("showBootMessage");
5787        mWindowManager.showBootMessage(msg, always);
5788    }
5789
5790    @Override
5791    public void keyguardWaitingForActivityDrawn() {
5792        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5793        final long token = Binder.clearCallingIdentity();
5794        try {
5795            synchronized (this) {
5796                if (DEBUG_LOCKSCREEN) logLockScreen("");
5797                mWindowManager.keyguardWaitingForActivityDrawn();
5798            }
5799        } finally {
5800            Binder.restoreCallingIdentity(token);
5801        }
5802    }
5803
5804    final void finishBooting() {
5805        // Register receivers to handle package update events
5806        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5807
5808        // Let system services know.
5809        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5810
5811        synchronized (this) {
5812            // Ensure that any processes we had put on hold are now started
5813            // up.
5814            final int NP = mProcessesOnHold.size();
5815            if (NP > 0) {
5816                ArrayList<ProcessRecord> procs =
5817                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5818                for (int ip=0; ip<NP; ip++) {
5819                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5820                            + procs.get(ip));
5821                    startProcessLocked(procs.get(ip), "on-hold", null);
5822                }
5823            }
5824
5825            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5826                // Start looking for apps that are abusing wake locks.
5827                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5828                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5829                // Tell anyone interested that we are done booting!
5830                SystemProperties.set("sys.boot_completed", "1");
5831                SystemProperties.set("dev.bootcomplete", "1");
5832                for (int i=0; i<mStartedUsers.size(); i++) {
5833                    UserStartedState uss = mStartedUsers.valueAt(i);
5834                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5835                        uss.mState = UserStartedState.STATE_RUNNING;
5836                        final int userId = mStartedUsers.keyAt(i);
5837                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5838                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5839                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5840                        broadcastIntentLocked(null, null, intent, null,
5841                                new IIntentReceiver.Stub() {
5842                                    @Override
5843                                    public void performReceive(Intent intent, int resultCode,
5844                                            String data, Bundle extras, boolean ordered,
5845                                            boolean sticky, int sendingUser) {
5846                                        synchronized (ActivityManagerService.this) {
5847                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5848                                                    true, false);
5849                                        }
5850                                    }
5851                                },
5852                                0, null, null,
5853                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5854                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5855                                userId);
5856                    }
5857                }
5858                scheduleStartProfilesLocked();
5859            }
5860        }
5861    }
5862
5863    final void ensureBootCompleted() {
5864        boolean booting;
5865        boolean enableScreen;
5866        synchronized (this) {
5867            booting = mBooting;
5868            mBooting = false;
5869            enableScreen = !mBooted;
5870            mBooted = true;
5871        }
5872
5873        if (booting) {
5874            finishBooting();
5875        }
5876
5877        if (enableScreen) {
5878            enableScreenAfterBoot();
5879        }
5880    }
5881
5882    @Override
5883    public final void activityResumed(IBinder token) {
5884        final long origId = Binder.clearCallingIdentity();
5885        synchronized(this) {
5886            ActivityStack stack = ActivityRecord.getStackLocked(token);
5887            if (stack != null) {
5888                ActivityRecord.activityResumedLocked(token);
5889            }
5890        }
5891        Binder.restoreCallingIdentity(origId);
5892    }
5893
5894    @Override
5895    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5896        final long origId = Binder.clearCallingIdentity();
5897        synchronized(this) {
5898            ActivityStack stack = ActivityRecord.getStackLocked(token);
5899            if (stack != null) {
5900                stack.activityPausedLocked(token, false, persistentState);
5901            }
5902        }
5903        Binder.restoreCallingIdentity(origId);
5904    }
5905
5906    @Override
5907    public final void activityStopped(IBinder token, Bundle icicle,
5908            PersistableBundle persistentState, CharSequence description) {
5909        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5910
5911        // Refuse possible leaked file descriptors
5912        if (icicle != null && icicle.hasFileDescriptors()) {
5913            throw new IllegalArgumentException("File descriptors passed in Bundle");
5914        }
5915
5916        final long origId = Binder.clearCallingIdentity();
5917
5918        synchronized (this) {
5919            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5920            if (r != null) {
5921                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5922            }
5923        }
5924
5925        trimApplications();
5926
5927        Binder.restoreCallingIdentity(origId);
5928    }
5929
5930    @Override
5931    public final void activityDestroyed(IBinder token) {
5932        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5933        synchronized (this) {
5934            ActivityStack stack = ActivityRecord.getStackLocked(token);
5935            if (stack != null) {
5936                stack.activityDestroyedLocked(token);
5937            }
5938        }
5939    }
5940
5941    @Override
5942    public final void backgroundResourcesReleased(IBinder token) {
5943        final long origId = Binder.clearCallingIdentity();
5944        try {
5945            synchronized (this) {
5946                ActivityStack stack = ActivityRecord.getStackLocked(token);
5947                if (stack != null) {
5948                    stack.backgroundResourcesReleased(token);
5949                }
5950            }
5951        } finally {
5952            Binder.restoreCallingIdentity(origId);
5953        }
5954    }
5955
5956    @Override
5957    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5958        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5959    }
5960
5961    @Override
5962    public final void notifyEnterAnimationComplete(IBinder token) {
5963        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5964    }
5965
5966    @Override
5967    public String getCallingPackage(IBinder token) {
5968        synchronized (this) {
5969            ActivityRecord r = getCallingRecordLocked(token);
5970            return r != null ? r.info.packageName : null;
5971        }
5972    }
5973
5974    @Override
5975    public ComponentName getCallingActivity(IBinder token) {
5976        synchronized (this) {
5977            ActivityRecord r = getCallingRecordLocked(token);
5978            return r != null ? r.intent.getComponent() : null;
5979        }
5980    }
5981
5982    private ActivityRecord getCallingRecordLocked(IBinder token) {
5983        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5984        if (r == null) {
5985            return null;
5986        }
5987        return r.resultTo;
5988    }
5989
5990    @Override
5991    public ComponentName getActivityClassForToken(IBinder token) {
5992        synchronized(this) {
5993            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5994            if (r == null) {
5995                return null;
5996            }
5997            return r.intent.getComponent();
5998        }
5999    }
6000
6001    @Override
6002    public String getPackageForToken(IBinder token) {
6003        synchronized(this) {
6004            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6005            if (r == null) {
6006                return null;
6007            }
6008            return r.packageName;
6009        }
6010    }
6011
6012    @Override
6013    public IIntentSender getIntentSender(int type,
6014            String packageName, IBinder token, String resultWho,
6015            int requestCode, Intent[] intents, String[] resolvedTypes,
6016            int flags, Bundle options, int userId) {
6017        enforceNotIsolatedCaller("getIntentSender");
6018        // Refuse possible leaked file descriptors
6019        if (intents != null) {
6020            if (intents.length < 1) {
6021                throw new IllegalArgumentException("Intents array length must be >= 1");
6022            }
6023            for (int i=0; i<intents.length; i++) {
6024                Intent intent = intents[i];
6025                if (intent != null) {
6026                    if (intent.hasFileDescriptors()) {
6027                        throw new IllegalArgumentException("File descriptors passed in Intent");
6028                    }
6029                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6030                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6031                        throw new IllegalArgumentException(
6032                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6033                    }
6034                    intents[i] = new Intent(intent);
6035                }
6036            }
6037            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6038                throw new IllegalArgumentException(
6039                        "Intent array length does not match resolvedTypes length");
6040            }
6041        }
6042        if (options != null) {
6043            if (options.hasFileDescriptors()) {
6044                throw new IllegalArgumentException("File descriptors passed in options");
6045            }
6046        }
6047
6048        synchronized(this) {
6049            int callingUid = Binder.getCallingUid();
6050            int origUserId = userId;
6051            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6052                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6053                    ALLOW_NON_FULL, "getIntentSender", null);
6054            if (origUserId == UserHandle.USER_CURRENT) {
6055                // We don't want to evaluate this until the pending intent is
6056                // actually executed.  However, we do want to always do the
6057                // security checking for it above.
6058                userId = UserHandle.USER_CURRENT;
6059            }
6060            try {
6061                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6062                    int uid = AppGlobals.getPackageManager()
6063                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6064                    if (!UserHandle.isSameApp(callingUid, uid)) {
6065                        String msg = "Permission Denial: getIntentSender() from pid="
6066                            + Binder.getCallingPid()
6067                            + ", uid=" + Binder.getCallingUid()
6068                            + ", (need uid=" + uid + ")"
6069                            + " is not allowed to send as package " + packageName;
6070                        Slog.w(TAG, msg);
6071                        throw new SecurityException(msg);
6072                    }
6073                }
6074
6075                return getIntentSenderLocked(type, packageName, callingUid, userId,
6076                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6077
6078            } catch (RemoteException e) {
6079                throw new SecurityException(e);
6080            }
6081        }
6082    }
6083
6084    IIntentSender getIntentSenderLocked(int type, String packageName,
6085            int callingUid, int userId, IBinder token, String resultWho,
6086            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6087            Bundle options) {
6088        if (DEBUG_MU)
6089            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6090        ActivityRecord activity = null;
6091        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6092            activity = ActivityRecord.isInStackLocked(token);
6093            if (activity == null) {
6094                return null;
6095            }
6096            if (activity.finishing) {
6097                return null;
6098            }
6099        }
6100
6101        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6102        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6103        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6104        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6105                |PendingIntent.FLAG_UPDATE_CURRENT);
6106
6107        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6108                type, packageName, activity, resultWho,
6109                requestCode, intents, resolvedTypes, flags, options, userId);
6110        WeakReference<PendingIntentRecord> ref;
6111        ref = mIntentSenderRecords.get(key);
6112        PendingIntentRecord rec = ref != null ? ref.get() : null;
6113        if (rec != null) {
6114            if (!cancelCurrent) {
6115                if (updateCurrent) {
6116                    if (rec.key.requestIntent != null) {
6117                        rec.key.requestIntent.replaceExtras(intents != null ?
6118                                intents[intents.length - 1] : null);
6119                    }
6120                    if (intents != null) {
6121                        intents[intents.length-1] = rec.key.requestIntent;
6122                        rec.key.allIntents = intents;
6123                        rec.key.allResolvedTypes = resolvedTypes;
6124                    } else {
6125                        rec.key.allIntents = null;
6126                        rec.key.allResolvedTypes = null;
6127                    }
6128                }
6129                return rec;
6130            }
6131            rec.canceled = true;
6132            mIntentSenderRecords.remove(key);
6133        }
6134        if (noCreate) {
6135            return rec;
6136        }
6137        rec = new PendingIntentRecord(this, key, callingUid);
6138        mIntentSenderRecords.put(key, rec.ref);
6139        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6140            if (activity.pendingResults == null) {
6141                activity.pendingResults
6142                        = new HashSet<WeakReference<PendingIntentRecord>>();
6143            }
6144            activity.pendingResults.add(rec.ref);
6145        }
6146        return rec;
6147    }
6148
6149    @Override
6150    public void cancelIntentSender(IIntentSender sender) {
6151        if (!(sender instanceof PendingIntentRecord)) {
6152            return;
6153        }
6154        synchronized(this) {
6155            PendingIntentRecord rec = (PendingIntentRecord)sender;
6156            try {
6157                int uid = AppGlobals.getPackageManager()
6158                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6159                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6160                    String msg = "Permission Denial: cancelIntentSender() from pid="
6161                        + Binder.getCallingPid()
6162                        + ", uid=" + Binder.getCallingUid()
6163                        + " is not allowed to cancel packges "
6164                        + rec.key.packageName;
6165                    Slog.w(TAG, msg);
6166                    throw new SecurityException(msg);
6167                }
6168            } catch (RemoteException e) {
6169                throw new SecurityException(e);
6170            }
6171            cancelIntentSenderLocked(rec, true);
6172        }
6173    }
6174
6175    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6176        rec.canceled = true;
6177        mIntentSenderRecords.remove(rec.key);
6178        if (cleanActivity && rec.key.activity != null) {
6179            rec.key.activity.pendingResults.remove(rec.ref);
6180        }
6181    }
6182
6183    @Override
6184    public String getPackageForIntentSender(IIntentSender pendingResult) {
6185        if (!(pendingResult instanceof PendingIntentRecord)) {
6186            return null;
6187        }
6188        try {
6189            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6190            return res.key.packageName;
6191        } catch (ClassCastException e) {
6192        }
6193        return null;
6194    }
6195
6196    @Override
6197    public int getUidForIntentSender(IIntentSender sender) {
6198        if (sender instanceof PendingIntentRecord) {
6199            try {
6200                PendingIntentRecord res = (PendingIntentRecord)sender;
6201                return res.uid;
6202            } catch (ClassCastException e) {
6203            }
6204        }
6205        return -1;
6206    }
6207
6208    @Override
6209    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6210        if (!(pendingResult instanceof PendingIntentRecord)) {
6211            return false;
6212        }
6213        try {
6214            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6215            if (res.key.allIntents == null) {
6216                return false;
6217            }
6218            for (int i=0; i<res.key.allIntents.length; i++) {
6219                Intent intent = res.key.allIntents[i];
6220                if (intent.getPackage() != null && intent.getComponent() != null) {
6221                    return false;
6222                }
6223            }
6224            return true;
6225        } catch (ClassCastException e) {
6226        }
6227        return false;
6228    }
6229
6230    @Override
6231    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6232        if (!(pendingResult instanceof PendingIntentRecord)) {
6233            return false;
6234        }
6235        try {
6236            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6237            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6238                return true;
6239            }
6240            return false;
6241        } catch (ClassCastException e) {
6242        }
6243        return false;
6244    }
6245
6246    @Override
6247    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6248        if (!(pendingResult instanceof PendingIntentRecord)) {
6249            return null;
6250        }
6251        try {
6252            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6253            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6254        } catch (ClassCastException e) {
6255        }
6256        return null;
6257    }
6258
6259    @Override
6260    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6261        if (!(pendingResult instanceof PendingIntentRecord)) {
6262            return null;
6263        }
6264        try {
6265            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6266            Intent intent = res.key.requestIntent;
6267            if (intent != null) {
6268                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6269                        || res.lastTagPrefix.equals(prefix))) {
6270                    return res.lastTag;
6271                }
6272                res.lastTagPrefix = prefix;
6273                StringBuilder sb = new StringBuilder(128);
6274                if (prefix != null) {
6275                    sb.append(prefix);
6276                }
6277                if (intent.getAction() != null) {
6278                    sb.append(intent.getAction());
6279                } else if (intent.getComponent() != null) {
6280                    intent.getComponent().appendShortString(sb);
6281                } else {
6282                    sb.append("?");
6283                }
6284                return res.lastTag = sb.toString();
6285            }
6286        } catch (ClassCastException e) {
6287        }
6288        return null;
6289    }
6290
6291    @Override
6292    public void setProcessLimit(int max) {
6293        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6294                "setProcessLimit()");
6295        synchronized (this) {
6296            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6297            mProcessLimitOverride = max;
6298        }
6299        trimApplications();
6300    }
6301
6302    @Override
6303    public int getProcessLimit() {
6304        synchronized (this) {
6305            return mProcessLimitOverride;
6306        }
6307    }
6308
6309    void foregroundTokenDied(ForegroundToken token) {
6310        synchronized (ActivityManagerService.this) {
6311            synchronized (mPidsSelfLocked) {
6312                ForegroundToken cur
6313                    = mForegroundProcesses.get(token.pid);
6314                if (cur != token) {
6315                    return;
6316                }
6317                mForegroundProcesses.remove(token.pid);
6318                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6319                if (pr == null) {
6320                    return;
6321                }
6322                pr.forcingToForeground = null;
6323                updateProcessForegroundLocked(pr, false, false);
6324            }
6325            updateOomAdjLocked();
6326        }
6327    }
6328
6329    @Override
6330    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6331        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6332                "setProcessForeground()");
6333        synchronized(this) {
6334            boolean changed = false;
6335
6336            synchronized (mPidsSelfLocked) {
6337                ProcessRecord pr = mPidsSelfLocked.get(pid);
6338                if (pr == null && isForeground) {
6339                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6340                    return;
6341                }
6342                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6343                if (oldToken != null) {
6344                    oldToken.token.unlinkToDeath(oldToken, 0);
6345                    mForegroundProcesses.remove(pid);
6346                    if (pr != null) {
6347                        pr.forcingToForeground = null;
6348                    }
6349                    changed = true;
6350                }
6351                if (isForeground && token != null) {
6352                    ForegroundToken newToken = new ForegroundToken() {
6353                        @Override
6354                        public void binderDied() {
6355                            foregroundTokenDied(this);
6356                        }
6357                    };
6358                    newToken.pid = pid;
6359                    newToken.token = token;
6360                    try {
6361                        token.linkToDeath(newToken, 0);
6362                        mForegroundProcesses.put(pid, newToken);
6363                        pr.forcingToForeground = token;
6364                        changed = true;
6365                    } catch (RemoteException e) {
6366                        // If the process died while doing this, we will later
6367                        // do the cleanup with the process death link.
6368                    }
6369                }
6370            }
6371
6372            if (changed) {
6373                updateOomAdjLocked();
6374            }
6375        }
6376    }
6377
6378    // =========================================================
6379    // PERMISSIONS
6380    // =========================================================
6381
6382    static class PermissionController extends IPermissionController.Stub {
6383        ActivityManagerService mActivityManagerService;
6384        PermissionController(ActivityManagerService activityManagerService) {
6385            mActivityManagerService = activityManagerService;
6386        }
6387
6388        @Override
6389        public boolean checkPermission(String permission, int pid, int uid) {
6390            return mActivityManagerService.checkPermission(permission, pid,
6391                    uid) == PackageManager.PERMISSION_GRANTED;
6392        }
6393    }
6394
6395    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6396        @Override
6397        public int checkComponentPermission(String permission, int pid, int uid,
6398                int owningUid, boolean exported) {
6399            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6400                    owningUid, exported);
6401        }
6402
6403        @Override
6404        public Object getAMSLock() {
6405            return ActivityManagerService.this;
6406        }
6407    }
6408
6409    /**
6410     * This can be called with or without the global lock held.
6411     */
6412    int checkComponentPermission(String permission, int pid, int uid,
6413            int owningUid, boolean exported) {
6414        // We might be performing an operation on behalf of an indirect binder
6415        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6416        // client identity accordingly before proceeding.
6417        Identity tlsIdentity = sCallerIdentity.get();
6418        if (tlsIdentity != null) {
6419            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6420                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6421            uid = tlsIdentity.uid;
6422            pid = tlsIdentity.pid;
6423        }
6424
6425        if (pid == MY_PID) {
6426            return PackageManager.PERMISSION_GRANTED;
6427        }
6428
6429        return ActivityManager.checkComponentPermission(permission, uid,
6430                owningUid, exported);
6431    }
6432
6433    /**
6434     * As the only public entry point for permissions checking, this method
6435     * can enforce the semantic that requesting a check on a null global
6436     * permission is automatically denied.  (Internally a null permission
6437     * string is used when calling {@link #checkComponentPermission} in cases
6438     * when only uid-based security is needed.)
6439     *
6440     * This can be called with or without the global lock held.
6441     */
6442    @Override
6443    public int checkPermission(String permission, int pid, int uid) {
6444        if (permission == null) {
6445            return PackageManager.PERMISSION_DENIED;
6446        }
6447        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6448    }
6449
6450    /**
6451     * Binder IPC calls go through the public entry point.
6452     * This can be called with or without the global lock held.
6453     */
6454    int checkCallingPermission(String permission) {
6455        return checkPermission(permission,
6456                Binder.getCallingPid(),
6457                UserHandle.getAppId(Binder.getCallingUid()));
6458    }
6459
6460    /**
6461     * This can be called with or without the global lock held.
6462     */
6463    void enforceCallingPermission(String permission, String func) {
6464        if (checkCallingPermission(permission)
6465                == PackageManager.PERMISSION_GRANTED) {
6466            return;
6467        }
6468
6469        String msg = "Permission Denial: " + func + " from pid="
6470                + Binder.getCallingPid()
6471                + ", uid=" + Binder.getCallingUid()
6472                + " requires " + permission;
6473        Slog.w(TAG, msg);
6474        throw new SecurityException(msg);
6475    }
6476
6477    /**
6478     * Determine if UID is holding permissions required to access {@link Uri} in
6479     * the given {@link ProviderInfo}. Final permission checking is always done
6480     * in {@link ContentProvider}.
6481     */
6482    private final boolean checkHoldingPermissionsLocked(
6483            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6484        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6485                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6486        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6487            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6488                    != PERMISSION_GRANTED) {
6489                return false;
6490            }
6491        }
6492        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6493    }
6494
6495    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6496            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6497        if (pi.applicationInfo.uid == uid) {
6498            return true;
6499        } else if (!pi.exported) {
6500            return false;
6501        }
6502
6503        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6504        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6505        try {
6506            // check if target holds top-level <provider> permissions
6507            if (!readMet && pi.readPermission != null && considerUidPermissions
6508                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6509                readMet = true;
6510            }
6511            if (!writeMet && pi.writePermission != null && considerUidPermissions
6512                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6513                writeMet = true;
6514            }
6515
6516            // track if unprotected read/write is allowed; any denied
6517            // <path-permission> below removes this ability
6518            boolean allowDefaultRead = pi.readPermission == null;
6519            boolean allowDefaultWrite = pi.writePermission == null;
6520
6521            // check if target holds any <path-permission> that match uri
6522            final PathPermission[] pps = pi.pathPermissions;
6523            if (pps != null) {
6524                final String path = grantUri.uri.getPath();
6525                int i = pps.length;
6526                while (i > 0 && (!readMet || !writeMet)) {
6527                    i--;
6528                    PathPermission pp = pps[i];
6529                    if (pp.match(path)) {
6530                        if (!readMet) {
6531                            final String pprperm = pp.getReadPermission();
6532                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6533                                    + pprperm + " for " + pp.getPath()
6534                                    + ": match=" + pp.match(path)
6535                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6536                            if (pprperm != null) {
6537                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6538                                        == PERMISSION_GRANTED) {
6539                                    readMet = true;
6540                                } else {
6541                                    allowDefaultRead = false;
6542                                }
6543                            }
6544                        }
6545                        if (!writeMet) {
6546                            final String ppwperm = pp.getWritePermission();
6547                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6548                                    + ppwperm + " for " + pp.getPath()
6549                                    + ": match=" + pp.match(path)
6550                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6551                            if (ppwperm != null) {
6552                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6553                                        == PERMISSION_GRANTED) {
6554                                    writeMet = true;
6555                                } else {
6556                                    allowDefaultWrite = false;
6557                                }
6558                            }
6559                        }
6560                    }
6561                }
6562            }
6563
6564            // grant unprotected <provider> read/write, if not blocked by
6565            // <path-permission> above
6566            if (allowDefaultRead) readMet = true;
6567            if (allowDefaultWrite) writeMet = true;
6568
6569        } catch (RemoteException e) {
6570            return false;
6571        }
6572
6573        return readMet && writeMet;
6574    }
6575
6576    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6577        ProviderInfo pi = null;
6578        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6579        if (cpr != null) {
6580            pi = cpr.info;
6581        } else {
6582            try {
6583                pi = AppGlobals.getPackageManager().resolveContentProvider(
6584                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6585            } catch (RemoteException ex) {
6586            }
6587        }
6588        return pi;
6589    }
6590
6591    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6592        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6593        if (targetUris != null) {
6594            return targetUris.get(grantUri);
6595        }
6596        return null;
6597    }
6598
6599    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6600            String targetPkg, int targetUid, GrantUri grantUri) {
6601        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6602        if (targetUris == null) {
6603            targetUris = Maps.newArrayMap();
6604            mGrantedUriPermissions.put(targetUid, targetUris);
6605        }
6606
6607        UriPermission perm = targetUris.get(grantUri);
6608        if (perm == null) {
6609            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6610            targetUris.put(grantUri, perm);
6611        }
6612
6613        return perm;
6614    }
6615
6616    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6617            final int modeFlags) {
6618        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6619        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6620                : UriPermission.STRENGTH_OWNED;
6621
6622        // Root gets to do everything.
6623        if (uid == 0) {
6624            return true;
6625        }
6626
6627        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6628        if (perms == null) return false;
6629
6630        // First look for exact match
6631        final UriPermission exactPerm = perms.get(grantUri);
6632        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6633            return true;
6634        }
6635
6636        // No exact match, look for prefixes
6637        final int N = perms.size();
6638        for (int i = 0; i < N; i++) {
6639            final UriPermission perm = perms.valueAt(i);
6640            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6641                    && perm.getStrength(modeFlags) >= minStrength) {
6642                return true;
6643            }
6644        }
6645
6646        return false;
6647    }
6648
6649    /**
6650     * @param uri This uri must NOT contain an embedded userId.
6651     * @param userId The userId in which the uri is to be resolved.
6652     */
6653    @Override
6654    public int checkUriPermission(Uri uri, int pid, int uid,
6655            final int modeFlags, int userId) {
6656        enforceNotIsolatedCaller("checkUriPermission");
6657
6658        // Another redirected-binder-call permissions check as in
6659        // {@link checkComponentPermission}.
6660        Identity tlsIdentity = sCallerIdentity.get();
6661        if (tlsIdentity != null) {
6662            uid = tlsIdentity.uid;
6663            pid = tlsIdentity.pid;
6664        }
6665
6666        // Our own process gets to do everything.
6667        if (pid == MY_PID) {
6668            return PackageManager.PERMISSION_GRANTED;
6669        }
6670        synchronized (this) {
6671            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6672                    ? PackageManager.PERMISSION_GRANTED
6673                    : PackageManager.PERMISSION_DENIED;
6674        }
6675    }
6676
6677    /**
6678     * Check if the targetPkg can be granted permission to access uri by
6679     * the callingUid using the given modeFlags.  Throws a security exception
6680     * if callingUid is not allowed to do this.  Returns the uid of the target
6681     * if the URI permission grant should be performed; returns -1 if it is not
6682     * needed (for example targetPkg already has permission to access the URI).
6683     * If you already know the uid of the target, you can supply it in
6684     * lastTargetUid else set that to -1.
6685     */
6686    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6687            final int modeFlags, int lastTargetUid) {
6688        if (!Intent.isAccessUriMode(modeFlags)) {
6689            return -1;
6690        }
6691
6692        if (targetPkg != null) {
6693            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6694                    "Checking grant " + targetPkg + " permission to " + grantUri);
6695        }
6696
6697        final IPackageManager pm = AppGlobals.getPackageManager();
6698
6699        // If this is not a content: uri, we can't do anything with it.
6700        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6701            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6702                    "Can't grant URI permission for non-content URI: " + grantUri);
6703            return -1;
6704        }
6705
6706        final String authority = grantUri.uri.getAuthority();
6707        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6708        if (pi == null) {
6709            Slog.w(TAG, "No content provider found for permission check: " +
6710                    grantUri.uri.toSafeString());
6711            return -1;
6712        }
6713
6714        int targetUid = lastTargetUid;
6715        if (targetUid < 0 && targetPkg != null) {
6716            try {
6717                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6718                if (targetUid < 0) {
6719                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6720                            "Can't grant URI permission no uid for: " + targetPkg);
6721                    return -1;
6722                }
6723            } catch (RemoteException ex) {
6724                return -1;
6725            }
6726        }
6727
6728        if (targetUid >= 0) {
6729            // First...  does the target actually need this permission?
6730            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6731                // No need to grant the target this permission.
6732                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6733                        "Target " + targetPkg + " already has full permission to " + grantUri);
6734                return -1;
6735            }
6736        } else {
6737            // First...  there is no target package, so can anyone access it?
6738            boolean allowed = pi.exported;
6739            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6740                if (pi.readPermission != null) {
6741                    allowed = false;
6742                }
6743            }
6744            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6745                if (pi.writePermission != null) {
6746                    allowed = false;
6747                }
6748            }
6749            if (allowed) {
6750                return -1;
6751            }
6752        }
6753
6754        /* There is a special cross user grant if:
6755         * - The target is on another user.
6756         * - Apps on the current user can access the uri without any uid permissions.
6757         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6758         * grant uri permissions.
6759         */
6760        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6761                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6762                modeFlags, false /*without considering the uid permissions*/);
6763
6764        // Second...  is the provider allowing granting of URI permissions?
6765        if (!specialCrossUserGrant) {
6766            if (!pi.grantUriPermissions) {
6767                throw new SecurityException("Provider " + pi.packageName
6768                        + "/" + pi.name
6769                        + " does not allow granting of Uri permissions (uri "
6770                        + grantUri + ")");
6771            }
6772            if (pi.uriPermissionPatterns != null) {
6773                final int N = pi.uriPermissionPatterns.length;
6774                boolean allowed = false;
6775                for (int i=0; i<N; i++) {
6776                    if (pi.uriPermissionPatterns[i] != null
6777                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6778                        allowed = true;
6779                        break;
6780                    }
6781                }
6782                if (!allowed) {
6783                    throw new SecurityException("Provider " + pi.packageName
6784                            + "/" + pi.name
6785                            + " does not allow granting of permission to path of Uri "
6786                            + grantUri);
6787                }
6788            }
6789        }
6790
6791        // Third...  does the caller itself have permission to access
6792        // this uri?
6793        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6794            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6795                // Require they hold a strong enough Uri permission
6796                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6797                    throw new SecurityException("Uid " + callingUid
6798                            + " does not have permission to uri " + grantUri);
6799                }
6800            }
6801        }
6802        return targetUid;
6803    }
6804
6805    /**
6806     * @param uri This uri must NOT contain an embedded userId.
6807     * @param userId The userId in which the uri is to be resolved.
6808     */
6809    @Override
6810    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6811            final int modeFlags, int userId) {
6812        enforceNotIsolatedCaller("checkGrantUriPermission");
6813        synchronized(this) {
6814            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6815                    new GrantUri(userId, uri, false), modeFlags, -1);
6816        }
6817    }
6818
6819    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6820            final int modeFlags, UriPermissionOwner owner) {
6821        if (!Intent.isAccessUriMode(modeFlags)) {
6822            return;
6823        }
6824
6825        // So here we are: the caller has the assumed permission
6826        // to the uri, and the target doesn't.  Let's now give this to
6827        // the target.
6828
6829        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6830                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6831
6832        final String authority = grantUri.uri.getAuthority();
6833        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6834        if (pi == null) {
6835            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6836            return;
6837        }
6838
6839        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6840            grantUri.prefix = true;
6841        }
6842        final UriPermission perm = findOrCreateUriPermissionLocked(
6843                pi.packageName, targetPkg, targetUid, grantUri);
6844        perm.grantModes(modeFlags, owner);
6845    }
6846
6847    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6848            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6849        if (targetPkg == null) {
6850            throw new NullPointerException("targetPkg");
6851        }
6852        int targetUid;
6853        final IPackageManager pm = AppGlobals.getPackageManager();
6854        try {
6855            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6856        } catch (RemoteException ex) {
6857            return;
6858        }
6859
6860        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6861                targetUid);
6862        if (targetUid < 0) {
6863            return;
6864        }
6865
6866        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6867                owner);
6868    }
6869
6870    static class NeededUriGrants extends ArrayList<GrantUri> {
6871        final String targetPkg;
6872        final int targetUid;
6873        final int flags;
6874
6875        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6876            this.targetPkg = targetPkg;
6877            this.targetUid = targetUid;
6878            this.flags = flags;
6879        }
6880    }
6881
6882    /**
6883     * Like checkGrantUriPermissionLocked, but takes an Intent.
6884     */
6885    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6886            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6887        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6888                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6889                + " clip=" + (intent != null ? intent.getClipData() : null)
6890                + " from " + intent + "; flags=0x"
6891                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6892
6893        if (targetPkg == null) {
6894            throw new NullPointerException("targetPkg");
6895        }
6896
6897        if (intent == null) {
6898            return null;
6899        }
6900        Uri data = intent.getData();
6901        ClipData clip = intent.getClipData();
6902        if (data == null && clip == null) {
6903            return null;
6904        }
6905        // Default userId for uris in the intent (if they don't specify it themselves)
6906        int contentUserHint = intent.getContentUserHint();
6907        if (contentUserHint == UserHandle.USER_CURRENT) {
6908            contentUserHint = UserHandle.getUserId(callingUid);
6909        }
6910        final IPackageManager pm = AppGlobals.getPackageManager();
6911        int targetUid;
6912        if (needed != null) {
6913            targetUid = needed.targetUid;
6914        } else {
6915            try {
6916                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6917            } catch (RemoteException ex) {
6918                return null;
6919            }
6920            if (targetUid < 0) {
6921                if (DEBUG_URI_PERMISSION) {
6922                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6923                            + " on user " + targetUserId);
6924                }
6925                return null;
6926            }
6927        }
6928        if (data != null) {
6929            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6930            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6931                    targetUid);
6932            if (targetUid > 0) {
6933                if (needed == null) {
6934                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6935                }
6936                needed.add(grantUri);
6937            }
6938        }
6939        if (clip != null) {
6940            for (int i=0; i<clip.getItemCount(); i++) {
6941                Uri uri = clip.getItemAt(i).getUri();
6942                if (uri != null) {
6943                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6944                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6945                            targetUid);
6946                    if (targetUid > 0) {
6947                        if (needed == null) {
6948                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6949                        }
6950                        needed.add(grantUri);
6951                    }
6952                } else {
6953                    Intent clipIntent = clip.getItemAt(i).getIntent();
6954                    if (clipIntent != null) {
6955                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6956                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6957                        if (newNeeded != null) {
6958                            needed = newNeeded;
6959                        }
6960                    }
6961                }
6962            }
6963        }
6964
6965        return needed;
6966    }
6967
6968    /**
6969     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6970     */
6971    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6972            UriPermissionOwner owner) {
6973        if (needed != null) {
6974            for (int i=0; i<needed.size(); i++) {
6975                GrantUri grantUri = needed.get(i);
6976                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6977                        grantUri, needed.flags, owner);
6978            }
6979        }
6980    }
6981
6982    void grantUriPermissionFromIntentLocked(int callingUid,
6983            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6984        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6985                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6986        if (needed == null) {
6987            return;
6988        }
6989
6990        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6991    }
6992
6993    /**
6994     * @param uri This uri must NOT contain an embedded userId.
6995     * @param userId The userId in which the uri is to be resolved.
6996     */
6997    @Override
6998    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6999            final int modeFlags, int userId) {
7000        enforceNotIsolatedCaller("grantUriPermission");
7001        GrantUri grantUri = new GrantUri(userId, uri, false);
7002        synchronized(this) {
7003            final ProcessRecord r = getRecordForAppLocked(caller);
7004            if (r == null) {
7005                throw new SecurityException("Unable to find app for caller "
7006                        + caller
7007                        + " when granting permission to uri " + grantUri);
7008            }
7009            if (targetPkg == null) {
7010                throw new IllegalArgumentException("null target");
7011            }
7012            if (grantUri == null) {
7013                throw new IllegalArgumentException("null uri");
7014            }
7015
7016            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7017                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7018                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7019                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7020
7021            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7022                    UserHandle.getUserId(r.uid));
7023        }
7024    }
7025
7026    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7027        if (perm.modeFlags == 0) {
7028            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7029                    perm.targetUid);
7030            if (perms != null) {
7031                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7032                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7033
7034                perms.remove(perm.uri);
7035                if (perms.isEmpty()) {
7036                    mGrantedUriPermissions.remove(perm.targetUid);
7037                }
7038            }
7039        }
7040    }
7041
7042    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7043        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7044
7045        final IPackageManager pm = AppGlobals.getPackageManager();
7046        final String authority = grantUri.uri.getAuthority();
7047        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7048        if (pi == null) {
7049            Slog.w(TAG, "No content provider found for permission revoke: "
7050                    + grantUri.toSafeString());
7051            return;
7052        }
7053
7054        // Does the caller have this permission on the URI?
7055        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7056            // Right now, if you are not the original owner of the permission,
7057            // you are not allowed to revoke it.
7058            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7059                throw new SecurityException("Uid " + callingUid
7060                        + " does not have permission to uri " + grantUri);
7061            //}
7062        }
7063
7064        boolean persistChanged = false;
7065
7066        // Go through all of the permissions and remove any that match.
7067        int N = mGrantedUriPermissions.size();
7068        for (int i = 0; i < N; i++) {
7069            final int targetUid = mGrantedUriPermissions.keyAt(i);
7070            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7071
7072            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7073                final UriPermission perm = it.next();
7074                if (perm.uri.sourceUserId == grantUri.sourceUserId
7075                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7076                    if (DEBUG_URI_PERMISSION)
7077                        Slog.v(TAG,
7078                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7079                    persistChanged |= perm.revokeModes(
7080                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7081                    if (perm.modeFlags == 0) {
7082                        it.remove();
7083                    }
7084                }
7085            }
7086
7087            if (perms.isEmpty()) {
7088                mGrantedUriPermissions.remove(targetUid);
7089                N--;
7090                i--;
7091            }
7092        }
7093
7094        if (persistChanged) {
7095            schedulePersistUriGrants();
7096        }
7097    }
7098
7099    /**
7100     * @param uri This uri must NOT contain an embedded userId.
7101     * @param userId The userId in which the uri is to be resolved.
7102     */
7103    @Override
7104    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7105            int userId) {
7106        enforceNotIsolatedCaller("revokeUriPermission");
7107        synchronized(this) {
7108            final ProcessRecord r = getRecordForAppLocked(caller);
7109            if (r == null) {
7110                throw new SecurityException("Unable to find app for caller "
7111                        + caller
7112                        + " when revoking permission to uri " + uri);
7113            }
7114            if (uri == null) {
7115                Slog.w(TAG, "revokeUriPermission: null uri");
7116                return;
7117            }
7118
7119            if (!Intent.isAccessUriMode(modeFlags)) {
7120                return;
7121            }
7122
7123            final IPackageManager pm = AppGlobals.getPackageManager();
7124            final String authority = uri.getAuthority();
7125            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7126            if (pi == null) {
7127                Slog.w(TAG, "No content provider found for permission revoke: "
7128                        + uri.toSafeString());
7129                return;
7130            }
7131
7132            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7133        }
7134    }
7135
7136    /**
7137     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7138     * given package.
7139     *
7140     * @param packageName Package name to match, or {@code null} to apply to all
7141     *            packages.
7142     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7143     *            to all users.
7144     * @param persistable If persistable grants should be removed.
7145     */
7146    private void removeUriPermissionsForPackageLocked(
7147            String packageName, int userHandle, boolean persistable) {
7148        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7149            throw new IllegalArgumentException("Must narrow by either package or user");
7150        }
7151
7152        boolean persistChanged = false;
7153
7154        int N = mGrantedUriPermissions.size();
7155        for (int i = 0; i < N; i++) {
7156            final int targetUid = mGrantedUriPermissions.keyAt(i);
7157            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7158
7159            // Only inspect grants matching user
7160            if (userHandle == UserHandle.USER_ALL
7161                    || userHandle == UserHandle.getUserId(targetUid)) {
7162                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7163                    final UriPermission perm = it.next();
7164
7165                    // Only inspect grants matching package
7166                    if (packageName == null || perm.sourcePkg.equals(packageName)
7167                            || perm.targetPkg.equals(packageName)) {
7168                        persistChanged |= perm.revokeModes(
7169                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7170
7171                        // Only remove when no modes remain; any persisted grants
7172                        // will keep this alive.
7173                        if (perm.modeFlags == 0) {
7174                            it.remove();
7175                        }
7176                    }
7177                }
7178
7179                if (perms.isEmpty()) {
7180                    mGrantedUriPermissions.remove(targetUid);
7181                    N--;
7182                    i--;
7183                }
7184            }
7185        }
7186
7187        if (persistChanged) {
7188            schedulePersistUriGrants();
7189        }
7190    }
7191
7192    @Override
7193    public IBinder newUriPermissionOwner(String name) {
7194        enforceNotIsolatedCaller("newUriPermissionOwner");
7195        synchronized(this) {
7196            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7197            return owner.getExternalTokenLocked();
7198        }
7199    }
7200
7201    /**
7202     * @param uri This uri must NOT contain an embedded userId.
7203     * @param sourceUserId The userId in which the uri is to be resolved.
7204     * @param targetUserId The userId of the app that receives the grant.
7205     */
7206    @Override
7207    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7208            final int modeFlags, int sourceUserId, int targetUserId) {
7209        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7210                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7211        synchronized(this) {
7212            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7213            if (owner == null) {
7214                throw new IllegalArgumentException("Unknown owner: " + token);
7215            }
7216            if (fromUid != Binder.getCallingUid()) {
7217                if (Binder.getCallingUid() != Process.myUid()) {
7218                    // Only system code can grant URI permissions on behalf
7219                    // of other users.
7220                    throw new SecurityException("nice try");
7221                }
7222            }
7223            if (targetPkg == null) {
7224                throw new IllegalArgumentException("null target");
7225            }
7226            if (uri == null) {
7227                throw new IllegalArgumentException("null uri");
7228            }
7229
7230            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7231                    modeFlags, owner, targetUserId);
7232        }
7233    }
7234
7235    /**
7236     * @param uri This uri must NOT contain an embedded userId.
7237     * @param userId The userId in which the uri is to be resolved.
7238     */
7239    @Override
7240    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7241        synchronized(this) {
7242            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7243            if (owner == null) {
7244                throw new IllegalArgumentException("Unknown owner: " + token);
7245            }
7246
7247            if (uri == null) {
7248                owner.removeUriPermissionsLocked(mode);
7249            } else {
7250                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7251            }
7252        }
7253    }
7254
7255    private void schedulePersistUriGrants() {
7256        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7257            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7258                    10 * DateUtils.SECOND_IN_MILLIS);
7259        }
7260    }
7261
7262    private void writeGrantedUriPermissions() {
7263        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7264
7265        // Snapshot permissions so we can persist without lock
7266        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7267        synchronized (this) {
7268            final int size = mGrantedUriPermissions.size();
7269            for (int i = 0; i < size; i++) {
7270                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7271                for (UriPermission perm : perms.values()) {
7272                    if (perm.persistedModeFlags != 0) {
7273                        persist.add(perm.snapshot());
7274                    }
7275                }
7276            }
7277        }
7278
7279        FileOutputStream fos = null;
7280        try {
7281            fos = mGrantFile.startWrite();
7282
7283            XmlSerializer out = new FastXmlSerializer();
7284            out.setOutput(fos, "utf-8");
7285            out.startDocument(null, true);
7286            out.startTag(null, TAG_URI_GRANTS);
7287            for (UriPermission.Snapshot perm : persist) {
7288                out.startTag(null, TAG_URI_GRANT);
7289                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7290                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7291                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7292                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7293                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7294                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7295                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7296                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7297                out.endTag(null, TAG_URI_GRANT);
7298            }
7299            out.endTag(null, TAG_URI_GRANTS);
7300            out.endDocument();
7301
7302            mGrantFile.finishWrite(fos);
7303        } catch (IOException e) {
7304            if (fos != null) {
7305                mGrantFile.failWrite(fos);
7306            }
7307        }
7308    }
7309
7310    private void readGrantedUriPermissionsLocked() {
7311        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7312
7313        final long now = System.currentTimeMillis();
7314
7315        FileInputStream fis = null;
7316        try {
7317            fis = mGrantFile.openRead();
7318            final XmlPullParser in = Xml.newPullParser();
7319            in.setInput(fis, null);
7320
7321            int type;
7322            while ((type = in.next()) != END_DOCUMENT) {
7323                final String tag = in.getName();
7324                if (type == START_TAG) {
7325                    if (TAG_URI_GRANT.equals(tag)) {
7326                        final int sourceUserId;
7327                        final int targetUserId;
7328                        final int userHandle = readIntAttribute(in,
7329                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7330                        if (userHandle != UserHandle.USER_NULL) {
7331                            // For backwards compatibility.
7332                            sourceUserId = userHandle;
7333                            targetUserId = userHandle;
7334                        } else {
7335                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7336                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7337                        }
7338                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7339                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7340                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7341                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7342                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7343                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7344
7345                        // Sanity check that provider still belongs to source package
7346                        final ProviderInfo pi = getProviderInfoLocked(
7347                                uri.getAuthority(), sourceUserId);
7348                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7349                            int targetUid = -1;
7350                            try {
7351                                targetUid = AppGlobals.getPackageManager()
7352                                        .getPackageUid(targetPkg, targetUserId);
7353                            } catch (RemoteException e) {
7354                            }
7355                            if (targetUid != -1) {
7356                                final UriPermission perm = findOrCreateUriPermissionLocked(
7357                                        sourcePkg, targetPkg, targetUid,
7358                                        new GrantUri(sourceUserId, uri, prefix));
7359                                perm.initPersistedModes(modeFlags, createdTime);
7360                            }
7361                        } else {
7362                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7363                                    + " but instead found " + pi);
7364                        }
7365                    }
7366                }
7367            }
7368        } catch (FileNotFoundException e) {
7369            // Missing grants is okay
7370        } catch (IOException e) {
7371            Log.wtf(TAG, "Failed reading Uri grants", e);
7372        } catch (XmlPullParserException e) {
7373            Log.wtf(TAG, "Failed reading Uri grants", e);
7374        } finally {
7375            IoUtils.closeQuietly(fis);
7376        }
7377    }
7378
7379    /**
7380     * @param uri This uri must NOT contain an embedded userId.
7381     * @param userId The userId in which the uri is to be resolved.
7382     */
7383    @Override
7384    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7385        enforceNotIsolatedCaller("takePersistableUriPermission");
7386
7387        Preconditions.checkFlagsArgument(modeFlags,
7388                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7389
7390        synchronized (this) {
7391            final int callingUid = Binder.getCallingUid();
7392            boolean persistChanged = false;
7393            GrantUri grantUri = new GrantUri(userId, uri, false);
7394
7395            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7396                    new GrantUri(userId, uri, false));
7397            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7398                    new GrantUri(userId, uri, true));
7399
7400            final boolean exactValid = (exactPerm != null)
7401                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7402            final boolean prefixValid = (prefixPerm != null)
7403                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7404
7405            if (!(exactValid || prefixValid)) {
7406                throw new SecurityException("No persistable permission grants found for UID "
7407                        + callingUid + " and Uri " + grantUri.toSafeString());
7408            }
7409
7410            if (exactValid) {
7411                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7412            }
7413            if (prefixValid) {
7414                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7415            }
7416
7417            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7418
7419            if (persistChanged) {
7420                schedulePersistUriGrants();
7421            }
7422        }
7423    }
7424
7425    /**
7426     * @param uri This uri must NOT contain an embedded userId.
7427     * @param userId The userId in which the uri is to be resolved.
7428     */
7429    @Override
7430    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7431        enforceNotIsolatedCaller("releasePersistableUriPermission");
7432
7433        Preconditions.checkFlagsArgument(modeFlags,
7434                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7435
7436        synchronized (this) {
7437            final int callingUid = Binder.getCallingUid();
7438            boolean persistChanged = false;
7439
7440            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7441                    new GrantUri(userId, uri, false));
7442            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7443                    new GrantUri(userId, uri, true));
7444            if (exactPerm == null && prefixPerm == null) {
7445                throw new SecurityException("No permission grants found for UID " + callingUid
7446                        + " and Uri " + uri.toSafeString());
7447            }
7448
7449            if (exactPerm != null) {
7450                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7451                removeUriPermissionIfNeededLocked(exactPerm);
7452            }
7453            if (prefixPerm != null) {
7454                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7455                removeUriPermissionIfNeededLocked(prefixPerm);
7456            }
7457
7458            if (persistChanged) {
7459                schedulePersistUriGrants();
7460            }
7461        }
7462    }
7463
7464    /**
7465     * Prune any older {@link UriPermission} for the given UID until outstanding
7466     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7467     *
7468     * @return if any mutations occured that require persisting.
7469     */
7470    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7471        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7472        if (perms == null) return false;
7473        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7474
7475        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7476        for (UriPermission perm : perms.values()) {
7477            if (perm.persistedModeFlags != 0) {
7478                persisted.add(perm);
7479            }
7480        }
7481
7482        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7483        if (trimCount <= 0) return false;
7484
7485        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7486        for (int i = 0; i < trimCount; i++) {
7487            final UriPermission perm = persisted.get(i);
7488
7489            if (DEBUG_URI_PERMISSION) {
7490                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7491            }
7492
7493            perm.releasePersistableModes(~0);
7494            removeUriPermissionIfNeededLocked(perm);
7495        }
7496
7497        return true;
7498    }
7499
7500    @Override
7501    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7502            String packageName, boolean incoming) {
7503        enforceNotIsolatedCaller("getPersistedUriPermissions");
7504        Preconditions.checkNotNull(packageName, "packageName");
7505
7506        final int callingUid = Binder.getCallingUid();
7507        final IPackageManager pm = AppGlobals.getPackageManager();
7508        try {
7509            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7510            if (packageUid != callingUid) {
7511                throw new SecurityException(
7512                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7513            }
7514        } catch (RemoteException e) {
7515            throw new SecurityException("Failed to verify package name ownership");
7516        }
7517
7518        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7519        synchronized (this) {
7520            if (incoming) {
7521                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7522                        callingUid);
7523                if (perms == null) {
7524                    Slog.w(TAG, "No permission grants found for " + packageName);
7525                } else {
7526                    for (UriPermission perm : perms.values()) {
7527                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7528                            result.add(perm.buildPersistedPublicApiObject());
7529                        }
7530                    }
7531                }
7532            } else {
7533                final int size = mGrantedUriPermissions.size();
7534                for (int i = 0; i < size; i++) {
7535                    final ArrayMap<GrantUri, UriPermission> perms =
7536                            mGrantedUriPermissions.valueAt(i);
7537                    for (UriPermission perm : perms.values()) {
7538                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7539                            result.add(perm.buildPersistedPublicApiObject());
7540                        }
7541                    }
7542                }
7543            }
7544        }
7545        return new ParceledListSlice<android.content.UriPermission>(result);
7546    }
7547
7548    @Override
7549    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7550        synchronized (this) {
7551            ProcessRecord app =
7552                who != null ? getRecordForAppLocked(who) : null;
7553            if (app == null) return;
7554
7555            Message msg = Message.obtain();
7556            msg.what = WAIT_FOR_DEBUGGER_MSG;
7557            msg.obj = app;
7558            msg.arg1 = waiting ? 1 : 0;
7559            mHandler.sendMessage(msg);
7560        }
7561    }
7562
7563    @Override
7564    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7565        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7566        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7567        outInfo.availMem = Process.getFreeMemory();
7568        outInfo.totalMem = Process.getTotalMemory();
7569        outInfo.threshold = homeAppMem;
7570        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7571        outInfo.hiddenAppThreshold = cachedAppMem;
7572        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7573                ProcessList.SERVICE_ADJ);
7574        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7575                ProcessList.VISIBLE_APP_ADJ);
7576        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7577                ProcessList.FOREGROUND_APP_ADJ);
7578    }
7579
7580    // =========================================================
7581    // TASK MANAGEMENT
7582    // =========================================================
7583
7584    @Override
7585    public List<IAppTask> getAppTasks(String callingPackage) {
7586        int callingUid = Binder.getCallingUid();
7587        long ident = Binder.clearCallingIdentity();
7588
7589        synchronized(this) {
7590            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7591            try {
7592                if (localLOGV) Slog.v(TAG, "getAppTasks");
7593
7594                final int N = mRecentTasks.size();
7595                for (int i = 0; i < N; i++) {
7596                    TaskRecord tr = mRecentTasks.get(i);
7597                    // Skip tasks that do not match the caller.  We don't need to verify
7598                    // callingPackage, because we are also limiting to callingUid and know
7599                    // that will limit to the correct security sandbox.
7600                    if (tr.effectiveUid != callingUid) {
7601                        continue;
7602                    }
7603                    Intent intent = tr.getBaseIntent();
7604                    if (intent == null ||
7605                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7606                        continue;
7607                    }
7608                    ActivityManager.RecentTaskInfo taskInfo =
7609                            createRecentTaskInfoFromTaskRecord(tr);
7610                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7611                    list.add(taskImpl);
7612                }
7613            } finally {
7614                Binder.restoreCallingIdentity(ident);
7615            }
7616            return list;
7617        }
7618    }
7619
7620    @Override
7621    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7622        final int callingUid = Binder.getCallingUid();
7623        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7624
7625        synchronized(this) {
7626            if (localLOGV) Slog.v(
7627                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7628
7629            final boolean allowed = checkCallingPermission(
7630                    android.Manifest.permission.GET_TASKS)
7631                    == PackageManager.PERMISSION_GRANTED;
7632            if (!allowed) {
7633                Slog.w(TAG, "getTasks: caller " + callingUid
7634                        + " does not hold GET_TASKS; limiting output");
7635            }
7636
7637            // TODO: Improve with MRU list from all ActivityStacks.
7638            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7639        }
7640
7641        return list;
7642    }
7643
7644    TaskRecord getMostRecentTask() {
7645        return mRecentTasks.get(0);
7646    }
7647
7648    /**
7649     * Creates a new RecentTaskInfo from a TaskRecord.
7650     */
7651    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7652        // Update the task description to reflect any changes in the task stack
7653        tr.updateTaskDescription();
7654
7655        // Compose the recent task info
7656        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7657        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7658        rti.persistentId = tr.taskId;
7659        rti.baseIntent = new Intent(tr.getBaseIntent());
7660        rti.origActivity = tr.origActivity;
7661        rti.description = tr.lastDescription;
7662        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7663        rti.userId = tr.userId;
7664        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7665        rti.firstActiveTime = tr.firstActiveTime;
7666        rti.lastActiveTime = tr.lastActiveTime;
7667        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7668        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7669        return rti;
7670    }
7671
7672    @Override
7673    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7674        final int callingUid = Binder.getCallingUid();
7675        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7676                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7677
7678        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7679        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7680        synchronized (this) {
7681            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7682                    == PackageManager.PERMISSION_GRANTED;
7683            if (!allowed) {
7684                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7685                        + " does not hold GET_TASKS; limiting output");
7686            }
7687            final boolean detailed = checkCallingPermission(
7688                    android.Manifest.permission.GET_DETAILED_TASKS)
7689                    == PackageManager.PERMISSION_GRANTED;
7690
7691            IPackageManager pm = AppGlobals.getPackageManager();
7692
7693            final int N = mRecentTasks.size();
7694            ArrayList<ActivityManager.RecentTaskInfo> res
7695                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7696                            maxNum < N ? maxNum : N);
7697
7698            final Set<Integer> includedUsers;
7699            if (includeProfiles) {
7700                includedUsers = getProfileIdsLocked(userId);
7701            } else {
7702                includedUsers = new HashSet<Integer>();
7703            }
7704            includedUsers.add(Integer.valueOf(userId));
7705
7706            // Regroup affiliated tasks together.
7707            for (int i = 0; i < N; ) {
7708                TaskRecord task = mRecentTasks.remove(i);
7709                if (mTmpRecents.contains(task)) {
7710                    continue;
7711                }
7712                int affiliatedTaskId = task.mAffiliatedTaskId;
7713                while (true) {
7714                    TaskRecord next = task.mNextAffiliate;
7715                    if (next == null) {
7716                        break;
7717                    }
7718                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7719                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7720                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7721                        task.setNextAffiliate(null);
7722                        if (next.mPrevAffiliate == task) {
7723                            next.setPrevAffiliate(null);
7724                        }
7725                        break;
7726                    }
7727                    if (next.mPrevAffiliate != task) {
7728                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7729                                next.mPrevAffiliate + " task=" + task);
7730                        next.setPrevAffiliate(null);
7731                        break;
7732                    }
7733                    if (!mRecentTasks.contains(next)) {
7734                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7735                        task.setNextAffiliate(null);
7736                        if (next.mPrevAffiliate == task) {
7737                            next.setPrevAffiliate(null);
7738                        }
7739                        break;
7740                    }
7741                    task = next;
7742                }
7743                // task is now the end of the list
7744                do {
7745                    mRecentTasks.remove(task);
7746                    mRecentTasks.add(i++, task);
7747                    mTmpRecents.add(task);
7748                } while ((task = task.mPrevAffiliate) != null);
7749            }
7750            mTmpRecents.clear();
7751            // mRecentTasks is now in sorted, affiliated order.
7752
7753            for (int i=0; i<N && maxNum > 0; i++) {
7754                TaskRecord tr = mRecentTasks.get(i);
7755                // Only add calling user or related users recent tasks
7756                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7757                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7758                    continue;
7759                }
7760
7761                // Return the entry if desired by the caller.  We always return
7762                // the first entry, because callers always expect this to be the
7763                // foreground app.  We may filter others if the caller has
7764                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7765                // we should exclude the entry.
7766
7767                if (i == 0
7768                        || withExcluded
7769                        || (tr.intent == null)
7770                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7771                                == 0)) {
7772                    if (!allowed) {
7773                        // If the caller doesn't have the GET_TASKS permission, then only
7774                        // allow them to see a small subset of tasks -- their own and home.
7775                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7776                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7777                            continue;
7778                        }
7779                    }
7780                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7781                        if (tr.stack != null && tr.stack.isHomeStack()) {
7782                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7783                            continue;
7784                        }
7785                    }
7786                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7787                        // Don't include auto remove tasks that are finished or finishing.
7788                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7789                                + tr);
7790                        continue;
7791                    }
7792
7793                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7794                    if (!detailed) {
7795                        rti.baseIntent.replaceExtras((Bundle)null);
7796                    }
7797
7798                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7799                        // Check whether this activity is currently available.
7800                        try {
7801                            if (rti.origActivity != null) {
7802                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7803                                        == null) {
7804                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: "
7805                                            + tr);
7806                                    continue;
7807                                }
7808                            } else if (rti.baseIntent != null) {
7809                                if (pm.queryIntentActivities(rti.baseIntent,
7810                                        null, 0, userId) == null) {
7811                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: "
7812                                            + tr);
7813                                    continue;
7814                                }
7815                            }
7816                        } catch (RemoteException e) {
7817                            // Will never happen.
7818                        }
7819                    }
7820
7821                    res.add(rti);
7822                    maxNum--;
7823                }
7824            }
7825            return res;
7826        }
7827    }
7828
7829    private TaskRecord recentTaskForIdLocked(int id) {
7830        final int N = mRecentTasks.size();
7831            for (int i=0; i<N; i++) {
7832                TaskRecord tr = mRecentTasks.get(i);
7833                if (tr.taskId == id) {
7834                    return tr;
7835                }
7836            }
7837            return null;
7838    }
7839
7840    @Override
7841    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7842        synchronized (this) {
7843            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7844                    "getTaskThumbnail()");
7845            TaskRecord tr = recentTaskForIdLocked(id);
7846            if (tr != null) {
7847                return tr.getTaskThumbnailLocked();
7848            }
7849        }
7850        return null;
7851    }
7852
7853    @Override
7854    public int addAppTask(IBinder activityToken, Intent intent,
7855            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7856        final int callingUid = Binder.getCallingUid();
7857        final long callingIdent = Binder.clearCallingIdentity();
7858
7859        try {
7860            synchronized (this) {
7861                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7862                if (r == null) {
7863                    throw new IllegalArgumentException("Activity does not exist; token="
7864                            + activityToken);
7865                }
7866                ComponentName comp = intent.getComponent();
7867                if (comp == null) {
7868                    throw new IllegalArgumentException("Intent " + intent
7869                            + " must specify explicit component");
7870                }
7871                if (thumbnail.getWidth() != mThumbnailWidth
7872                        || thumbnail.getHeight() != mThumbnailHeight) {
7873                    throw new IllegalArgumentException("Bad thumbnail size: got "
7874                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7875                            + mThumbnailWidth + "x" + mThumbnailHeight);
7876                }
7877                if (intent.getSelector() != null) {
7878                    intent.setSelector(null);
7879                }
7880                if (intent.getSourceBounds() != null) {
7881                    intent.setSourceBounds(null);
7882                }
7883                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7884                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7885                        // The caller has added this as an auto-remove task...  that makes no
7886                        // sense, so turn off auto-remove.
7887                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7888                    }
7889                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7890                    // Must be a new task.
7891                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7892                }
7893                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7894                    mLastAddedTaskActivity = null;
7895                }
7896                ActivityInfo ainfo = mLastAddedTaskActivity;
7897                if (ainfo == null) {
7898                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7899                            comp, 0, UserHandle.getUserId(callingUid));
7900                    if (ainfo.applicationInfo.uid != callingUid) {
7901                        throw new SecurityException(
7902                                "Can't add task for another application: target uid="
7903                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7904                    }
7905                }
7906
7907                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7908                        intent, description);
7909
7910                int trimIdx = trimRecentsForTask(task, false);
7911                if (trimIdx >= 0) {
7912                    // If this would have caused a trim, then we'll abort because that
7913                    // means it would be added at the end of the list but then just removed.
7914                    return -1;
7915                }
7916
7917                final int N = mRecentTasks.size();
7918                if (N >= (MAX_RECENT_TASKS-1)) {
7919                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7920                    tr.disposeThumbnail();
7921                    tr.closeRecentsChain();
7922                }
7923
7924                mRecentTasks.add(task);
7925                r.task.stack.addTask(task, false, false);
7926
7927                task.setLastThumbnail(thumbnail);
7928                task.freeLastThumbnail();
7929
7930                return task.taskId;
7931            }
7932        } finally {
7933            Binder.restoreCallingIdentity(callingIdent);
7934        }
7935    }
7936
7937    @Override
7938    public Point getAppTaskThumbnailSize() {
7939        synchronized (this) {
7940            return new Point(mThumbnailWidth,  mThumbnailHeight);
7941        }
7942    }
7943
7944    @Override
7945    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7946        synchronized (this) {
7947            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7948            if (r != null) {
7949                r.taskDescription = td;
7950                r.task.updateTaskDescription();
7951            }
7952        }
7953    }
7954
7955    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7956        tr.disposeThumbnail();
7957        mRecentTasks.remove(tr);
7958        tr.closeRecentsChain();
7959        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7960        Intent baseIntent = new Intent(
7961                tr.intent != null ? tr.intent : tr.affinityIntent);
7962        ComponentName component = baseIntent.getComponent();
7963        if (component == null) {
7964            Slog.w(TAG, "Now component for base intent of task: " + tr);
7965            return;
7966        }
7967
7968        // Find any running services associated with this app.
7969        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7970
7971        if (killProcesses) {
7972            // Find any running processes associated with this app.
7973            final String pkg = component.getPackageName();
7974            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7975            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7976            for (int i=0; i<pmap.size(); i++) {
7977                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7978                for (int j=0; j<uids.size(); j++) {
7979                    ProcessRecord proc = uids.valueAt(j);
7980                    if (proc.userId != tr.userId) {
7981                        continue;
7982                    }
7983                    if (!proc.pkgList.containsKey(pkg)) {
7984                        continue;
7985                    }
7986                    procs.add(proc);
7987                }
7988            }
7989
7990            // Kill the running processes.
7991            for (int i=0; i<procs.size(); i++) {
7992                ProcessRecord pr = procs.get(i);
7993                if (pr == mHomeProcess) {
7994                    // Don't kill the home process along with tasks from the same package.
7995                    continue;
7996                }
7997                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7998                    pr.kill("remove task", true);
7999                } else {
8000                    pr.waitingToKill = "remove task";
8001                }
8002            }
8003        }
8004    }
8005
8006    /**
8007     * Removes the task with the specified task id.
8008     *
8009     * @param taskId Identifier of the task to be removed.
8010     * @param flags Additional operational flags.  May be 0 or
8011     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8012     * @return Returns true if the given task was found and removed.
8013     */
8014    private boolean removeTaskByIdLocked(int taskId, int flags) {
8015        TaskRecord tr = recentTaskForIdLocked(taskId);
8016        if (tr != null) {
8017            tr.removeTaskActivitiesLocked();
8018            cleanUpRemovedTaskLocked(tr, flags);
8019            if (tr.isPersistable) {
8020                notifyTaskPersisterLocked(null, true);
8021            }
8022            return true;
8023        }
8024        return false;
8025    }
8026
8027    @Override
8028    public boolean removeTask(int taskId, int flags) {
8029        synchronized (this) {
8030            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8031                    "removeTask()");
8032            long ident = Binder.clearCallingIdentity();
8033            try {
8034                return removeTaskByIdLocked(taskId, flags);
8035            } finally {
8036                Binder.restoreCallingIdentity(ident);
8037            }
8038        }
8039    }
8040
8041    /**
8042     * TODO: Add mController hook
8043     */
8044    @Override
8045    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8046        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8047                "moveTaskToFront()");
8048
8049        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8050        synchronized(this) {
8051            moveTaskToFrontLocked(taskId, flags, options);
8052        }
8053    }
8054
8055    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8056        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8057                Binder.getCallingUid(), "Task to front")) {
8058            ActivityOptions.abort(options);
8059            return;
8060        }
8061        final long origId = Binder.clearCallingIdentity();
8062        try {
8063            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8064            if (task == null) {
8065                return;
8066            }
8067            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8068                mStackSupervisor.showLockTaskToast();
8069                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8070                return;
8071            }
8072            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8073            if (prev != null && prev.isRecentsActivity()) {
8074                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8075            }
8076            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8077        } finally {
8078            Binder.restoreCallingIdentity(origId);
8079        }
8080        ActivityOptions.abort(options);
8081    }
8082
8083    @Override
8084    public void moveTaskToBack(int taskId) {
8085        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8086                "moveTaskToBack()");
8087
8088        synchronized(this) {
8089            TaskRecord tr = recentTaskForIdLocked(taskId);
8090            if (tr != null) {
8091                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8092                ActivityStack stack = tr.stack;
8093                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8094                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8095                            Binder.getCallingUid(), "Task to back")) {
8096                        return;
8097                    }
8098                }
8099                final long origId = Binder.clearCallingIdentity();
8100                try {
8101                    stack.moveTaskToBackLocked(taskId, null);
8102                } finally {
8103                    Binder.restoreCallingIdentity(origId);
8104                }
8105            }
8106        }
8107    }
8108
8109    /**
8110     * Moves an activity, and all of the other activities within the same task, to the bottom
8111     * of the history stack.  The activity's order within the task is unchanged.
8112     *
8113     * @param token A reference to the activity we wish to move
8114     * @param nonRoot If false then this only works if the activity is the root
8115     *                of a task; if true it will work for any activity in a task.
8116     * @return Returns true if the move completed, false if not.
8117     */
8118    @Override
8119    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8120        enforceNotIsolatedCaller("moveActivityTaskToBack");
8121        synchronized(this) {
8122            final long origId = Binder.clearCallingIdentity();
8123            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8124            if (taskId >= 0) {
8125                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8126            }
8127            Binder.restoreCallingIdentity(origId);
8128        }
8129        return false;
8130    }
8131
8132    @Override
8133    public void moveTaskBackwards(int task) {
8134        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8135                "moveTaskBackwards()");
8136
8137        synchronized(this) {
8138            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8139                    Binder.getCallingUid(), "Task backwards")) {
8140                return;
8141            }
8142            final long origId = Binder.clearCallingIdentity();
8143            moveTaskBackwardsLocked(task);
8144            Binder.restoreCallingIdentity(origId);
8145        }
8146    }
8147
8148    private final void moveTaskBackwardsLocked(int task) {
8149        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8150    }
8151
8152    @Override
8153    public IBinder getHomeActivityToken() throws RemoteException {
8154        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8155                "getHomeActivityToken()");
8156        synchronized (this) {
8157            return mStackSupervisor.getHomeActivityToken();
8158        }
8159    }
8160
8161    @Override
8162    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8163            IActivityContainerCallback callback) throws RemoteException {
8164        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8165                "createActivityContainer()");
8166        synchronized (this) {
8167            if (parentActivityToken == null) {
8168                throw new IllegalArgumentException("parent token must not be null");
8169            }
8170            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8171            if (r == null) {
8172                return null;
8173            }
8174            if (callback == null) {
8175                throw new IllegalArgumentException("callback must not be null");
8176            }
8177            return mStackSupervisor.createActivityContainer(r, callback);
8178        }
8179    }
8180
8181    @Override
8182    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8183        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8184                "deleteActivityContainer()");
8185        synchronized (this) {
8186            mStackSupervisor.deleteActivityContainer(container);
8187        }
8188    }
8189
8190    @Override
8191    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8192            throws RemoteException {
8193        synchronized (this) {
8194            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8195            if (stack != null) {
8196                return stack.mActivityContainer;
8197            }
8198            return null;
8199        }
8200    }
8201
8202    @Override
8203    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8204        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8205                "moveTaskToStack()");
8206        if (stackId == HOME_STACK_ID) {
8207            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8208                    new RuntimeException("here").fillInStackTrace());
8209        }
8210        synchronized (this) {
8211            long ident = Binder.clearCallingIdentity();
8212            try {
8213                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8214                        + stackId + " toTop=" + toTop);
8215                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8216            } finally {
8217                Binder.restoreCallingIdentity(ident);
8218            }
8219        }
8220    }
8221
8222    @Override
8223    public void resizeStack(int stackBoxId, Rect bounds) {
8224        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8225                "resizeStackBox()");
8226        long ident = Binder.clearCallingIdentity();
8227        try {
8228            mWindowManager.resizeStack(stackBoxId, bounds);
8229        } finally {
8230            Binder.restoreCallingIdentity(ident);
8231        }
8232    }
8233
8234    @Override
8235    public List<StackInfo> getAllStackInfos() {
8236        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8237                "getAllStackInfos()");
8238        long ident = Binder.clearCallingIdentity();
8239        try {
8240            synchronized (this) {
8241                return mStackSupervisor.getAllStackInfosLocked();
8242            }
8243        } finally {
8244            Binder.restoreCallingIdentity(ident);
8245        }
8246    }
8247
8248    @Override
8249    public StackInfo getStackInfo(int stackId) {
8250        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8251                "getStackInfo()");
8252        long ident = Binder.clearCallingIdentity();
8253        try {
8254            synchronized (this) {
8255                return mStackSupervisor.getStackInfoLocked(stackId);
8256            }
8257        } finally {
8258            Binder.restoreCallingIdentity(ident);
8259        }
8260    }
8261
8262    @Override
8263    public boolean isInHomeStack(int taskId) {
8264        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8265                "getStackInfo()");
8266        long ident = Binder.clearCallingIdentity();
8267        try {
8268            synchronized (this) {
8269                TaskRecord tr = recentTaskForIdLocked(taskId);
8270                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8271            }
8272        } finally {
8273            Binder.restoreCallingIdentity(ident);
8274        }
8275    }
8276
8277    @Override
8278    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8279        synchronized(this) {
8280            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8281        }
8282    }
8283
8284    private boolean isLockTaskAuthorized(String pkg) {
8285        final DevicePolicyManager dpm = (DevicePolicyManager)
8286                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8287        try {
8288            int uid = mContext.getPackageManager().getPackageUid(pkg,
8289                    Binder.getCallingUserHandle().getIdentifier());
8290            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8291        } catch (NameNotFoundException e) {
8292            return false;
8293        }
8294    }
8295
8296    void startLockTaskMode(TaskRecord task) {
8297        final String pkg;
8298        synchronized (this) {
8299            pkg = task.intent.getComponent().getPackageName();
8300        }
8301        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8302        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8303            final TaskRecord taskRecord = task;
8304            mHandler.post(new Runnable() {
8305                @Override
8306                public void run() {
8307                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8308                }
8309            });
8310            return;
8311        }
8312        long ident = Binder.clearCallingIdentity();
8313        try {
8314            synchronized (this) {
8315                // Since we lost lock on task, make sure it is still there.
8316                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8317                if (task != null) {
8318                    if (!isSystemInitiated
8319                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8320                        throw new IllegalArgumentException("Invalid task, not in foreground");
8321                    }
8322                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8323                }
8324            }
8325        } finally {
8326            Binder.restoreCallingIdentity(ident);
8327        }
8328    }
8329
8330    @Override
8331    public void startLockTaskMode(int taskId) {
8332        final TaskRecord task;
8333        long ident = Binder.clearCallingIdentity();
8334        try {
8335            synchronized (this) {
8336                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8337            }
8338        } finally {
8339            Binder.restoreCallingIdentity(ident);
8340        }
8341        if (task != null) {
8342            startLockTaskMode(task);
8343        }
8344    }
8345
8346    @Override
8347    public void startLockTaskMode(IBinder token) {
8348        final TaskRecord task;
8349        long ident = Binder.clearCallingIdentity();
8350        try {
8351            synchronized (this) {
8352                final ActivityRecord r = ActivityRecord.forToken(token);
8353                if (r == null) {
8354                    return;
8355                }
8356                task = r.task;
8357            }
8358        } finally {
8359            Binder.restoreCallingIdentity(ident);
8360        }
8361        if (task != null) {
8362            startLockTaskMode(task);
8363        }
8364    }
8365
8366    @Override
8367    public void startLockTaskModeOnCurrent() throws RemoteException {
8368        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8369        ActivityRecord r = null;
8370        synchronized (this) {
8371            r = mStackSupervisor.topRunningActivityLocked();
8372        }
8373        startLockTaskMode(r.task);
8374    }
8375
8376    @Override
8377    public void stopLockTaskMode() {
8378        // Verify that the user matches the package of the intent for the TaskRecord
8379        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8380        // and stopLockTaskMode.
8381        final int callingUid = Binder.getCallingUid();
8382        if (callingUid != Process.SYSTEM_UID) {
8383            try {
8384                String pkg =
8385                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8386                int uid = mContext.getPackageManager().getPackageUid(pkg,
8387                        Binder.getCallingUserHandle().getIdentifier());
8388                if (uid != callingUid) {
8389                    throw new SecurityException("Invalid uid, expected " + uid);
8390                }
8391            } catch (NameNotFoundException e) {
8392                Log.d(TAG, "stopLockTaskMode " + e);
8393                return;
8394            }
8395        }
8396        long ident = Binder.clearCallingIdentity();
8397        try {
8398            Log.d(TAG, "stopLockTaskMode");
8399            // Stop lock task
8400            synchronized (this) {
8401                mStackSupervisor.setLockTaskModeLocked(null, false);
8402            }
8403        } finally {
8404            Binder.restoreCallingIdentity(ident);
8405        }
8406    }
8407
8408    @Override
8409    public void stopLockTaskModeOnCurrent() throws RemoteException {
8410        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8411        long ident = Binder.clearCallingIdentity();
8412        try {
8413            stopLockTaskMode();
8414        } finally {
8415            Binder.restoreCallingIdentity(ident);
8416        }
8417    }
8418
8419    @Override
8420    public boolean isInLockTaskMode() {
8421        synchronized (this) {
8422            return mStackSupervisor.isInLockTaskMode();
8423        }
8424    }
8425
8426    // =========================================================
8427    // CONTENT PROVIDERS
8428    // =========================================================
8429
8430    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8431        List<ProviderInfo> providers = null;
8432        try {
8433            providers = AppGlobals.getPackageManager().
8434                queryContentProviders(app.processName, app.uid,
8435                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8436        } catch (RemoteException ex) {
8437        }
8438        if (DEBUG_MU)
8439            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8440        int userId = app.userId;
8441        if (providers != null) {
8442            int N = providers.size();
8443            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8444            for (int i=0; i<N; i++) {
8445                ProviderInfo cpi =
8446                    (ProviderInfo)providers.get(i);
8447                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8448                        cpi.name, cpi.flags);
8449                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8450                    // This is a singleton provider, but a user besides the
8451                    // default user is asking to initialize a process it runs
8452                    // in...  well, no, it doesn't actually run in this process,
8453                    // it runs in the process of the default user.  Get rid of it.
8454                    providers.remove(i);
8455                    N--;
8456                    i--;
8457                    continue;
8458                }
8459
8460                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8461                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8462                if (cpr == null) {
8463                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8464                    mProviderMap.putProviderByClass(comp, cpr);
8465                }
8466                if (DEBUG_MU)
8467                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8468                app.pubProviders.put(cpi.name, cpr);
8469                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8470                    // Don't add this if it is a platform component that is marked
8471                    // to run in multiple processes, because this is actually
8472                    // part of the framework so doesn't make sense to track as a
8473                    // separate apk in the process.
8474                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8475                            mProcessStats);
8476                }
8477                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8478            }
8479        }
8480        return providers;
8481    }
8482
8483    /**
8484     * Check if {@link ProcessRecord} has a possible chance at accessing the
8485     * given {@link ProviderInfo}. Final permission checking is always done
8486     * in {@link ContentProvider}.
8487     */
8488    private final String checkContentProviderPermissionLocked(
8489            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8490        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8491        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8492        boolean checkedGrants = false;
8493        if (checkUser) {
8494            // Looking for cross-user grants before enforcing the typical cross-users permissions
8495            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8496            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8497                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8498                    return null;
8499                }
8500                checkedGrants = true;
8501            }
8502            userId = handleIncomingUser(callingPid, callingUid, userId,
8503                    false, ALLOW_NON_FULL,
8504                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8505            if (userId != tmpTargetUserId) {
8506                // When we actually went to determine the final targer user ID, this ended
8507                // up different than our initial check for the authority.  This is because
8508                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8509                // SELF.  So we need to re-check the grants again.
8510                checkedGrants = false;
8511            }
8512        }
8513        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8514                cpi.applicationInfo.uid, cpi.exported)
8515                == PackageManager.PERMISSION_GRANTED) {
8516            return null;
8517        }
8518        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8519                cpi.applicationInfo.uid, cpi.exported)
8520                == PackageManager.PERMISSION_GRANTED) {
8521            return null;
8522        }
8523
8524        PathPermission[] pps = cpi.pathPermissions;
8525        if (pps != null) {
8526            int i = pps.length;
8527            while (i > 0) {
8528                i--;
8529                PathPermission pp = pps[i];
8530                String pprperm = pp.getReadPermission();
8531                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8532                        cpi.applicationInfo.uid, cpi.exported)
8533                        == PackageManager.PERMISSION_GRANTED) {
8534                    return null;
8535                }
8536                String ppwperm = pp.getWritePermission();
8537                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8538                        cpi.applicationInfo.uid, cpi.exported)
8539                        == PackageManager.PERMISSION_GRANTED) {
8540                    return null;
8541                }
8542            }
8543        }
8544        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8545            return null;
8546        }
8547
8548        String msg;
8549        if (!cpi.exported) {
8550            msg = "Permission Denial: opening provider " + cpi.name
8551                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8552                    + ", uid=" + callingUid + ") that is not exported from uid "
8553                    + cpi.applicationInfo.uid;
8554        } else {
8555            msg = "Permission Denial: opening provider " + cpi.name
8556                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8557                    + ", uid=" + callingUid + ") requires "
8558                    + cpi.readPermission + " or " + cpi.writePermission;
8559        }
8560        Slog.w(TAG, msg);
8561        return msg;
8562    }
8563
8564    /**
8565     * Returns if the ContentProvider has granted a uri to callingUid
8566     */
8567    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8568        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8569        if (perms != null) {
8570            for (int i=perms.size()-1; i>=0; i--) {
8571                GrantUri grantUri = perms.keyAt(i);
8572                if (grantUri.sourceUserId == userId || !checkUser) {
8573                    if (matchesProvider(grantUri.uri, cpi)) {
8574                        return true;
8575                    }
8576                }
8577            }
8578        }
8579        return false;
8580    }
8581
8582    /**
8583     * Returns true if the uri authority is one of the authorities specified in the provider.
8584     */
8585    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8586        String uriAuth = uri.getAuthority();
8587        String cpiAuth = cpi.authority;
8588        if (cpiAuth.indexOf(';') == -1) {
8589            return cpiAuth.equals(uriAuth);
8590        }
8591        String[] cpiAuths = cpiAuth.split(";");
8592        int length = cpiAuths.length;
8593        for (int i = 0; i < length; i++) {
8594            if (cpiAuths[i].equals(uriAuth)) return true;
8595        }
8596        return false;
8597    }
8598
8599    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8600            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8601        if (r != null) {
8602            for (int i=0; i<r.conProviders.size(); i++) {
8603                ContentProviderConnection conn = r.conProviders.get(i);
8604                if (conn.provider == cpr) {
8605                    if (DEBUG_PROVIDER) Slog.v(TAG,
8606                            "Adding provider requested by "
8607                            + r.processName + " from process "
8608                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8609                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8610                    if (stable) {
8611                        conn.stableCount++;
8612                        conn.numStableIncs++;
8613                    } else {
8614                        conn.unstableCount++;
8615                        conn.numUnstableIncs++;
8616                    }
8617                    return conn;
8618                }
8619            }
8620            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8621            if (stable) {
8622                conn.stableCount = 1;
8623                conn.numStableIncs = 1;
8624            } else {
8625                conn.unstableCount = 1;
8626                conn.numUnstableIncs = 1;
8627            }
8628            cpr.connections.add(conn);
8629            r.conProviders.add(conn);
8630            return conn;
8631        }
8632        cpr.addExternalProcessHandleLocked(externalProcessToken);
8633        return null;
8634    }
8635
8636    boolean decProviderCountLocked(ContentProviderConnection conn,
8637            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8638        if (conn != null) {
8639            cpr = conn.provider;
8640            if (DEBUG_PROVIDER) Slog.v(TAG,
8641                    "Removing provider requested by "
8642                    + conn.client.processName + " from process "
8643                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8644                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8645            if (stable) {
8646                conn.stableCount--;
8647            } else {
8648                conn.unstableCount--;
8649            }
8650            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8651                cpr.connections.remove(conn);
8652                conn.client.conProviders.remove(conn);
8653                return true;
8654            }
8655            return false;
8656        }
8657        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8658        return false;
8659    }
8660
8661    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8662            String name, IBinder token, boolean stable, int userId) {
8663        ContentProviderRecord cpr;
8664        ContentProviderConnection conn = null;
8665        ProviderInfo cpi = null;
8666
8667        synchronized(this) {
8668            ProcessRecord r = null;
8669            if (caller != null) {
8670                r = getRecordForAppLocked(caller);
8671                if (r == null) {
8672                    throw new SecurityException(
8673                            "Unable to find app for caller " + caller
8674                          + " (pid=" + Binder.getCallingPid()
8675                          + ") when getting content provider " + name);
8676                }
8677            }
8678
8679            boolean checkCrossUser = true;
8680
8681            // First check if this content provider has been published...
8682            cpr = mProviderMap.getProviderByName(name, userId);
8683            // If that didn't work, check if it exists for user 0 and then
8684            // verify that it's a singleton provider before using it.
8685            if (cpr == null && userId != UserHandle.USER_OWNER) {
8686                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8687                if (cpr != null) {
8688                    cpi = cpr.info;
8689                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8690                            cpi.name, cpi.flags)
8691                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8692                        userId = UserHandle.USER_OWNER;
8693                        checkCrossUser = false;
8694                    } else {
8695                        cpr = null;
8696                        cpi = null;
8697                    }
8698                }
8699            }
8700
8701            boolean providerRunning = cpr != null;
8702            if (providerRunning) {
8703                cpi = cpr.info;
8704                String msg;
8705                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8706                        != null) {
8707                    throw new SecurityException(msg);
8708                }
8709
8710                if (r != null && cpr.canRunHere(r)) {
8711                    // This provider has been published or is in the process
8712                    // of being published...  but it is also allowed to run
8713                    // in the caller's process, so don't make a connection
8714                    // and just let the caller instantiate its own instance.
8715                    ContentProviderHolder holder = cpr.newHolder(null);
8716                    // don't give caller the provider object, it needs
8717                    // to make its own.
8718                    holder.provider = null;
8719                    return holder;
8720                }
8721
8722                final long origId = Binder.clearCallingIdentity();
8723
8724                // In this case the provider instance already exists, so we can
8725                // return it right away.
8726                conn = incProviderCountLocked(r, cpr, token, stable);
8727                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8728                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8729                        // If this is a perceptible app accessing the provider,
8730                        // make sure to count it as being accessed and thus
8731                        // back up on the LRU list.  This is good because
8732                        // content providers are often expensive to start.
8733                        updateLruProcessLocked(cpr.proc, false, null);
8734                    }
8735                }
8736
8737                if (cpr.proc != null) {
8738                    if (false) {
8739                        if (cpr.name.flattenToShortString().equals(
8740                                "com.android.providers.calendar/.CalendarProvider2")) {
8741                            Slog.v(TAG, "****************** KILLING "
8742                                + cpr.name.flattenToShortString());
8743                            Process.killProcess(cpr.proc.pid);
8744                        }
8745                    }
8746                    boolean success = updateOomAdjLocked(cpr.proc);
8747                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8748                    // NOTE: there is still a race here where a signal could be
8749                    // pending on the process even though we managed to update its
8750                    // adj level.  Not sure what to do about this, but at least
8751                    // the race is now smaller.
8752                    if (!success) {
8753                        // Uh oh...  it looks like the provider's process
8754                        // has been killed on us.  We need to wait for a new
8755                        // process to be started, and make sure its death
8756                        // doesn't kill our process.
8757                        Slog.i(TAG,
8758                                "Existing provider " + cpr.name.flattenToShortString()
8759                                + " is crashing; detaching " + r);
8760                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8761                        appDiedLocked(cpr.proc);
8762                        if (!lastRef) {
8763                            // This wasn't the last ref our process had on
8764                            // the provider...  we have now been killed, bail.
8765                            return null;
8766                        }
8767                        providerRunning = false;
8768                        conn = null;
8769                    }
8770                }
8771
8772                Binder.restoreCallingIdentity(origId);
8773            }
8774
8775            boolean singleton;
8776            if (!providerRunning) {
8777                try {
8778                    cpi = AppGlobals.getPackageManager().
8779                        resolveContentProvider(name,
8780                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8781                } catch (RemoteException ex) {
8782                }
8783                if (cpi == null) {
8784                    return null;
8785                }
8786                // If the provider is a singleton AND
8787                // (it's a call within the same user || the provider is a
8788                // privileged app)
8789                // Then allow connecting to the singleton provider
8790                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8791                        cpi.name, cpi.flags)
8792                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8793                if (singleton) {
8794                    userId = UserHandle.USER_OWNER;
8795                }
8796                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8797
8798                String msg;
8799                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8800                        != null) {
8801                    throw new SecurityException(msg);
8802                }
8803
8804                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8805                        && !cpi.processName.equals("system")) {
8806                    // If this content provider does not run in the system
8807                    // process, and the system is not yet ready to run other
8808                    // processes, then fail fast instead of hanging.
8809                    throw new IllegalArgumentException(
8810                            "Attempt to launch content provider before system ready");
8811                }
8812
8813                // Make sure that the user who owns this provider is started.  If not,
8814                // we don't want to allow it to run.
8815                if (mStartedUsers.get(userId) == null) {
8816                    Slog.w(TAG, "Unable to launch app "
8817                            + cpi.applicationInfo.packageName + "/"
8818                            + cpi.applicationInfo.uid + " for provider "
8819                            + name + ": user " + userId + " is stopped");
8820                    return null;
8821                }
8822
8823                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8824                cpr = mProviderMap.getProviderByClass(comp, userId);
8825                final boolean firstClass = cpr == null;
8826                if (firstClass) {
8827                    try {
8828                        ApplicationInfo ai =
8829                            AppGlobals.getPackageManager().
8830                                getApplicationInfo(
8831                                        cpi.applicationInfo.packageName,
8832                                        STOCK_PM_FLAGS, userId);
8833                        if (ai == null) {
8834                            Slog.w(TAG, "No package info for content provider "
8835                                    + cpi.name);
8836                            return null;
8837                        }
8838                        ai = getAppInfoForUser(ai, userId);
8839                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8840                    } catch (RemoteException ex) {
8841                        // pm is in same process, this will never happen.
8842                    }
8843                }
8844
8845                if (r != null && cpr.canRunHere(r)) {
8846                    // If this is a multiprocess provider, then just return its
8847                    // info and allow the caller to instantiate it.  Only do
8848                    // this if the provider is the same user as the caller's
8849                    // process, or can run as root (so can be in any process).
8850                    return cpr.newHolder(null);
8851                }
8852
8853                if (DEBUG_PROVIDER) {
8854                    RuntimeException e = new RuntimeException("here");
8855                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8856                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8857                }
8858
8859                // This is single process, and our app is now connecting to it.
8860                // See if we are already in the process of launching this
8861                // provider.
8862                final int N = mLaunchingProviders.size();
8863                int i;
8864                for (i=0; i<N; i++) {
8865                    if (mLaunchingProviders.get(i) == cpr) {
8866                        break;
8867                    }
8868                }
8869
8870                // If the provider is not already being launched, then get it
8871                // started.
8872                if (i >= N) {
8873                    final long origId = Binder.clearCallingIdentity();
8874
8875                    try {
8876                        // Content provider is now in use, its package can't be stopped.
8877                        try {
8878                            AppGlobals.getPackageManager().setPackageStoppedState(
8879                                    cpr.appInfo.packageName, false, userId);
8880                        } catch (RemoteException e) {
8881                        } catch (IllegalArgumentException e) {
8882                            Slog.w(TAG, "Failed trying to unstop package "
8883                                    + cpr.appInfo.packageName + ": " + e);
8884                        }
8885
8886                        // Use existing process if already started
8887                        ProcessRecord proc = getProcessRecordLocked(
8888                                cpi.processName, cpr.appInfo.uid, false);
8889                        if (proc != null && proc.thread != null) {
8890                            if (DEBUG_PROVIDER) {
8891                                Slog.d(TAG, "Installing in existing process " + proc);
8892                            }
8893                            proc.pubProviders.put(cpi.name, cpr);
8894                            try {
8895                                proc.thread.scheduleInstallProvider(cpi);
8896                            } catch (RemoteException e) {
8897                            }
8898                        } else {
8899                            proc = startProcessLocked(cpi.processName,
8900                                    cpr.appInfo, false, 0, "content provider",
8901                                    new ComponentName(cpi.applicationInfo.packageName,
8902                                            cpi.name), false, false, false);
8903                            if (proc == null) {
8904                                Slog.w(TAG, "Unable to launch app "
8905                                        + cpi.applicationInfo.packageName + "/"
8906                                        + cpi.applicationInfo.uid + " for provider "
8907                                        + name + ": process is bad");
8908                                return null;
8909                            }
8910                        }
8911                        cpr.launchingApp = proc;
8912                        mLaunchingProviders.add(cpr);
8913                    } finally {
8914                        Binder.restoreCallingIdentity(origId);
8915                    }
8916                }
8917
8918                // Make sure the provider is published (the same provider class
8919                // may be published under multiple names).
8920                if (firstClass) {
8921                    mProviderMap.putProviderByClass(comp, cpr);
8922                }
8923
8924                mProviderMap.putProviderByName(name, cpr);
8925                conn = incProviderCountLocked(r, cpr, token, stable);
8926                if (conn != null) {
8927                    conn.waiting = true;
8928                }
8929            }
8930        }
8931
8932        // Wait for the provider to be published...
8933        synchronized (cpr) {
8934            while (cpr.provider == null) {
8935                if (cpr.launchingApp == null) {
8936                    Slog.w(TAG, "Unable to launch app "
8937                            + cpi.applicationInfo.packageName + "/"
8938                            + cpi.applicationInfo.uid + " for provider "
8939                            + name + ": launching app became null");
8940                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8941                            UserHandle.getUserId(cpi.applicationInfo.uid),
8942                            cpi.applicationInfo.packageName,
8943                            cpi.applicationInfo.uid, name);
8944                    return null;
8945                }
8946                try {
8947                    if (DEBUG_MU) {
8948                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8949                                + cpr.launchingApp);
8950                    }
8951                    if (conn != null) {
8952                        conn.waiting = true;
8953                    }
8954                    cpr.wait();
8955                } catch (InterruptedException ex) {
8956                } finally {
8957                    if (conn != null) {
8958                        conn.waiting = false;
8959                    }
8960                }
8961            }
8962        }
8963        return cpr != null ? cpr.newHolder(conn) : null;
8964    }
8965
8966    @Override
8967    public final ContentProviderHolder getContentProvider(
8968            IApplicationThread caller, String name, int userId, boolean stable) {
8969        enforceNotIsolatedCaller("getContentProvider");
8970        if (caller == null) {
8971            String msg = "null IApplicationThread when getting content provider "
8972                    + name;
8973            Slog.w(TAG, msg);
8974            throw new SecurityException(msg);
8975        }
8976        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8977        // with cross-user grant.
8978        return getContentProviderImpl(caller, name, null, stable, userId);
8979    }
8980
8981    public ContentProviderHolder getContentProviderExternal(
8982            String name, int userId, IBinder token) {
8983        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8984            "Do not have permission in call getContentProviderExternal()");
8985        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8986                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8987        return getContentProviderExternalUnchecked(name, token, userId);
8988    }
8989
8990    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8991            IBinder token, int userId) {
8992        return getContentProviderImpl(null, name, token, true, userId);
8993    }
8994
8995    /**
8996     * Drop a content provider from a ProcessRecord's bookkeeping
8997     */
8998    public void removeContentProvider(IBinder connection, boolean stable) {
8999        enforceNotIsolatedCaller("removeContentProvider");
9000        long ident = Binder.clearCallingIdentity();
9001        try {
9002            synchronized (this) {
9003                ContentProviderConnection conn;
9004                try {
9005                    conn = (ContentProviderConnection)connection;
9006                } catch (ClassCastException e) {
9007                    String msg ="removeContentProvider: " + connection
9008                            + " not a ContentProviderConnection";
9009                    Slog.w(TAG, msg);
9010                    throw new IllegalArgumentException(msg);
9011                }
9012                if (conn == null) {
9013                    throw new NullPointerException("connection is null");
9014                }
9015                if (decProviderCountLocked(conn, null, null, stable)) {
9016                    updateOomAdjLocked();
9017                }
9018            }
9019        } finally {
9020            Binder.restoreCallingIdentity(ident);
9021        }
9022    }
9023
9024    public void removeContentProviderExternal(String name, IBinder token) {
9025        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9026            "Do not have permission in call removeContentProviderExternal()");
9027        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9028    }
9029
9030    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9031        synchronized (this) {
9032            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9033            if(cpr == null) {
9034                //remove from mProvidersByClass
9035                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9036                return;
9037            }
9038
9039            //update content provider record entry info
9040            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9041            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9042            if (localCpr.hasExternalProcessHandles()) {
9043                if (localCpr.removeExternalProcessHandleLocked(token)) {
9044                    updateOomAdjLocked();
9045                } else {
9046                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9047                            + " with no external reference for token: "
9048                            + token + ".");
9049                }
9050            } else {
9051                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9052                        + " with no external references.");
9053            }
9054        }
9055    }
9056
9057    public final void publishContentProviders(IApplicationThread caller,
9058            List<ContentProviderHolder> providers) {
9059        if (providers == null) {
9060            return;
9061        }
9062
9063        enforceNotIsolatedCaller("publishContentProviders");
9064        synchronized (this) {
9065            final ProcessRecord r = getRecordForAppLocked(caller);
9066            if (DEBUG_MU)
9067                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9068            if (r == null) {
9069                throw new SecurityException(
9070                        "Unable to find app for caller " + caller
9071                      + " (pid=" + Binder.getCallingPid()
9072                      + ") when publishing content providers");
9073            }
9074
9075            final long origId = Binder.clearCallingIdentity();
9076
9077            final int N = providers.size();
9078            for (int i=0; i<N; i++) {
9079                ContentProviderHolder src = providers.get(i);
9080                if (src == null || src.info == null || src.provider == null) {
9081                    continue;
9082                }
9083                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9084                if (DEBUG_MU)
9085                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9086                if (dst != null) {
9087                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9088                    mProviderMap.putProviderByClass(comp, dst);
9089                    String names[] = dst.info.authority.split(";");
9090                    for (int j = 0; j < names.length; j++) {
9091                        mProviderMap.putProviderByName(names[j], dst);
9092                    }
9093
9094                    int NL = mLaunchingProviders.size();
9095                    int j;
9096                    for (j=0; j<NL; j++) {
9097                        if (mLaunchingProviders.get(j) == dst) {
9098                            mLaunchingProviders.remove(j);
9099                            j--;
9100                            NL--;
9101                        }
9102                    }
9103                    synchronized (dst) {
9104                        dst.provider = src.provider;
9105                        dst.proc = r;
9106                        dst.notifyAll();
9107                    }
9108                    updateOomAdjLocked(r);
9109                }
9110            }
9111
9112            Binder.restoreCallingIdentity(origId);
9113        }
9114    }
9115
9116    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9117        ContentProviderConnection conn;
9118        try {
9119            conn = (ContentProviderConnection)connection;
9120        } catch (ClassCastException e) {
9121            String msg ="refContentProvider: " + connection
9122                    + " not a ContentProviderConnection";
9123            Slog.w(TAG, msg);
9124            throw new IllegalArgumentException(msg);
9125        }
9126        if (conn == null) {
9127            throw new NullPointerException("connection is null");
9128        }
9129
9130        synchronized (this) {
9131            if (stable > 0) {
9132                conn.numStableIncs += stable;
9133            }
9134            stable = conn.stableCount + stable;
9135            if (stable < 0) {
9136                throw new IllegalStateException("stableCount < 0: " + stable);
9137            }
9138
9139            if (unstable > 0) {
9140                conn.numUnstableIncs += unstable;
9141            }
9142            unstable = conn.unstableCount + unstable;
9143            if (unstable < 0) {
9144                throw new IllegalStateException("unstableCount < 0: " + unstable);
9145            }
9146
9147            if ((stable+unstable) <= 0) {
9148                throw new IllegalStateException("ref counts can't go to zero here: stable="
9149                        + stable + " unstable=" + unstable);
9150            }
9151            conn.stableCount = stable;
9152            conn.unstableCount = unstable;
9153            return !conn.dead;
9154        }
9155    }
9156
9157    public void unstableProviderDied(IBinder connection) {
9158        ContentProviderConnection conn;
9159        try {
9160            conn = (ContentProviderConnection)connection;
9161        } catch (ClassCastException e) {
9162            String msg ="refContentProvider: " + connection
9163                    + " not a ContentProviderConnection";
9164            Slog.w(TAG, msg);
9165            throw new IllegalArgumentException(msg);
9166        }
9167        if (conn == null) {
9168            throw new NullPointerException("connection is null");
9169        }
9170
9171        // Safely retrieve the content provider associated with the connection.
9172        IContentProvider provider;
9173        synchronized (this) {
9174            provider = conn.provider.provider;
9175        }
9176
9177        if (provider == null) {
9178            // Um, yeah, we're way ahead of you.
9179            return;
9180        }
9181
9182        // Make sure the caller is being honest with us.
9183        if (provider.asBinder().pingBinder()) {
9184            // Er, no, still looks good to us.
9185            synchronized (this) {
9186                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9187                        + " says " + conn + " died, but we don't agree");
9188                return;
9189            }
9190        }
9191
9192        // Well look at that!  It's dead!
9193        synchronized (this) {
9194            if (conn.provider.provider != provider) {
9195                // But something changed...  good enough.
9196                return;
9197            }
9198
9199            ProcessRecord proc = conn.provider.proc;
9200            if (proc == null || proc.thread == null) {
9201                // Seems like the process is already cleaned up.
9202                return;
9203            }
9204
9205            // As far as we're concerned, this is just like receiving a
9206            // death notification...  just a bit prematurely.
9207            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9208                    + ") early provider death");
9209            final long ident = Binder.clearCallingIdentity();
9210            try {
9211                appDiedLocked(proc);
9212            } finally {
9213                Binder.restoreCallingIdentity(ident);
9214            }
9215        }
9216    }
9217
9218    @Override
9219    public void appNotRespondingViaProvider(IBinder connection) {
9220        enforceCallingPermission(
9221                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9222
9223        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9224        if (conn == null) {
9225            Slog.w(TAG, "ContentProviderConnection is null");
9226            return;
9227        }
9228
9229        final ProcessRecord host = conn.provider.proc;
9230        if (host == null) {
9231            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9232            return;
9233        }
9234
9235        final long token = Binder.clearCallingIdentity();
9236        try {
9237            appNotResponding(host, null, null, false, "ContentProvider not responding");
9238        } finally {
9239            Binder.restoreCallingIdentity(token);
9240        }
9241    }
9242
9243    public final void installSystemProviders() {
9244        List<ProviderInfo> providers;
9245        synchronized (this) {
9246            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9247            providers = generateApplicationProvidersLocked(app);
9248            if (providers != null) {
9249                for (int i=providers.size()-1; i>=0; i--) {
9250                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9251                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9252                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9253                                + ": not system .apk");
9254                        providers.remove(i);
9255                    }
9256                }
9257            }
9258        }
9259        if (providers != null) {
9260            mSystemThread.installSystemProviders(providers);
9261        }
9262
9263        mCoreSettingsObserver = new CoreSettingsObserver(this);
9264
9265        //mUsageStatsService.monitorPackages();
9266    }
9267
9268    /**
9269     * Allows apps to retrieve the MIME type of a URI.
9270     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9271     * users, then it does not need permission to access the ContentProvider.
9272     * Either, it needs cross-user uri grants.
9273     *
9274     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9275     *
9276     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9277     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9278     */
9279    public String getProviderMimeType(Uri uri, int userId) {
9280        enforceNotIsolatedCaller("getProviderMimeType");
9281        final String name = uri.getAuthority();
9282        int callingUid = Binder.getCallingUid();
9283        int callingPid = Binder.getCallingPid();
9284        long ident = 0;
9285        boolean clearedIdentity = false;
9286        userId = unsafeConvertIncomingUser(userId);
9287        if (UserHandle.getUserId(callingUid) != userId) {
9288            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9289                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9290                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9291                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9292                clearedIdentity = true;
9293                ident = Binder.clearCallingIdentity();
9294            }
9295        }
9296        ContentProviderHolder holder = null;
9297        try {
9298            holder = getContentProviderExternalUnchecked(name, null, userId);
9299            if (holder != null) {
9300                return holder.provider.getType(uri);
9301            }
9302        } catch (RemoteException e) {
9303            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9304            return null;
9305        } finally {
9306            // We need to clear the identity to call removeContentProviderExternalUnchecked
9307            if (!clearedIdentity) {
9308                ident = Binder.clearCallingIdentity();
9309            }
9310            try {
9311                if (holder != null) {
9312                    removeContentProviderExternalUnchecked(name, null, userId);
9313                }
9314            } finally {
9315                Binder.restoreCallingIdentity(ident);
9316            }
9317        }
9318
9319        return null;
9320    }
9321
9322    // =========================================================
9323    // GLOBAL MANAGEMENT
9324    // =========================================================
9325
9326    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9327            boolean isolated, int isolatedUid) {
9328        String proc = customProcess != null ? customProcess : info.processName;
9329        BatteryStatsImpl.Uid.Proc ps = null;
9330        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9331        int uid = info.uid;
9332        if (isolated) {
9333            if (isolatedUid == 0) {
9334                int userId = UserHandle.getUserId(uid);
9335                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9336                while (true) {
9337                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9338                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9339                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9340                    }
9341                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9342                    mNextIsolatedProcessUid++;
9343                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9344                        // No process for this uid, use it.
9345                        break;
9346                    }
9347                    stepsLeft--;
9348                    if (stepsLeft <= 0) {
9349                        return null;
9350                    }
9351                }
9352            } else {
9353                // Special case for startIsolatedProcess (internal only), where
9354                // the uid of the isolated process is specified by the caller.
9355                uid = isolatedUid;
9356            }
9357        }
9358        return new ProcessRecord(stats, info, proc, uid);
9359    }
9360
9361    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9362            String abiOverride) {
9363        ProcessRecord app;
9364        if (!isolated) {
9365            app = getProcessRecordLocked(info.processName, info.uid, true);
9366        } else {
9367            app = null;
9368        }
9369
9370        if (app == null) {
9371            app = newProcessRecordLocked(info, null, isolated, 0);
9372            mProcessNames.put(info.processName, app.uid, app);
9373            if (isolated) {
9374                mIsolatedProcesses.put(app.uid, app);
9375            }
9376            updateLruProcessLocked(app, false, null);
9377            updateOomAdjLocked();
9378        }
9379
9380        // This package really, really can not be stopped.
9381        try {
9382            AppGlobals.getPackageManager().setPackageStoppedState(
9383                    info.packageName, false, UserHandle.getUserId(app.uid));
9384        } catch (RemoteException e) {
9385        } catch (IllegalArgumentException e) {
9386            Slog.w(TAG, "Failed trying to unstop package "
9387                    + info.packageName + ": " + e);
9388        }
9389
9390        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9391                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9392            app.persistent = true;
9393            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9394        }
9395        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9396            mPersistentStartingProcesses.add(app);
9397            startProcessLocked(app, "added application", app.processName, abiOverride,
9398                    null /* entryPoint */, null /* entryPointArgs */);
9399        }
9400
9401        return app;
9402    }
9403
9404    public void unhandledBack() {
9405        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9406                "unhandledBack()");
9407
9408        synchronized(this) {
9409            final long origId = Binder.clearCallingIdentity();
9410            try {
9411                getFocusedStack().unhandledBackLocked();
9412            } finally {
9413                Binder.restoreCallingIdentity(origId);
9414            }
9415        }
9416    }
9417
9418    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9419        enforceNotIsolatedCaller("openContentUri");
9420        final int userId = UserHandle.getCallingUserId();
9421        String name = uri.getAuthority();
9422        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9423        ParcelFileDescriptor pfd = null;
9424        if (cph != null) {
9425            // We record the binder invoker's uid in thread-local storage before
9426            // going to the content provider to open the file.  Later, in the code
9427            // that handles all permissions checks, we look for this uid and use
9428            // that rather than the Activity Manager's own uid.  The effect is that
9429            // we do the check against the caller's permissions even though it looks
9430            // to the content provider like the Activity Manager itself is making
9431            // the request.
9432            sCallerIdentity.set(new Identity(
9433                    Binder.getCallingPid(), Binder.getCallingUid()));
9434            try {
9435                pfd = cph.provider.openFile(null, uri, "r", null);
9436            } catch (FileNotFoundException e) {
9437                // do nothing; pfd will be returned null
9438            } finally {
9439                // Ensure that whatever happens, we clean up the identity state
9440                sCallerIdentity.remove();
9441            }
9442
9443            // We've got the fd now, so we're done with the provider.
9444            removeContentProviderExternalUnchecked(name, null, userId);
9445        } else {
9446            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9447        }
9448        return pfd;
9449    }
9450
9451    // Actually is sleeping or shutting down or whatever else in the future
9452    // is an inactive state.
9453    public boolean isSleepingOrShuttingDown() {
9454        return mSleeping || mShuttingDown;
9455    }
9456
9457    public boolean isSleeping() {
9458        return mSleeping;
9459    }
9460
9461    void goingToSleep() {
9462        synchronized(this) {
9463            mWentToSleep = true;
9464            updateEventDispatchingLocked();
9465            goToSleepIfNeededLocked();
9466        }
9467    }
9468
9469    void finishRunningVoiceLocked() {
9470        if (mRunningVoice) {
9471            mRunningVoice = false;
9472            goToSleepIfNeededLocked();
9473        }
9474    }
9475
9476    void goToSleepIfNeededLocked() {
9477        if (mWentToSleep && !mRunningVoice) {
9478            if (!mSleeping) {
9479                mSleeping = true;
9480                mStackSupervisor.goingToSleepLocked();
9481
9482                // Initialize the wake times of all processes.
9483                checkExcessivePowerUsageLocked(false);
9484                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9485                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9486                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9487            }
9488        }
9489    }
9490
9491    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9492        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9493            // Never persist the home stack.
9494            return;
9495        }
9496        mTaskPersister.wakeup(task, flush);
9497    }
9498
9499    @Override
9500    public boolean shutdown(int timeout) {
9501        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9502                != PackageManager.PERMISSION_GRANTED) {
9503            throw new SecurityException("Requires permission "
9504                    + android.Manifest.permission.SHUTDOWN);
9505        }
9506
9507        boolean timedout = false;
9508
9509        synchronized(this) {
9510            mShuttingDown = true;
9511            updateEventDispatchingLocked();
9512            timedout = mStackSupervisor.shutdownLocked(timeout);
9513        }
9514
9515        mAppOpsService.shutdown();
9516        if (mUsageStatsService != null) {
9517            mUsageStatsService.prepareShutdown();
9518        }
9519        mBatteryStatsService.shutdown();
9520        synchronized (this) {
9521            mProcessStats.shutdownLocked();
9522        }
9523        notifyTaskPersisterLocked(null, true);
9524
9525        return timedout;
9526    }
9527
9528    public final void activitySlept(IBinder token) {
9529        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9530
9531        final long origId = Binder.clearCallingIdentity();
9532
9533        synchronized (this) {
9534            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9535            if (r != null) {
9536                mStackSupervisor.activitySleptLocked(r);
9537            }
9538        }
9539
9540        Binder.restoreCallingIdentity(origId);
9541    }
9542
9543    void logLockScreen(String msg) {
9544        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9545                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9546                mWentToSleep + " mSleeping=" + mSleeping);
9547    }
9548
9549    private void comeOutOfSleepIfNeededLocked() {
9550        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9551            if (mSleeping) {
9552                mSleeping = false;
9553                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9554            }
9555        }
9556    }
9557
9558    void wakingUp() {
9559        synchronized(this) {
9560            mWentToSleep = false;
9561            updateEventDispatchingLocked();
9562            comeOutOfSleepIfNeededLocked();
9563        }
9564    }
9565
9566    void startRunningVoiceLocked() {
9567        if (!mRunningVoice) {
9568            mRunningVoice = true;
9569            comeOutOfSleepIfNeededLocked();
9570        }
9571    }
9572
9573    private void updateEventDispatchingLocked() {
9574        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9575    }
9576
9577    public void setLockScreenShown(boolean shown) {
9578        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9579                != PackageManager.PERMISSION_GRANTED) {
9580            throw new SecurityException("Requires permission "
9581                    + android.Manifest.permission.DEVICE_POWER);
9582        }
9583
9584        synchronized(this) {
9585            long ident = Binder.clearCallingIdentity();
9586            try {
9587                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9588                mLockScreenShown = shown;
9589                comeOutOfSleepIfNeededLocked();
9590            } finally {
9591                Binder.restoreCallingIdentity(ident);
9592            }
9593        }
9594    }
9595
9596    @Override
9597    public void stopAppSwitches() {
9598        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9599                != PackageManager.PERMISSION_GRANTED) {
9600            throw new SecurityException("Requires permission "
9601                    + android.Manifest.permission.STOP_APP_SWITCHES);
9602        }
9603
9604        synchronized(this) {
9605            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9606                    + APP_SWITCH_DELAY_TIME;
9607            mDidAppSwitch = false;
9608            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9609            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9610            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9611        }
9612    }
9613
9614    public void resumeAppSwitches() {
9615        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9616                != PackageManager.PERMISSION_GRANTED) {
9617            throw new SecurityException("Requires permission "
9618                    + android.Manifest.permission.STOP_APP_SWITCHES);
9619        }
9620
9621        synchronized(this) {
9622            // Note that we don't execute any pending app switches... we will
9623            // let those wait until either the timeout, or the next start
9624            // activity request.
9625            mAppSwitchesAllowedTime = 0;
9626        }
9627    }
9628
9629    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9630            String name) {
9631        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9632            return true;
9633        }
9634
9635        final int perm = checkComponentPermission(
9636                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9637                callingUid, -1, true);
9638        if (perm == PackageManager.PERMISSION_GRANTED) {
9639            return true;
9640        }
9641
9642        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9643        return false;
9644    }
9645
9646    public void setDebugApp(String packageName, boolean waitForDebugger,
9647            boolean persistent) {
9648        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9649                "setDebugApp()");
9650
9651        long ident = Binder.clearCallingIdentity();
9652        try {
9653            // Note that this is not really thread safe if there are multiple
9654            // callers into it at the same time, but that's not a situation we
9655            // care about.
9656            if (persistent) {
9657                final ContentResolver resolver = mContext.getContentResolver();
9658                Settings.Global.putString(
9659                    resolver, Settings.Global.DEBUG_APP,
9660                    packageName);
9661                Settings.Global.putInt(
9662                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9663                    waitForDebugger ? 1 : 0);
9664            }
9665
9666            synchronized (this) {
9667                if (!persistent) {
9668                    mOrigDebugApp = mDebugApp;
9669                    mOrigWaitForDebugger = mWaitForDebugger;
9670                }
9671                mDebugApp = packageName;
9672                mWaitForDebugger = waitForDebugger;
9673                mDebugTransient = !persistent;
9674                if (packageName != null) {
9675                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9676                            false, UserHandle.USER_ALL, "set debug app");
9677                }
9678            }
9679        } finally {
9680            Binder.restoreCallingIdentity(ident);
9681        }
9682    }
9683
9684    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9685        synchronized (this) {
9686            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9687            if (!isDebuggable) {
9688                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9689                    throw new SecurityException("Process not debuggable: " + app.packageName);
9690                }
9691            }
9692
9693            mOpenGlTraceApp = processName;
9694        }
9695    }
9696
9697    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9698        synchronized (this) {
9699            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9700            if (!isDebuggable) {
9701                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9702                    throw new SecurityException("Process not debuggable: " + app.packageName);
9703                }
9704            }
9705            mProfileApp = processName;
9706            mProfileFile = profilerInfo.profileFile;
9707            if (mProfileFd != null) {
9708                try {
9709                    mProfileFd.close();
9710                } catch (IOException e) {
9711                }
9712                mProfileFd = null;
9713            }
9714            mProfileFd = profilerInfo.profileFd;
9715            mSamplingInterval = profilerInfo.samplingInterval;
9716            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9717            mProfileType = 0;
9718        }
9719    }
9720
9721    @Override
9722    public void setAlwaysFinish(boolean enabled) {
9723        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9724                "setAlwaysFinish()");
9725
9726        Settings.Global.putInt(
9727                mContext.getContentResolver(),
9728                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9729
9730        synchronized (this) {
9731            mAlwaysFinishActivities = enabled;
9732        }
9733    }
9734
9735    @Override
9736    public void setActivityController(IActivityController controller) {
9737        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9738                "setActivityController()");
9739        synchronized (this) {
9740            mController = controller;
9741            Watchdog.getInstance().setActivityController(controller);
9742        }
9743    }
9744
9745    @Override
9746    public void setUserIsMonkey(boolean userIsMonkey) {
9747        synchronized (this) {
9748            synchronized (mPidsSelfLocked) {
9749                final int callingPid = Binder.getCallingPid();
9750                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9751                if (precessRecord == null) {
9752                    throw new SecurityException("Unknown process: " + callingPid);
9753                }
9754                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9755                    throw new SecurityException("Only an instrumentation process "
9756                            + "with a UiAutomation can call setUserIsMonkey");
9757                }
9758            }
9759            mUserIsMonkey = userIsMonkey;
9760        }
9761    }
9762
9763    @Override
9764    public boolean isUserAMonkey() {
9765        synchronized (this) {
9766            // If there is a controller also implies the user is a monkey.
9767            return (mUserIsMonkey || mController != null);
9768        }
9769    }
9770
9771    public void requestBugReport() {
9772        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9773        SystemProperties.set("ctl.start", "bugreport");
9774    }
9775
9776    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9777        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9778    }
9779
9780    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9781        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9782            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9783        }
9784        return KEY_DISPATCHING_TIMEOUT;
9785    }
9786
9787    @Override
9788    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9789        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9790                != PackageManager.PERMISSION_GRANTED) {
9791            throw new SecurityException("Requires permission "
9792                    + android.Manifest.permission.FILTER_EVENTS);
9793        }
9794        ProcessRecord proc;
9795        long timeout;
9796        synchronized (this) {
9797            synchronized (mPidsSelfLocked) {
9798                proc = mPidsSelfLocked.get(pid);
9799            }
9800            timeout = getInputDispatchingTimeoutLocked(proc);
9801        }
9802
9803        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9804            return -1;
9805        }
9806
9807        return timeout;
9808    }
9809
9810    /**
9811     * Handle input dispatching timeouts.
9812     * Returns whether input dispatching should be aborted or not.
9813     */
9814    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9815            final ActivityRecord activity, final ActivityRecord parent,
9816            final boolean aboveSystem, String reason) {
9817        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9818                != PackageManager.PERMISSION_GRANTED) {
9819            throw new SecurityException("Requires permission "
9820                    + android.Manifest.permission.FILTER_EVENTS);
9821        }
9822
9823        final String annotation;
9824        if (reason == null) {
9825            annotation = "Input dispatching timed out";
9826        } else {
9827            annotation = "Input dispatching timed out (" + reason + ")";
9828        }
9829
9830        if (proc != null) {
9831            synchronized (this) {
9832                if (proc.debugging) {
9833                    return false;
9834                }
9835
9836                if (mDidDexOpt) {
9837                    // Give more time since we were dexopting.
9838                    mDidDexOpt = false;
9839                    return false;
9840                }
9841
9842                if (proc.instrumentationClass != null) {
9843                    Bundle info = new Bundle();
9844                    info.putString("shortMsg", "keyDispatchingTimedOut");
9845                    info.putString("longMsg", annotation);
9846                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9847                    return true;
9848                }
9849            }
9850            mHandler.post(new Runnable() {
9851                @Override
9852                public void run() {
9853                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9854                }
9855            });
9856        }
9857
9858        return true;
9859    }
9860
9861    public Bundle getAssistContextExtras(int requestType) {
9862        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9863                "getAssistContextExtras()");
9864        PendingAssistExtras pae;
9865        Bundle extras = new Bundle();
9866        synchronized (this) {
9867            ActivityRecord activity = getFocusedStack().mResumedActivity;
9868            if (activity == null) {
9869                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9870                return null;
9871            }
9872            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9873            if (activity.app == null || activity.app.thread == null) {
9874                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9875                return extras;
9876            }
9877            if (activity.app.pid == Binder.getCallingPid()) {
9878                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9879                return extras;
9880            }
9881            pae = new PendingAssistExtras(activity);
9882            try {
9883                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9884                        requestType);
9885                mPendingAssistExtras.add(pae);
9886                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9887            } catch (RemoteException e) {
9888                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9889                return extras;
9890            }
9891        }
9892        synchronized (pae) {
9893            while (!pae.haveResult) {
9894                try {
9895                    pae.wait();
9896                } catch (InterruptedException e) {
9897                }
9898            }
9899            if (pae.result != null) {
9900                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9901            }
9902        }
9903        synchronized (this) {
9904            mPendingAssistExtras.remove(pae);
9905            mHandler.removeCallbacks(pae);
9906        }
9907        return extras;
9908    }
9909
9910    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9911        PendingAssistExtras pae = (PendingAssistExtras)token;
9912        synchronized (pae) {
9913            pae.result = extras;
9914            pae.haveResult = true;
9915            pae.notifyAll();
9916        }
9917    }
9918
9919    public void registerProcessObserver(IProcessObserver observer) {
9920        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9921                "registerProcessObserver()");
9922        synchronized (this) {
9923            mProcessObservers.register(observer);
9924        }
9925    }
9926
9927    @Override
9928    public void unregisterProcessObserver(IProcessObserver observer) {
9929        synchronized (this) {
9930            mProcessObservers.unregister(observer);
9931        }
9932    }
9933
9934    @Override
9935    public boolean convertFromTranslucent(IBinder token) {
9936        final long origId = Binder.clearCallingIdentity();
9937        try {
9938            synchronized (this) {
9939                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9940                if (r == null) {
9941                    return false;
9942                }
9943                if (r.changeWindowTranslucency(true)) {
9944                    mWindowManager.setAppFullscreen(token, true);
9945                    r.task.stack.releaseBackgroundResources();
9946                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9947                    return true;
9948                }
9949                return false;
9950            }
9951        } finally {
9952            Binder.restoreCallingIdentity(origId);
9953        }
9954    }
9955
9956    @Override
9957    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9958        final long origId = Binder.clearCallingIdentity();
9959        try {
9960            synchronized (this) {
9961                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9962                if (r == null) {
9963                    return false;
9964                }
9965                int index = r.task.mActivities.lastIndexOf(r);
9966                if (index > 0) {
9967                    ActivityRecord under = r.task.mActivities.get(index - 1);
9968                    under.returningOptions = options;
9969                }
9970                if (r.changeWindowTranslucency(false)) {
9971                    r.task.stack.convertToTranslucent(r);
9972                    mWindowManager.setAppFullscreen(token, false);
9973                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9974                    return true;
9975                } else {
9976                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9977                    return false;
9978                }
9979            }
9980        } finally {
9981            Binder.restoreCallingIdentity(origId);
9982        }
9983    }
9984
9985    @Override
9986    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9987        final long origId = Binder.clearCallingIdentity();
9988        try {
9989            synchronized (this) {
9990                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9991                if (r != null) {
9992                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9993                }
9994            }
9995            return false;
9996        } finally {
9997            Binder.restoreCallingIdentity(origId);
9998        }
9999    }
10000
10001    @Override
10002    public boolean isBackgroundVisibleBehind(IBinder token) {
10003        final long origId = Binder.clearCallingIdentity();
10004        try {
10005            synchronized (this) {
10006                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10007                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10008                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10009                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10010                return visible;
10011            }
10012        } finally {
10013            Binder.restoreCallingIdentity(origId);
10014        }
10015    }
10016
10017    @Override
10018    public ActivityOptions getActivityOptions(IBinder token) {
10019        final long origId = Binder.clearCallingIdentity();
10020        try {
10021            synchronized (this) {
10022                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10023                if (r != null) {
10024                    final ActivityOptions activityOptions = r.pendingOptions;
10025                    r.pendingOptions = null;
10026                    return activityOptions;
10027                }
10028                return null;
10029            }
10030        } finally {
10031            Binder.restoreCallingIdentity(origId);
10032        }
10033    }
10034
10035    @Override
10036    public void setImmersive(IBinder token, boolean immersive) {
10037        synchronized(this) {
10038            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10039            if (r == null) {
10040                throw new IllegalArgumentException();
10041            }
10042            r.immersive = immersive;
10043
10044            // update associated state if we're frontmost
10045            if (r == mFocusedActivity) {
10046                if (DEBUG_IMMERSIVE) {
10047                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10048                }
10049                applyUpdateLockStateLocked(r);
10050            }
10051        }
10052    }
10053
10054    @Override
10055    public boolean isImmersive(IBinder token) {
10056        synchronized (this) {
10057            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10058            if (r == null) {
10059                throw new IllegalArgumentException();
10060            }
10061            return r.immersive;
10062        }
10063    }
10064
10065    public boolean isTopActivityImmersive() {
10066        enforceNotIsolatedCaller("startActivity");
10067        synchronized (this) {
10068            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10069            return (r != null) ? r.immersive : false;
10070        }
10071    }
10072
10073    @Override
10074    public boolean isTopOfTask(IBinder token) {
10075        synchronized (this) {
10076            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10077            if (r == null) {
10078                throw new IllegalArgumentException();
10079            }
10080            return r.task.getTopActivity() == r;
10081        }
10082    }
10083
10084    public final void enterSafeMode() {
10085        synchronized(this) {
10086            // It only makes sense to do this before the system is ready
10087            // and started launching other packages.
10088            if (!mSystemReady) {
10089                try {
10090                    AppGlobals.getPackageManager().enterSafeMode();
10091                } catch (RemoteException e) {
10092                }
10093            }
10094
10095            mSafeMode = true;
10096        }
10097    }
10098
10099    public final void showSafeModeOverlay() {
10100        View v = LayoutInflater.from(mContext).inflate(
10101                com.android.internal.R.layout.safe_mode, null);
10102        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10103        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10104        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10105        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10106        lp.gravity = Gravity.BOTTOM | Gravity.START;
10107        lp.format = v.getBackground().getOpacity();
10108        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10109                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10110        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10111        ((WindowManager)mContext.getSystemService(
10112                Context.WINDOW_SERVICE)).addView(v, lp);
10113    }
10114
10115    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10116        if (!(sender instanceof PendingIntentRecord)) {
10117            return;
10118        }
10119        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10120        synchronized (stats) {
10121            if (mBatteryStatsService.isOnBattery()) {
10122                mBatteryStatsService.enforceCallingPermission();
10123                PendingIntentRecord rec = (PendingIntentRecord)sender;
10124                int MY_UID = Binder.getCallingUid();
10125                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10126                BatteryStatsImpl.Uid.Pkg pkg =
10127                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10128                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10129                pkg.incWakeupsLocked();
10130            }
10131        }
10132    }
10133
10134    public boolean killPids(int[] pids, String pReason, boolean secure) {
10135        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10136            throw new SecurityException("killPids only available to the system");
10137        }
10138        String reason = (pReason == null) ? "Unknown" : pReason;
10139        // XXX Note: don't acquire main activity lock here, because the window
10140        // manager calls in with its locks held.
10141
10142        boolean killed = false;
10143        synchronized (mPidsSelfLocked) {
10144            int[] types = new int[pids.length];
10145            int worstType = 0;
10146            for (int i=0; i<pids.length; i++) {
10147                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10148                if (proc != null) {
10149                    int type = proc.setAdj;
10150                    types[i] = type;
10151                    if (type > worstType) {
10152                        worstType = type;
10153                    }
10154                }
10155            }
10156
10157            // If the worst oom_adj is somewhere in the cached proc LRU range,
10158            // then constrain it so we will kill all cached procs.
10159            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10160                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10161                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10162            }
10163
10164            // If this is not a secure call, don't let it kill processes that
10165            // are important.
10166            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10167                worstType = ProcessList.SERVICE_ADJ;
10168            }
10169
10170            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10171            for (int i=0; i<pids.length; i++) {
10172                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10173                if (proc == null) {
10174                    continue;
10175                }
10176                int adj = proc.setAdj;
10177                if (adj >= worstType && !proc.killedByAm) {
10178                    proc.kill(reason, true);
10179                    killed = true;
10180                }
10181            }
10182        }
10183        return killed;
10184    }
10185
10186    @Override
10187    public void killUid(int uid, String reason) {
10188        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10189            throw new SecurityException("killUid only available to the system");
10190        }
10191        synchronized (this) {
10192            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10193                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10194                    reason != null ? reason : "kill uid");
10195        }
10196    }
10197
10198    @Override
10199    public boolean killProcessesBelowForeground(String reason) {
10200        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10201            throw new SecurityException("killProcessesBelowForeground() only available to system");
10202        }
10203
10204        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10205    }
10206
10207    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10208        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10209            throw new SecurityException("killProcessesBelowAdj() only available to system");
10210        }
10211
10212        boolean killed = false;
10213        synchronized (mPidsSelfLocked) {
10214            final int size = mPidsSelfLocked.size();
10215            for (int i = 0; i < size; i++) {
10216                final int pid = mPidsSelfLocked.keyAt(i);
10217                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10218                if (proc == null) continue;
10219
10220                final int adj = proc.setAdj;
10221                if (adj > belowAdj && !proc.killedByAm) {
10222                    proc.kill(reason, true);
10223                    killed = true;
10224                }
10225            }
10226        }
10227        return killed;
10228    }
10229
10230    @Override
10231    public void hang(final IBinder who, boolean allowRestart) {
10232        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10233                != PackageManager.PERMISSION_GRANTED) {
10234            throw new SecurityException("Requires permission "
10235                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10236        }
10237
10238        final IBinder.DeathRecipient death = new DeathRecipient() {
10239            @Override
10240            public void binderDied() {
10241                synchronized (this) {
10242                    notifyAll();
10243                }
10244            }
10245        };
10246
10247        try {
10248            who.linkToDeath(death, 0);
10249        } catch (RemoteException e) {
10250            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10251            return;
10252        }
10253
10254        synchronized (this) {
10255            Watchdog.getInstance().setAllowRestart(allowRestart);
10256            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10257            synchronized (death) {
10258                while (who.isBinderAlive()) {
10259                    try {
10260                        death.wait();
10261                    } catch (InterruptedException e) {
10262                    }
10263                }
10264            }
10265            Watchdog.getInstance().setAllowRestart(true);
10266        }
10267    }
10268
10269    @Override
10270    public void restart() {
10271        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10272                != PackageManager.PERMISSION_GRANTED) {
10273            throw new SecurityException("Requires permission "
10274                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10275        }
10276
10277        Log.i(TAG, "Sending shutdown broadcast...");
10278
10279        BroadcastReceiver br = new BroadcastReceiver() {
10280            @Override public void onReceive(Context context, Intent intent) {
10281                // Now the broadcast is done, finish up the low-level shutdown.
10282                Log.i(TAG, "Shutting down activity manager...");
10283                shutdown(10000);
10284                Log.i(TAG, "Shutdown complete, restarting!");
10285                Process.killProcess(Process.myPid());
10286                System.exit(10);
10287            }
10288        };
10289
10290        // First send the high-level shut down broadcast.
10291        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10292        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10293        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10294        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10295        mContext.sendOrderedBroadcastAsUser(intent,
10296                UserHandle.ALL, null, br, mHandler, 0, null, null);
10297        */
10298        br.onReceive(mContext, intent);
10299    }
10300
10301    private long getLowRamTimeSinceIdle(long now) {
10302        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10303    }
10304
10305    @Override
10306    public void performIdleMaintenance() {
10307        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10308                != PackageManager.PERMISSION_GRANTED) {
10309            throw new SecurityException("Requires permission "
10310                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10311        }
10312
10313        synchronized (this) {
10314            final long now = SystemClock.uptimeMillis();
10315            final long timeSinceLastIdle = now - mLastIdleTime;
10316            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10317            mLastIdleTime = now;
10318            mLowRamTimeSinceLastIdle = 0;
10319            if (mLowRamStartTime != 0) {
10320                mLowRamStartTime = now;
10321            }
10322
10323            StringBuilder sb = new StringBuilder(128);
10324            sb.append("Idle maintenance over ");
10325            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10326            sb.append(" low RAM for ");
10327            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10328            Slog.i(TAG, sb.toString());
10329
10330            // If at least 1/3 of our time since the last idle period has been spent
10331            // with RAM low, then we want to kill processes.
10332            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10333
10334            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10335                ProcessRecord proc = mLruProcesses.get(i);
10336                if (proc.notCachedSinceIdle) {
10337                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10338                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10339                        if (doKilling && proc.initialIdlePss != 0
10340                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10341                            proc.kill("idle maint (pss " + proc.lastPss
10342                                    + " from " + proc.initialIdlePss + ")", true);
10343                        }
10344                    }
10345                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10346                    proc.notCachedSinceIdle = true;
10347                    proc.initialIdlePss = 0;
10348                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10349                            isSleeping(), now);
10350                }
10351            }
10352
10353            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10354            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10355        }
10356    }
10357
10358    private void retrieveSettings() {
10359        final ContentResolver resolver = mContext.getContentResolver();
10360        String debugApp = Settings.Global.getString(
10361            resolver, Settings.Global.DEBUG_APP);
10362        boolean waitForDebugger = Settings.Global.getInt(
10363            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10364        boolean alwaysFinishActivities = Settings.Global.getInt(
10365            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10366        boolean forceRtl = Settings.Global.getInt(
10367                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10368        // Transfer any global setting for forcing RTL layout, into a System Property
10369        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10370
10371        Configuration configuration = new Configuration();
10372        Settings.System.getConfiguration(resolver, configuration);
10373        if (forceRtl) {
10374            // This will take care of setting the correct layout direction flags
10375            configuration.setLayoutDirection(configuration.locale);
10376        }
10377
10378        synchronized (this) {
10379            mDebugApp = mOrigDebugApp = debugApp;
10380            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10381            mAlwaysFinishActivities = alwaysFinishActivities;
10382            // This happens before any activities are started, so we can
10383            // change mConfiguration in-place.
10384            updateConfigurationLocked(configuration, null, false, true);
10385            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10386        }
10387    }
10388
10389    public boolean testIsSystemReady() {
10390        // no need to synchronize(this) just to read & return the value
10391        return mSystemReady;
10392    }
10393
10394    private static File getCalledPreBootReceiversFile() {
10395        File dataDir = Environment.getDataDirectory();
10396        File systemDir = new File(dataDir, "system");
10397        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10398        return fname;
10399    }
10400
10401    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10402        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10403        File file = getCalledPreBootReceiversFile();
10404        FileInputStream fis = null;
10405        try {
10406            fis = new FileInputStream(file);
10407            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10408            int fvers = dis.readInt();
10409            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10410                String vers = dis.readUTF();
10411                String codename = dis.readUTF();
10412                String build = dis.readUTF();
10413                if (android.os.Build.VERSION.RELEASE.equals(vers)
10414                        && android.os.Build.VERSION.CODENAME.equals(codename)
10415                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10416                    int num = dis.readInt();
10417                    while (num > 0) {
10418                        num--;
10419                        String pkg = dis.readUTF();
10420                        String cls = dis.readUTF();
10421                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10422                    }
10423                }
10424            }
10425        } catch (FileNotFoundException e) {
10426        } catch (IOException e) {
10427            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10428        } finally {
10429            if (fis != null) {
10430                try {
10431                    fis.close();
10432                } catch (IOException e) {
10433                }
10434            }
10435        }
10436        return lastDoneReceivers;
10437    }
10438
10439    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10440        File file = getCalledPreBootReceiversFile();
10441        FileOutputStream fos = null;
10442        DataOutputStream dos = null;
10443        try {
10444            fos = new FileOutputStream(file);
10445            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10446            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10447            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10448            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10449            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10450            dos.writeInt(list.size());
10451            for (int i=0; i<list.size(); i++) {
10452                dos.writeUTF(list.get(i).getPackageName());
10453                dos.writeUTF(list.get(i).getClassName());
10454            }
10455        } catch (IOException e) {
10456            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10457            file.delete();
10458        } finally {
10459            FileUtils.sync(fos);
10460            if (dos != null) {
10461                try {
10462                    dos.close();
10463                } catch (IOException e) {
10464                    // TODO Auto-generated catch block
10465                    e.printStackTrace();
10466                }
10467            }
10468        }
10469    }
10470
10471    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10472            ArrayList<ComponentName> doneReceivers, int userId) {
10473        boolean waitingUpdate = false;
10474        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10475        List<ResolveInfo> ris = null;
10476        try {
10477            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10478                    intent, null, 0, userId);
10479        } catch (RemoteException e) {
10480        }
10481        if (ris != null) {
10482            for (int i=ris.size()-1; i>=0; i--) {
10483                if ((ris.get(i).activityInfo.applicationInfo.flags
10484                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10485                    ris.remove(i);
10486                }
10487            }
10488            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10489
10490            // For User 0, load the version number. When delivering to a new user, deliver
10491            // to all receivers.
10492            if (userId == UserHandle.USER_OWNER) {
10493                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10494                for (int i=0; i<ris.size(); i++) {
10495                    ActivityInfo ai = ris.get(i).activityInfo;
10496                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10497                    if (lastDoneReceivers.contains(comp)) {
10498                        // We already did the pre boot receiver for this app with the current
10499                        // platform version, so don't do it again...
10500                        ris.remove(i);
10501                        i--;
10502                        // ...however, do keep it as one that has been done, so we don't
10503                        // forget about it when rewriting the file of last done receivers.
10504                        doneReceivers.add(comp);
10505                    }
10506                }
10507            }
10508
10509            // If primary user, send broadcast to all available users, else just to userId
10510            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10511                    : new int[] { userId };
10512            for (int i = 0; i < ris.size(); i++) {
10513                ActivityInfo ai = ris.get(i).activityInfo;
10514                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10515                doneReceivers.add(comp);
10516                intent.setComponent(comp);
10517                for (int j=0; j<users.length; j++) {
10518                    IIntentReceiver finisher = null;
10519                    // On last receiver and user, set up a completion callback
10520                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10521                        finisher = new IIntentReceiver.Stub() {
10522                            public void performReceive(Intent intent, int resultCode,
10523                                    String data, Bundle extras, boolean ordered,
10524                                    boolean sticky, int sendingUser) {
10525                                // The raw IIntentReceiver interface is called
10526                                // with the AM lock held, so redispatch to
10527                                // execute our code without the lock.
10528                                mHandler.post(onFinishCallback);
10529                            }
10530                        };
10531                    }
10532                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10533                            + " for user " + users[j]);
10534                    broadcastIntentLocked(null, null, intent, null, finisher,
10535                            0, null, null, null, AppOpsManager.OP_NONE,
10536                            true, false, MY_PID, Process.SYSTEM_UID,
10537                            users[j]);
10538                    if (finisher != null) {
10539                        waitingUpdate = true;
10540                    }
10541                }
10542            }
10543        }
10544
10545        return waitingUpdate;
10546    }
10547
10548    public void systemReady(final Runnable goingCallback) {
10549        synchronized(this) {
10550            if (mSystemReady) {
10551                // If we're done calling all the receivers, run the next "boot phase" passed in
10552                // by the SystemServer
10553                if (goingCallback != null) {
10554                    goingCallback.run();
10555                }
10556                return;
10557            }
10558
10559            // Make sure we have the current profile info, since it is needed for
10560            // security checks.
10561            updateCurrentProfileIdsLocked();
10562
10563            if (mRecentTasks == null) {
10564                mRecentTasks = mTaskPersister.restoreTasksLocked();
10565                if (!mRecentTasks.isEmpty()) {
10566                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10567                }
10568                mTaskPersister.startPersisting();
10569            }
10570
10571            // Check to see if there are any update receivers to run.
10572            if (!mDidUpdate) {
10573                if (mWaitingUpdate) {
10574                    return;
10575                }
10576                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10577                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10578                    public void run() {
10579                        synchronized (ActivityManagerService.this) {
10580                            mDidUpdate = true;
10581                        }
10582                        writeLastDonePreBootReceivers(doneReceivers);
10583                        showBootMessage(mContext.getText(
10584                                R.string.android_upgrading_complete),
10585                                false);
10586                        systemReady(goingCallback);
10587                    }
10588                }, doneReceivers, UserHandle.USER_OWNER);
10589
10590                if (mWaitingUpdate) {
10591                    return;
10592                }
10593                mDidUpdate = true;
10594            }
10595
10596            mAppOpsService.systemReady();
10597            mSystemReady = true;
10598        }
10599
10600        ArrayList<ProcessRecord> procsToKill = null;
10601        synchronized(mPidsSelfLocked) {
10602            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10603                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10604                if (!isAllowedWhileBooting(proc.info)){
10605                    if (procsToKill == null) {
10606                        procsToKill = new ArrayList<ProcessRecord>();
10607                    }
10608                    procsToKill.add(proc);
10609                }
10610            }
10611        }
10612
10613        synchronized(this) {
10614            if (procsToKill != null) {
10615                for (int i=procsToKill.size()-1; i>=0; i--) {
10616                    ProcessRecord proc = procsToKill.get(i);
10617                    Slog.i(TAG, "Removing system update proc: " + proc);
10618                    removeProcessLocked(proc, true, false, "system update done");
10619                }
10620            }
10621
10622            // Now that we have cleaned up any update processes, we
10623            // are ready to start launching real processes and know that
10624            // we won't trample on them any more.
10625            mProcessesReady = true;
10626        }
10627
10628        Slog.i(TAG, "System now ready");
10629        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10630            SystemClock.uptimeMillis());
10631
10632        synchronized(this) {
10633            // Make sure we have no pre-ready processes sitting around.
10634
10635            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10636                ResolveInfo ri = mContext.getPackageManager()
10637                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10638                                STOCK_PM_FLAGS);
10639                CharSequence errorMsg = null;
10640                if (ri != null) {
10641                    ActivityInfo ai = ri.activityInfo;
10642                    ApplicationInfo app = ai.applicationInfo;
10643                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10644                        mTopAction = Intent.ACTION_FACTORY_TEST;
10645                        mTopData = null;
10646                        mTopComponent = new ComponentName(app.packageName,
10647                                ai.name);
10648                    } else {
10649                        errorMsg = mContext.getResources().getText(
10650                                com.android.internal.R.string.factorytest_not_system);
10651                    }
10652                } else {
10653                    errorMsg = mContext.getResources().getText(
10654                            com.android.internal.R.string.factorytest_no_action);
10655                }
10656                if (errorMsg != null) {
10657                    mTopAction = null;
10658                    mTopData = null;
10659                    mTopComponent = null;
10660                    Message msg = Message.obtain();
10661                    msg.what = SHOW_FACTORY_ERROR_MSG;
10662                    msg.getData().putCharSequence("msg", errorMsg);
10663                    mHandler.sendMessage(msg);
10664                }
10665            }
10666        }
10667
10668        retrieveSettings();
10669
10670        synchronized (this) {
10671            readGrantedUriPermissionsLocked();
10672        }
10673
10674        if (goingCallback != null) goingCallback.run();
10675
10676        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10677                Integer.toString(mCurrentUserId), mCurrentUserId);
10678        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10679                Integer.toString(mCurrentUserId), mCurrentUserId);
10680        mSystemServiceManager.startUser(mCurrentUserId);
10681
10682        synchronized (this) {
10683            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10684                try {
10685                    List apps = AppGlobals.getPackageManager().
10686                        getPersistentApplications(STOCK_PM_FLAGS);
10687                    if (apps != null) {
10688                        int N = apps.size();
10689                        int i;
10690                        for (i=0; i<N; i++) {
10691                            ApplicationInfo info
10692                                = (ApplicationInfo)apps.get(i);
10693                            if (info != null &&
10694                                    !info.packageName.equals("android")) {
10695                                addAppLocked(info, false, null /* ABI override */);
10696                            }
10697                        }
10698                    }
10699                } catch (RemoteException ex) {
10700                    // pm is in same process, this will never happen.
10701                }
10702            }
10703
10704            // Start up initial activity.
10705            mBooting = true;
10706
10707            try {
10708                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10709                    Message msg = Message.obtain();
10710                    msg.what = SHOW_UID_ERROR_MSG;
10711                    mHandler.sendMessage(msg);
10712                }
10713            } catch (RemoteException e) {
10714            }
10715
10716            long ident = Binder.clearCallingIdentity();
10717            try {
10718                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10719                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10720                        | Intent.FLAG_RECEIVER_FOREGROUND);
10721                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10722                broadcastIntentLocked(null, null, intent,
10723                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10724                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10725                intent = new Intent(Intent.ACTION_USER_STARTING);
10726                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10727                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10728                broadcastIntentLocked(null, null, intent,
10729                        null, new IIntentReceiver.Stub() {
10730                            @Override
10731                            public void performReceive(Intent intent, int resultCode, String data,
10732                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10733                                    throws RemoteException {
10734                            }
10735                        }, 0, null, null,
10736                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10737                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10738            } catch (Throwable t) {
10739                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10740            } finally {
10741                Binder.restoreCallingIdentity(ident);
10742            }
10743            mStackSupervisor.resumeTopActivitiesLocked();
10744            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10745        }
10746    }
10747
10748    private boolean makeAppCrashingLocked(ProcessRecord app,
10749            String shortMsg, String longMsg, String stackTrace) {
10750        app.crashing = true;
10751        app.crashingReport = generateProcessError(app,
10752                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10753        startAppProblemLocked(app);
10754        app.stopFreezingAllLocked();
10755        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10756    }
10757
10758    private void makeAppNotRespondingLocked(ProcessRecord app,
10759            String activity, String shortMsg, String longMsg) {
10760        app.notResponding = true;
10761        app.notRespondingReport = generateProcessError(app,
10762                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10763                activity, shortMsg, longMsg, null);
10764        startAppProblemLocked(app);
10765        app.stopFreezingAllLocked();
10766    }
10767
10768    /**
10769     * Generate a process error record, suitable for attachment to a ProcessRecord.
10770     *
10771     * @param app The ProcessRecord in which the error occurred.
10772     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10773     *                      ActivityManager.AppErrorStateInfo
10774     * @param activity The activity associated with the crash, if known.
10775     * @param shortMsg Short message describing the crash.
10776     * @param longMsg Long message describing the crash.
10777     * @param stackTrace Full crash stack trace, may be null.
10778     *
10779     * @return Returns a fully-formed AppErrorStateInfo record.
10780     */
10781    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10782            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10783        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10784
10785        report.condition = condition;
10786        report.processName = app.processName;
10787        report.pid = app.pid;
10788        report.uid = app.info.uid;
10789        report.tag = activity;
10790        report.shortMsg = shortMsg;
10791        report.longMsg = longMsg;
10792        report.stackTrace = stackTrace;
10793
10794        return report;
10795    }
10796
10797    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10798        synchronized (this) {
10799            app.crashing = false;
10800            app.crashingReport = null;
10801            app.notResponding = false;
10802            app.notRespondingReport = null;
10803            if (app.anrDialog == fromDialog) {
10804                app.anrDialog = null;
10805            }
10806            if (app.waitDialog == fromDialog) {
10807                app.waitDialog = null;
10808            }
10809            if (app.pid > 0 && app.pid != MY_PID) {
10810                handleAppCrashLocked(app, null, null, null);
10811                app.kill("user request after error", true);
10812            }
10813        }
10814    }
10815
10816    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10817            String stackTrace) {
10818        long now = SystemClock.uptimeMillis();
10819
10820        Long crashTime;
10821        if (!app.isolated) {
10822            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10823        } else {
10824            crashTime = null;
10825        }
10826        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10827            // This process loses!
10828            Slog.w(TAG, "Process " + app.info.processName
10829                    + " has crashed too many times: killing!");
10830            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10831                    app.userId, app.info.processName, app.uid);
10832            mStackSupervisor.handleAppCrashLocked(app);
10833            if (!app.persistent) {
10834                // We don't want to start this process again until the user
10835                // explicitly does so...  but for persistent process, we really
10836                // need to keep it running.  If a persistent process is actually
10837                // repeatedly crashing, then badness for everyone.
10838                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10839                        app.info.processName);
10840                if (!app.isolated) {
10841                    // XXX We don't have a way to mark isolated processes
10842                    // as bad, since they don't have a peristent identity.
10843                    mBadProcesses.put(app.info.processName, app.uid,
10844                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10845                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10846                }
10847                app.bad = true;
10848                app.removed = true;
10849                // Don't let services in this process be restarted and potentially
10850                // annoy the user repeatedly.  Unless it is persistent, since those
10851                // processes run critical code.
10852                removeProcessLocked(app, false, false, "crash");
10853                mStackSupervisor.resumeTopActivitiesLocked();
10854                return false;
10855            }
10856            mStackSupervisor.resumeTopActivitiesLocked();
10857        } else {
10858            mStackSupervisor.finishTopRunningActivityLocked(app);
10859        }
10860
10861        // Bump up the crash count of any services currently running in the proc.
10862        for (int i=app.services.size()-1; i>=0; i--) {
10863            // Any services running in the application need to be placed
10864            // back in the pending list.
10865            ServiceRecord sr = app.services.valueAt(i);
10866            sr.crashCount++;
10867        }
10868
10869        // If the crashing process is what we consider to be the "home process" and it has been
10870        // replaced by a third-party app, clear the package preferred activities from packages
10871        // with a home activity running in the process to prevent a repeatedly crashing app
10872        // from blocking the user to manually clear the list.
10873        final ArrayList<ActivityRecord> activities = app.activities;
10874        if (app == mHomeProcess && activities.size() > 0
10875                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10876            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10877                final ActivityRecord r = activities.get(activityNdx);
10878                if (r.isHomeActivity()) {
10879                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10880                    try {
10881                        ActivityThread.getPackageManager()
10882                                .clearPackagePreferredActivities(r.packageName);
10883                    } catch (RemoteException c) {
10884                        // pm is in same process, this will never happen.
10885                    }
10886                }
10887            }
10888        }
10889
10890        if (!app.isolated) {
10891            // XXX Can't keep track of crash times for isolated processes,
10892            // because they don't have a perisistent identity.
10893            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10894        }
10895
10896        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10897        return true;
10898    }
10899
10900    void startAppProblemLocked(ProcessRecord app) {
10901        // If this app is not running under the current user, then we
10902        // can't give it a report button because that would require
10903        // launching the report UI under a different user.
10904        app.errorReportReceiver = null;
10905
10906        for (int userId : mCurrentProfileIds) {
10907            if (app.userId == userId) {
10908                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10909                        mContext, app.info.packageName, app.info.flags);
10910            }
10911        }
10912        skipCurrentReceiverLocked(app);
10913    }
10914
10915    void skipCurrentReceiverLocked(ProcessRecord app) {
10916        for (BroadcastQueue queue : mBroadcastQueues) {
10917            queue.skipCurrentReceiverLocked(app);
10918        }
10919    }
10920
10921    /**
10922     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10923     * The application process will exit immediately after this call returns.
10924     * @param app object of the crashing app, null for the system server
10925     * @param crashInfo describing the exception
10926     */
10927    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10928        ProcessRecord r = findAppProcess(app, "Crash");
10929        final String processName = app == null ? "system_server"
10930                : (r == null ? "unknown" : r.processName);
10931
10932        handleApplicationCrashInner("crash", r, processName, crashInfo);
10933    }
10934
10935    /* Native crash reporting uses this inner version because it needs to be somewhat
10936     * decoupled from the AM-managed cleanup lifecycle
10937     */
10938    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10939            ApplicationErrorReport.CrashInfo crashInfo) {
10940        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10941                UserHandle.getUserId(Binder.getCallingUid()), processName,
10942                r == null ? -1 : r.info.flags,
10943                crashInfo.exceptionClassName,
10944                crashInfo.exceptionMessage,
10945                crashInfo.throwFileName,
10946                crashInfo.throwLineNumber);
10947
10948        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10949
10950        crashApplication(r, crashInfo);
10951    }
10952
10953    public void handleApplicationStrictModeViolation(
10954            IBinder app,
10955            int violationMask,
10956            StrictMode.ViolationInfo info) {
10957        ProcessRecord r = findAppProcess(app, "StrictMode");
10958        if (r == null) {
10959            return;
10960        }
10961
10962        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10963            Integer stackFingerprint = info.hashCode();
10964            boolean logIt = true;
10965            synchronized (mAlreadyLoggedViolatedStacks) {
10966                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10967                    logIt = false;
10968                    // TODO: sub-sample into EventLog for these, with
10969                    // the info.durationMillis?  Then we'd get
10970                    // the relative pain numbers, without logging all
10971                    // the stack traces repeatedly.  We'd want to do
10972                    // likewise in the client code, which also does
10973                    // dup suppression, before the Binder call.
10974                } else {
10975                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10976                        mAlreadyLoggedViolatedStacks.clear();
10977                    }
10978                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10979                }
10980            }
10981            if (logIt) {
10982                logStrictModeViolationToDropBox(r, info);
10983            }
10984        }
10985
10986        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10987            AppErrorResult result = new AppErrorResult();
10988            synchronized (this) {
10989                final long origId = Binder.clearCallingIdentity();
10990
10991                Message msg = Message.obtain();
10992                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10993                HashMap<String, Object> data = new HashMap<String, Object>();
10994                data.put("result", result);
10995                data.put("app", r);
10996                data.put("violationMask", violationMask);
10997                data.put("info", info);
10998                msg.obj = data;
10999                mHandler.sendMessage(msg);
11000
11001                Binder.restoreCallingIdentity(origId);
11002            }
11003            int res = result.get();
11004            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11005        }
11006    }
11007
11008    // Depending on the policy in effect, there could be a bunch of
11009    // these in quick succession so we try to batch these together to
11010    // minimize disk writes, number of dropbox entries, and maximize
11011    // compression, by having more fewer, larger records.
11012    private void logStrictModeViolationToDropBox(
11013            ProcessRecord process,
11014            StrictMode.ViolationInfo info) {
11015        if (info == null) {
11016            return;
11017        }
11018        final boolean isSystemApp = process == null ||
11019                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11020                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11021        final String processName = process == null ? "unknown" : process.processName;
11022        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11023        final DropBoxManager dbox = (DropBoxManager)
11024                mContext.getSystemService(Context.DROPBOX_SERVICE);
11025
11026        // Exit early if the dropbox isn't configured to accept this report type.
11027        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11028
11029        boolean bufferWasEmpty;
11030        boolean needsFlush;
11031        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11032        synchronized (sb) {
11033            bufferWasEmpty = sb.length() == 0;
11034            appendDropBoxProcessHeaders(process, processName, sb);
11035            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11036            sb.append("System-App: ").append(isSystemApp).append("\n");
11037            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11038            if (info.violationNumThisLoop != 0) {
11039                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11040            }
11041            if (info.numAnimationsRunning != 0) {
11042                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11043            }
11044            if (info.broadcastIntentAction != null) {
11045                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11046            }
11047            if (info.durationMillis != -1) {
11048                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11049            }
11050            if (info.numInstances != -1) {
11051                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11052            }
11053            if (info.tags != null) {
11054                for (String tag : info.tags) {
11055                    sb.append("Span-Tag: ").append(tag).append("\n");
11056                }
11057            }
11058            sb.append("\n");
11059            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11060                sb.append(info.crashInfo.stackTrace);
11061            }
11062            sb.append("\n");
11063
11064            // Only buffer up to ~64k.  Various logging bits truncate
11065            // things at 128k.
11066            needsFlush = (sb.length() > 64 * 1024);
11067        }
11068
11069        // Flush immediately if the buffer's grown too large, or this
11070        // is a non-system app.  Non-system apps are isolated with a
11071        // different tag & policy and not batched.
11072        //
11073        // Batching is useful during internal testing with
11074        // StrictMode settings turned up high.  Without batching,
11075        // thousands of separate files could be created on boot.
11076        if (!isSystemApp || needsFlush) {
11077            new Thread("Error dump: " + dropboxTag) {
11078                @Override
11079                public void run() {
11080                    String report;
11081                    synchronized (sb) {
11082                        report = sb.toString();
11083                        sb.delete(0, sb.length());
11084                        sb.trimToSize();
11085                    }
11086                    if (report.length() != 0) {
11087                        dbox.addText(dropboxTag, report);
11088                    }
11089                }
11090            }.start();
11091            return;
11092        }
11093
11094        // System app batching:
11095        if (!bufferWasEmpty) {
11096            // An existing dropbox-writing thread is outstanding, so
11097            // we don't need to start it up.  The existing thread will
11098            // catch the buffer appends we just did.
11099            return;
11100        }
11101
11102        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11103        // (After this point, we shouldn't access AMS internal data structures.)
11104        new Thread("Error dump: " + dropboxTag) {
11105            @Override
11106            public void run() {
11107                // 5 second sleep to let stacks arrive and be batched together
11108                try {
11109                    Thread.sleep(5000);  // 5 seconds
11110                } catch (InterruptedException e) {}
11111
11112                String errorReport;
11113                synchronized (mStrictModeBuffer) {
11114                    errorReport = mStrictModeBuffer.toString();
11115                    if (errorReport.length() == 0) {
11116                        return;
11117                    }
11118                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11119                    mStrictModeBuffer.trimToSize();
11120                }
11121                dbox.addText(dropboxTag, errorReport);
11122            }
11123        }.start();
11124    }
11125
11126    /**
11127     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11128     * @param app object of the crashing app, null for the system server
11129     * @param tag reported by the caller
11130     * @param crashInfo describing the context of the error
11131     * @return true if the process should exit immediately (WTF is fatal)
11132     */
11133    public boolean handleApplicationWtf(IBinder app, String tag,
11134            ApplicationErrorReport.CrashInfo crashInfo) {
11135        ProcessRecord r = findAppProcess(app, "WTF");
11136        final String processName = app == null ? "system_server"
11137                : (r == null ? "unknown" : r.processName);
11138
11139        EventLog.writeEvent(EventLogTags.AM_WTF,
11140                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11141                processName,
11142                r == null ? -1 : r.info.flags,
11143                tag, crashInfo.exceptionMessage);
11144
11145        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11146
11147        if (r != null && r.pid != Process.myPid() &&
11148                Settings.Global.getInt(mContext.getContentResolver(),
11149                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11150            crashApplication(r, crashInfo);
11151            return true;
11152        } else {
11153            return false;
11154        }
11155    }
11156
11157    /**
11158     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11159     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11160     */
11161    private ProcessRecord findAppProcess(IBinder app, String reason) {
11162        if (app == null) {
11163            return null;
11164        }
11165
11166        synchronized (this) {
11167            final int NP = mProcessNames.getMap().size();
11168            for (int ip=0; ip<NP; ip++) {
11169                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11170                final int NA = apps.size();
11171                for (int ia=0; ia<NA; ia++) {
11172                    ProcessRecord p = apps.valueAt(ia);
11173                    if (p.thread != null && p.thread.asBinder() == app) {
11174                        return p;
11175                    }
11176                }
11177            }
11178
11179            Slog.w(TAG, "Can't find mystery application for " + reason
11180                    + " from pid=" + Binder.getCallingPid()
11181                    + " uid=" + Binder.getCallingUid() + ": " + app);
11182            return null;
11183        }
11184    }
11185
11186    /**
11187     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11188     * to append various headers to the dropbox log text.
11189     */
11190    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11191            StringBuilder sb) {
11192        // Watchdog thread ends up invoking this function (with
11193        // a null ProcessRecord) to add the stack file to dropbox.
11194        // Do not acquire a lock on this (am) in such cases, as it
11195        // could cause a potential deadlock, if and when watchdog
11196        // is invoked due to unavailability of lock on am and it
11197        // would prevent watchdog from killing system_server.
11198        if (process == null) {
11199            sb.append("Process: ").append(processName).append("\n");
11200            return;
11201        }
11202        // Note: ProcessRecord 'process' is guarded by the service
11203        // instance.  (notably process.pkgList, which could otherwise change
11204        // concurrently during execution of this method)
11205        synchronized (this) {
11206            sb.append("Process: ").append(processName).append("\n");
11207            int flags = process.info.flags;
11208            IPackageManager pm = AppGlobals.getPackageManager();
11209            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11210            for (int ip=0; ip<process.pkgList.size(); ip++) {
11211                String pkg = process.pkgList.keyAt(ip);
11212                sb.append("Package: ").append(pkg);
11213                try {
11214                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11215                    if (pi != null) {
11216                        sb.append(" v").append(pi.versionCode);
11217                        if (pi.versionName != null) {
11218                            sb.append(" (").append(pi.versionName).append(")");
11219                        }
11220                    }
11221                } catch (RemoteException e) {
11222                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11223                }
11224                sb.append("\n");
11225            }
11226        }
11227    }
11228
11229    private static String processClass(ProcessRecord process) {
11230        if (process == null || process.pid == MY_PID) {
11231            return "system_server";
11232        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11233            return "system_app";
11234        } else {
11235            return "data_app";
11236        }
11237    }
11238
11239    /**
11240     * Write a description of an error (crash, WTF, ANR) to the drop box.
11241     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11242     * @param process which caused the error, null means the system server
11243     * @param activity which triggered the error, null if unknown
11244     * @param parent activity related to the error, null if unknown
11245     * @param subject line related to the error, null if absent
11246     * @param report in long form describing the error, null if absent
11247     * @param logFile to include in the report, null if none
11248     * @param crashInfo giving an application stack trace, null if absent
11249     */
11250    public void addErrorToDropBox(String eventType,
11251            ProcessRecord process, String processName, ActivityRecord activity,
11252            ActivityRecord parent, String subject,
11253            final String report, final File logFile,
11254            final ApplicationErrorReport.CrashInfo crashInfo) {
11255        // NOTE -- this must never acquire the ActivityManagerService lock,
11256        // otherwise the watchdog may be prevented from resetting the system.
11257
11258        final String dropboxTag = processClass(process) + "_" + eventType;
11259        final DropBoxManager dbox = (DropBoxManager)
11260                mContext.getSystemService(Context.DROPBOX_SERVICE);
11261
11262        // Exit early if the dropbox isn't configured to accept this report type.
11263        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11264
11265        final StringBuilder sb = new StringBuilder(1024);
11266        appendDropBoxProcessHeaders(process, processName, sb);
11267        if (activity != null) {
11268            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11269        }
11270        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11271            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11272        }
11273        if (parent != null && parent != activity) {
11274            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11275        }
11276        if (subject != null) {
11277            sb.append("Subject: ").append(subject).append("\n");
11278        }
11279        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11280        if (Debug.isDebuggerConnected()) {
11281            sb.append("Debugger: Connected\n");
11282        }
11283        sb.append("\n");
11284
11285        // Do the rest in a worker thread to avoid blocking the caller on I/O
11286        // (After this point, we shouldn't access AMS internal data structures.)
11287        Thread worker = new Thread("Error dump: " + dropboxTag) {
11288            @Override
11289            public void run() {
11290                if (report != null) {
11291                    sb.append(report);
11292                }
11293                if (logFile != null) {
11294                    try {
11295                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11296                                    "\n\n[[TRUNCATED]]"));
11297                    } catch (IOException e) {
11298                        Slog.e(TAG, "Error reading " + logFile, e);
11299                    }
11300                }
11301                if (crashInfo != null && crashInfo.stackTrace != null) {
11302                    sb.append(crashInfo.stackTrace);
11303                }
11304
11305                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11306                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11307                if (lines > 0) {
11308                    sb.append("\n");
11309
11310                    // Merge several logcat streams, and take the last N lines
11311                    InputStreamReader input = null;
11312                    try {
11313                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11314                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11315                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11316
11317                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11318                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11319                        input = new InputStreamReader(logcat.getInputStream());
11320
11321                        int num;
11322                        char[] buf = new char[8192];
11323                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11324                    } catch (IOException e) {
11325                        Slog.e(TAG, "Error running logcat", e);
11326                    } finally {
11327                        if (input != null) try { input.close(); } catch (IOException e) {}
11328                    }
11329                }
11330
11331                dbox.addText(dropboxTag, sb.toString());
11332            }
11333        };
11334
11335        if (process == null) {
11336            // If process is null, we are being called from some internal code
11337            // and may be about to die -- run this synchronously.
11338            worker.run();
11339        } else {
11340            worker.start();
11341        }
11342    }
11343
11344    /**
11345     * Bring up the "unexpected error" dialog box for a crashing app.
11346     * Deal with edge cases (intercepts from instrumented applications,
11347     * ActivityController, error intent receivers, that sort of thing).
11348     * @param r the application crashing
11349     * @param crashInfo describing the failure
11350     */
11351    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11352        long timeMillis = System.currentTimeMillis();
11353        String shortMsg = crashInfo.exceptionClassName;
11354        String longMsg = crashInfo.exceptionMessage;
11355        String stackTrace = crashInfo.stackTrace;
11356        if (shortMsg != null && longMsg != null) {
11357            longMsg = shortMsg + ": " + longMsg;
11358        } else if (shortMsg != null) {
11359            longMsg = shortMsg;
11360        }
11361
11362        AppErrorResult result = new AppErrorResult();
11363        synchronized (this) {
11364            if (mController != null) {
11365                try {
11366                    String name = r != null ? r.processName : null;
11367                    int pid = r != null ? r.pid : Binder.getCallingPid();
11368                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11369                    if (!mController.appCrashed(name, pid,
11370                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11371                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11372                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11373                            Slog.w(TAG, "Skip killing native crashed app " + name
11374                                    + "(" + pid + ") during testing");
11375                        } else {
11376                            Slog.w(TAG, "Force-killing crashed app " + name
11377                                    + " at watcher's request");
11378                            if (r != null) {
11379                                r.kill("crash", true);
11380                            } else {
11381                                // Huh.
11382                                Process.killProcess(pid);
11383                                Process.killProcessGroup(uid, pid);
11384                            }
11385                        }
11386                        return;
11387                    }
11388                } catch (RemoteException e) {
11389                    mController = null;
11390                    Watchdog.getInstance().setActivityController(null);
11391                }
11392            }
11393
11394            final long origId = Binder.clearCallingIdentity();
11395
11396            // If this process is running instrumentation, finish it.
11397            if (r != null && r.instrumentationClass != null) {
11398                Slog.w(TAG, "Error in app " + r.processName
11399                      + " running instrumentation " + r.instrumentationClass + ":");
11400                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11401                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11402                Bundle info = new Bundle();
11403                info.putString("shortMsg", shortMsg);
11404                info.putString("longMsg", longMsg);
11405                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11406                Binder.restoreCallingIdentity(origId);
11407                return;
11408            }
11409
11410            // If we can't identify the process or it's already exceeded its crash quota,
11411            // quit right away without showing a crash dialog.
11412            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11413                Binder.restoreCallingIdentity(origId);
11414                return;
11415            }
11416
11417            Message msg = Message.obtain();
11418            msg.what = SHOW_ERROR_MSG;
11419            HashMap data = new HashMap();
11420            data.put("result", result);
11421            data.put("app", r);
11422            msg.obj = data;
11423            mHandler.sendMessage(msg);
11424
11425            Binder.restoreCallingIdentity(origId);
11426        }
11427
11428        int res = result.get();
11429
11430        Intent appErrorIntent = null;
11431        synchronized (this) {
11432            if (r != null && !r.isolated) {
11433                // XXX Can't keep track of crash time for isolated processes,
11434                // since they don't have a persistent identity.
11435                mProcessCrashTimes.put(r.info.processName, r.uid,
11436                        SystemClock.uptimeMillis());
11437            }
11438            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11439                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11440            }
11441        }
11442
11443        if (appErrorIntent != null) {
11444            try {
11445                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11446            } catch (ActivityNotFoundException e) {
11447                Slog.w(TAG, "bug report receiver dissappeared", e);
11448            }
11449        }
11450    }
11451
11452    Intent createAppErrorIntentLocked(ProcessRecord r,
11453            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11454        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11455        if (report == null) {
11456            return null;
11457        }
11458        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11459        result.setComponent(r.errorReportReceiver);
11460        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11461        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11462        return result;
11463    }
11464
11465    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11466            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11467        if (r.errorReportReceiver == null) {
11468            return null;
11469        }
11470
11471        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11472            return null;
11473        }
11474
11475        ApplicationErrorReport report = new ApplicationErrorReport();
11476        report.packageName = r.info.packageName;
11477        report.installerPackageName = r.errorReportReceiver.getPackageName();
11478        report.processName = r.processName;
11479        report.time = timeMillis;
11480        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11481
11482        if (r.crashing || r.forceCrashReport) {
11483            report.type = ApplicationErrorReport.TYPE_CRASH;
11484            report.crashInfo = crashInfo;
11485        } else if (r.notResponding) {
11486            report.type = ApplicationErrorReport.TYPE_ANR;
11487            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11488
11489            report.anrInfo.activity = r.notRespondingReport.tag;
11490            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11491            report.anrInfo.info = r.notRespondingReport.longMsg;
11492        }
11493
11494        return report;
11495    }
11496
11497    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11498        enforceNotIsolatedCaller("getProcessesInErrorState");
11499        // assume our apps are happy - lazy create the list
11500        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11501
11502        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11503                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11504        int userId = UserHandle.getUserId(Binder.getCallingUid());
11505
11506        synchronized (this) {
11507
11508            // iterate across all processes
11509            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11510                ProcessRecord app = mLruProcesses.get(i);
11511                if (!allUsers && app.userId != userId) {
11512                    continue;
11513                }
11514                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11515                    // This one's in trouble, so we'll generate a report for it
11516                    // crashes are higher priority (in case there's a crash *and* an anr)
11517                    ActivityManager.ProcessErrorStateInfo report = null;
11518                    if (app.crashing) {
11519                        report = app.crashingReport;
11520                    } else if (app.notResponding) {
11521                        report = app.notRespondingReport;
11522                    }
11523
11524                    if (report != null) {
11525                        if (errList == null) {
11526                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11527                        }
11528                        errList.add(report);
11529                    } else {
11530                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11531                                " crashing = " + app.crashing +
11532                                " notResponding = " + app.notResponding);
11533                    }
11534                }
11535            }
11536        }
11537
11538        return errList;
11539    }
11540
11541    static int procStateToImportance(int procState, int memAdj,
11542            ActivityManager.RunningAppProcessInfo currApp) {
11543        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11544        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11545            currApp.lru = memAdj;
11546        } else {
11547            currApp.lru = 0;
11548        }
11549        return imp;
11550    }
11551
11552    private void fillInProcMemInfo(ProcessRecord app,
11553            ActivityManager.RunningAppProcessInfo outInfo) {
11554        outInfo.pid = app.pid;
11555        outInfo.uid = app.info.uid;
11556        if (mHeavyWeightProcess == app) {
11557            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11558        }
11559        if (app.persistent) {
11560            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11561        }
11562        if (app.activities.size() > 0) {
11563            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11564        }
11565        outInfo.lastTrimLevel = app.trimMemoryLevel;
11566        int adj = app.curAdj;
11567        int procState = app.curProcState;
11568        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11569        outInfo.importanceReasonCode = app.adjTypeCode;
11570        outInfo.processState = app.curProcState;
11571    }
11572
11573    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11574        enforceNotIsolatedCaller("getRunningAppProcesses");
11575        // Lazy instantiation of list
11576        List<ActivityManager.RunningAppProcessInfo> runList = null;
11577        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11578                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11579        int userId = UserHandle.getUserId(Binder.getCallingUid());
11580        synchronized (this) {
11581            // Iterate across all processes
11582            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11583                ProcessRecord app = mLruProcesses.get(i);
11584                if (!allUsers && app.userId != userId) {
11585                    continue;
11586                }
11587                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11588                    // Generate process state info for running application
11589                    ActivityManager.RunningAppProcessInfo currApp =
11590                        new ActivityManager.RunningAppProcessInfo(app.processName,
11591                                app.pid, app.getPackageList());
11592                    fillInProcMemInfo(app, currApp);
11593                    if (app.adjSource instanceof ProcessRecord) {
11594                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11595                        currApp.importanceReasonImportance =
11596                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11597                                        app.adjSourceProcState);
11598                    } else if (app.adjSource instanceof ActivityRecord) {
11599                        ActivityRecord r = (ActivityRecord)app.adjSource;
11600                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11601                    }
11602                    if (app.adjTarget instanceof ComponentName) {
11603                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11604                    }
11605                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11606                    //        + " lru=" + currApp.lru);
11607                    if (runList == null) {
11608                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11609                    }
11610                    runList.add(currApp);
11611                }
11612            }
11613        }
11614        return runList;
11615    }
11616
11617    public List<ApplicationInfo> getRunningExternalApplications() {
11618        enforceNotIsolatedCaller("getRunningExternalApplications");
11619        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11620        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11621        if (runningApps != null && runningApps.size() > 0) {
11622            Set<String> extList = new HashSet<String>();
11623            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11624                if (app.pkgList != null) {
11625                    for (String pkg : app.pkgList) {
11626                        extList.add(pkg);
11627                    }
11628                }
11629            }
11630            IPackageManager pm = AppGlobals.getPackageManager();
11631            for (String pkg : extList) {
11632                try {
11633                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11634                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11635                        retList.add(info);
11636                    }
11637                } catch (RemoteException e) {
11638                }
11639            }
11640        }
11641        return retList;
11642    }
11643
11644    @Override
11645    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11646        enforceNotIsolatedCaller("getMyMemoryState");
11647        synchronized (this) {
11648            ProcessRecord proc;
11649            synchronized (mPidsSelfLocked) {
11650                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11651            }
11652            fillInProcMemInfo(proc, outInfo);
11653        }
11654    }
11655
11656    @Override
11657    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11658        if (checkCallingPermission(android.Manifest.permission.DUMP)
11659                != PackageManager.PERMISSION_GRANTED) {
11660            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11661                    + Binder.getCallingPid()
11662                    + ", uid=" + Binder.getCallingUid()
11663                    + " without permission "
11664                    + android.Manifest.permission.DUMP);
11665            return;
11666        }
11667
11668        boolean dumpAll = false;
11669        boolean dumpClient = false;
11670        String dumpPackage = null;
11671
11672        int opti = 0;
11673        while (opti < args.length) {
11674            String opt = args[opti];
11675            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11676                break;
11677            }
11678            opti++;
11679            if ("-a".equals(opt)) {
11680                dumpAll = true;
11681            } else if ("-c".equals(opt)) {
11682                dumpClient = true;
11683            } else if ("-h".equals(opt)) {
11684                pw.println("Activity manager dump options:");
11685                pw.println("  [-a] [-c] [-h] [cmd] ...");
11686                pw.println("  cmd may be one of:");
11687                pw.println("    a[ctivities]: activity stack state");
11688                pw.println("    r[recents]: recent activities state");
11689                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11690                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11691                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11692                pw.println("    o[om]: out of memory management");
11693                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11694                pw.println("    provider [COMP_SPEC]: provider client-side state");
11695                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11696                pw.println("    service [COMP_SPEC]: service client-side state");
11697                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11698                pw.println("    all: dump all activities");
11699                pw.println("    top: dump the top activity");
11700                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11701                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11702                pw.println("    a partial substring in a component name, a");
11703                pw.println("    hex object identifier.");
11704                pw.println("  -a: include all available server state.");
11705                pw.println("  -c: include client state.");
11706                return;
11707            } else {
11708                pw.println("Unknown argument: " + opt + "; use -h for help");
11709            }
11710        }
11711
11712        long origId = Binder.clearCallingIdentity();
11713        boolean more = false;
11714        // Is the caller requesting to dump a particular piece of data?
11715        if (opti < args.length) {
11716            String cmd = args[opti];
11717            opti++;
11718            if ("activities".equals(cmd) || "a".equals(cmd)) {
11719                synchronized (this) {
11720                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11721                }
11722            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11723                synchronized (this) {
11724                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11725                }
11726            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11727                String[] newArgs;
11728                String name;
11729                if (opti >= args.length) {
11730                    name = null;
11731                    newArgs = EMPTY_STRING_ARRAY;
11732                } else {
11733                    name = args[opti];
11734                    opti++;
11735                    newArgs = new String[args.length - opti];
11736                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11737                            args.length - opti);
11738                }
11739                synchronized (this) {
11740                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11741                }
11742            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11743                String[] newArgs;
11744                String name;
11745                if (opti >= args.length) {
11746                    name = null;
11747                    newArgs = EMPTY_STRING_ARRAY;
11748                } else {
11749                    name = args[opti];
11750                    opti++;
11751                    newArgs = new String[args.length - opti];
11752                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11753                            args.length - opti);
11754                }
11755                synchronized (this) {
11756                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11757                }
11758            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11759                String[] newArgs;
11760                String name;
11761                if (opti >= args.length) {
11762                    name = null;
11763                    newArgs = EMPTY_STRING_ARRAY;
11764                } else {
11765                    name = args[opti];
11766                    opti++;
11767                    newArgs = new String[args.length - opti];
11768                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11769                            args.length - opti);
11770                }
11771                synchronized (this) {
11772                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11773                }
11774            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11775                synchronized (this) {
11776                    dumpOomLocked(fd, pw, args, opti, true);
11777                }
11778            } else if ("provider".equals(cmd)) {
11779                String[] newArgs;
11780                String name;
11781                if (opti >= args.length) {
11782                    name = null;
11783                    newArgs = EMPTY_STRING_ARRAY;
11784                } else {
11785                    name = args[opti];
11786                    opti++;
11787                    newArgs = new String[args.length - opti];
11788                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11789                }
11790                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11791                    pw.println("No providers match: " + name);
11792                    pw.println("Use -h for help.");
11793                }
11794            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11795                synchronized (this) {
11796                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11797                }
11798            } else if ("service".equals(cmd)) {
11799                String[] newArgs;
11800                String name;
11801                if (opti >= args.length) {
11802                    name = null;
11803                    newArgs = EMPTY_STRING_ARRAY;
11804                } else {
11805                    name = args[opti];
11806                    opti++;
11807                    newArgs = new String[args.length - opti];
11808                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11809                            args.length - opti);
11810                }
11811                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11812                    pw.println("No services match: " + name);
11813                    pw.println("Use -h for help.");
11814                }
11815            } else if ("package".equals(cmd)) {
11816                String[] newArgs;
11817                if (opti >= args.length) {
11818                    pw.println("package: no package name specified");
11819                    pw.println("Use -h for help.");
11820                } else {
11821                    dumpPackage = args[opti];
11822                    opti++;
11823                    newArgs = new String[args.length - opti];
11824                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11825                            args.length - opti);
11826                    args = newArgs;
11827                    opti = 0;
11828                    more = true;
11829                }
11830            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11831                synchronized (this) {
11832                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11833                }
11834            } else {
11835                // Dumping a single activity?
11836                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11837                    pw.println("Bad activity command, or no activities match: " + cmd);
11838                    pw.println("Use -h for help.");
11839                }
11840            }
11841            if (!more) {
11842                Binder.restoreCallingIdentity(origId);
11843                return;
11844            }
11845        }
11846
11847        // No piece of data specified, dump everything.
11848        synchronized (this) {
11849            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11850            pw.println();
11851            if (dumpAll) {
11852                pw.println("-------------------------------------------------------------------------------");
11853            }
11854            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11855            pw.println();
11856            if (dumpAll) {
11857                pw.println("-------------------------------------------------------------------------------");
11858            }
11859            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11860            pw.println();
11861            if (dumpAll) {
11862                pw.println("-------------------------------------------------------------------------------");
11863            }
11864            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11865            pw.println();
11866            if (dumpAll) {
11867                pw.println("-------------------------------------------------------------------------------");
11868            }
11869            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11870            pw.println();
11871            if (dumpAll) {
11872                pw.println("-------------------------------------------------------------------------------");
11873            }
11874            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11875            pw.println();
11876            if (dumpAll) {
11877                pw.println("-------------------------------------------------------------------------------");
11878            }
11879            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11880        }
11881        Binder.restoreCallingIdentity(origId);
11882    }
11883
11884    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11885            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11886        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11887
11888        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11889                dumpPackage);
11890        boolean needSep = printedAnything;
11891
11892        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11893                dumpPackage, needSep, "  mFocusedActivity: ");
11894        if (printed) {
11895            printedAnything = true;
11896            needSep = false;
11897        }
11898
11899        if (dumpPackage == null) {
11900            if (needSep) {
11901                pw.println();
11902            }
11903            needSep = true;
11904            printedAnything = true;
11905            mStackSupervisor.dump(pw, "  ");
11906        }
11907
11908        if (!printedAnything) {
11909            pw.println("  (nothing)");
11910        }
11911    }
11912
11913    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11914            int opti, boolean dumpAll, String dumpPackage) {
11915        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11916
11917        boolean printedAnything = false;
11918
11919        if (mRecentTasks.size() > 0) {
11920            boolean printedHeader = false;
11921
11922            final int N = mRecentTasks.size();
11923            for (int i=0; i<N; i++) {
11924                TaskRecord tr = mRecentTasks.get(i);
11925                if (dumpPackage != null) {
11926                    if (tr.realActivity == null ||
11927                            !dumpPackage.equals(tr.realActivity)) {
11928                        continue;
11929                    }
11930                }
11931                if (!printedHeader) {
11932                    pw.println("  Recent tasks:");
11933                    printedHeader = true;
11934                    printedAnything = true;
11935                }
11936                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11937                        pw.println(tr);
11938                if (dumpAll) {
11939                    mRecentTasks.get(i).dump(pw, "    ");
11940                }
11941            }
11942        }
11943
11944        if (!printedAnything) {
11945            pw.println("  (nothing)");
11946        }
11947    }
11948
11949    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11950            int opti, boolean dumpAll, String dumpPackage) {
11951        boolean needSep = false;
11952        boolean printedAnything = false;
11953        int numPers = 0;
11954
11955        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11956
11957        if (dumpAll) {
11958            final int NP = mProcessNames.getMap().size();
11959            for (int ip=0; ip<NP; ip++) {
11960                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11961                final int NA = procs.size();
11962                for (int ia=0; ia<NA; ia++) {
11963                    ProcessRecord r = procs.valueAt(ia);
11964                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11965                        continue;
11966                    }
11967                    if (!needSep) {
11968                        pw.println("  All known processes:");
11969                        needSep = true;
11970                        printedAnything = true;
11971                    }
11972                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11973                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11974                        pw.print(" "); pw.println(r);
11975                    r.dump(pw, "    ");
11976                    if (r.persistent) {
11977                        numPers++;
11978                    }
11979                }
11980            }
11981        }
11982
11983        if (mIsolatedProcesses.size() > 0) {
11984            boolean printed = false;
11985            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11986                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11987                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11988                    continue;
11989                }
11990                if (!printed) {
11991                    if (needSep) {
11992                        pw.println();
11993                    }
11994                    pw.println("  Isolated process list (sorted by uid):");
11995                    printedAnything = true;
11996                    printed = true;
11997                    needSep = true;
11998                }
11999                pw.println(String.format("%sIsolated #%2d: %s",
12000                        "    ", i, r.toString()));
12001            }
12002        }
12003
12004        if (mLruProcesses.size() > 0) {
12005            if (needSep) {
12006                pw.println();
12007            }
12008            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12009                    pw.print(" total, non-act at ");
12010                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12011                    pw.print(", non-svc at ");
12012                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12013                    pw.println("):");
12014            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12015            needSep = true;
12016            printedAnything = true;
12017        }
12018
12019        if (dumpAll || dumpPackage != null) {
12020            synchronized (mPidsSelfLocked) {
12021                boolean printed = false;
12022                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12023                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12024                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12025                        continue;
12026                    }
12027                    if (!printed) {
12028                        if (needSep) pw.println();
12029                        needSep = true;
12030                        pw.println("  PID mappings:");
12031                        printed = true;
12032                        printedAnything = true;
12033                    }
12034                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12035                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12036                }
12037            }
12038        }
12039
12040        if (mForegroundProcesses.size() > 0) {
12041            synchronized (mPidsSelfLocked) {
12042                boolean printed = false;
12043                for (int i=0; i<mForegroundProcesses.size(); i++) {
12044                    ProcessRecord r = mPidsSelfLocked.get(
12045                            mForegroundProcesses.valueAt(i).pid);
12046                    if (dumpPackage != null && (r == null
12047                            || !r.pkgList.containsKey(dumpPackage))) {
12048                        continue;
12049                    }
12050                    if (!printed) {
12051                        if (needSep) pw.println();
12052                        needSep = true;
12053                        pw.println("  Foreground Processes:");
12054                        printed = true;
12055                        printedAnything = true;
12056                    }
12057                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12058                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12059                }
12060            }
12061        }
12062
12063        if (mPersistentStartingProcesses.size() > 0) {
12064            if (needSep) pw.println();
12065            needSep = true;
12066            printedAnything = true;
12067            pw.println("  Persisent processes that are starting:");
12068            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12069                    "Starting Norm", "Restarting PERS", dumpPackage);
12070        }
12071
12072        if (mRemovedProcesses.size() > 0) {
12073            if (needSep) pw.println();
12074            needSep = true;
12075            printedAnything = true;
12076            pw.println("  Processes that are being removed:");
12077            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12078                    "Removed Norm", "Removed PERS", dumpPackage);
12079        }
12080
12081        if (mProcessesOnHold.size() > 0) {
12082            if (needSep) pw.println();
12083            needSep = true;
12084            printedAnything = true;
12085            pw.println("  Processes that are on old until the system is ready:");
12086            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12087                    "OnHold Norm", "OnHold PERS", dumpPackage);
12088        }
12089
12090        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12091
12092        if (mProcessCrashTimes.getMap().size() > 0) {
12093            boolean printed = false;
12094            long now = SystemClock.uptimeMillis();
12095            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12096            final int NP = pmap.size();
12097            for (int ip=0; ip<NP; ip++) {
12098                String pname = pmap.keyAt(ip);
12099                SparseArray<Long> uids = pmap.valueAt(ip);
12100                final int N = uids.size();
12101                for (int i=0; i<N; i++) {
12102                    int puid = uids.keyAt(i);
12103                    ProcessRecord r = mProcessNames.get(pname, puid);
12104                    if (dumpPackage != null && (r == null
12105                            || !r.pkgList.containsKey(dumpPackage))) {
12106                        continue;
12107                    }
12108                    if (!printed) {
12109                        if (needSep) pw.println();
12110                        needSep = true;
12111                        pw.println("  Time since processes crashed:");
12112                        printed = true;
12113                        printedAnything = true;
12114                    }
12115                    pw.print("    Process "); pw.print(pname);
12116                            pw.print(" uid "); pw.print(puid);
12117                            pw.print(": last crashed ");
12118                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12119                            pw.println(" ago");
12120                }
12121            }
12122        }
12123
12124        if (mBadProcesses.getMap().size() > 0) {
12125            boolean printed = false;
12126            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12127            final int NP = pmap.size();
12128            for (int ip=0; ip<NP; ip++) {
12129                String pname = pmap.keyAt(ip);
12130                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12131                final int N = uids.size();
12132                for (int i=0; i<N; i++) {
12133                    int puid = uids.keyAt(i);
12134                    ProcessRecord r = mProcessNames.get(pname, puid);
12135                    if (dumpPackage != null && (r == null
12136                            || !r.pkgList.containsKey(dumpPackage))) {
12137                        continue;
12138                    }
12139                    if (!printed) {
12140                        if (needSep) pw.println();
12141                        needSep = true;
12142                        pw.println("  Bad processes:");
12143                        printedAnything = true;
12144                    }
12145                    BadProcessInfo info = uids.valueAt(i);
12146                    pw.print("    Bad process "); pw.print(pname);
12147                            pw.print(" uid "); pw.print(puid);
12148                            pw.print(": crashed at time "); pw.println(info.time);
12149                    if (info.shortMsg != null) {
12150                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12151                    }
12152                    if (info.longMsg != null) {
12153                        pw.print("      Long msg: "); pw.println(info.longMsg);
12154                    }
12155                    if (info.stack != null) {
12156                        pw.println("      Stack:");
12157                        int lastPos = 0;
12158                        for (int pos=0; pos<info.stack.length(); pos++) {
12159                            if (info.stack.charAt(pos) == '\n') {
12160                                pw.print("        ");
12161                                pw.write(info.stack, lastPos, pos-lastPos);
12162                                pw.println();
12163                                lastPos = pos+1;
12164                            }
12165                        }
12166                        if (lastPos < info.stack.length()) {
12167                            pw.print("        ");
12168                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12169                            pw.println();
12170                        }
12171                    }
12172                }
12173            }
12174        }
12175
12176        if (dumpPackage == null) {
12177            pw.println();
12178            needSep = false;
12179            pw.println("  mStartedUsers:");
12180            for (int i=0; i<mStartedUsers.size(); i++) {
12181                UserStartedState uss = mStartedUsers.valueAt(i);
12182                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12183                        pw.print(": "); uss.dump("", pw);
12184            }
12185            pw.print("  mStartedUserArray: [");
12186            for (int i=0; i<mStartedUserArray.length; i++) {
12187                if (i > 0) pw.print(", ");
12188                pw.print(mStartedUserArray[i]);
12189            }
12190            pw.println("]");
12191            pw.print("  mUserLru: [");
12192            for (int i=0; i<mUserLru.size(); i++) {
12193                if (i > 0) pw.print(", ");
12194                pw.print(mUserLru.get(i));
12195            }
12196            pw.println("]");
12197            if (dumpAll) {
12198                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12199            }
12200            synchronized (mUserProfileGroupIdsSelfLocked) {
12201                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12202                    pw.println("  mUserProfileGroupIds:");
12203                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12204                        pw.print("    User #");
12205                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12206                        pw.print(" -> profile #");
12207                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12208                    }
12209                }
12210            }
12211        }
12212        if (mHomeProcess != null && (dumpPackage == null
12213                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12214            if (needSep) {
12215                pw.println();
12216                needSep = false;
12217            }
12218            pw.println("  mHomeProcess: " + mHomeProcess);
12219        }
12220        if (mPreviousProcess != null && (dumpPackage == null
12221                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12222            if (needSep) {
12223                pw.println();
12224                needSep = false;
12225            }
12226            pw.println("  mPreviousProcess: " + mPreviousProcess);
12227        }
12228        if (dumpAll) {
12229            StringBuilder sb = new StringBuilder(128);
12230            sb.append("  mPreviousProcessVisibleTime: ");
12231            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12232            pw.println(sb);
12233        }
12234        if (mHeavyWeightProcess != null && (dumpPackage == null
12235                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12236            if (needSep) {
12237                pw.println();
12238                needSep = false;
12239            }
12240            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12241        }
12242        if (dumpPackage == null) {
12243            pw.println("  mConfiguration: " + mConfiguration);
12244        }
12245        if (dumpAll) {
12246            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12247            if (mCompatModePackages.getPackages().size() > 0) {
12248                boolean printed = false;
12249                for (Map.Entry<String, Integer> entry
12250                        : mCompatModePackages.getPackages().entrySet()) {
12251                    String pkg = entry.getKey();
12252                    int mode = entry.getValue();
12253                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12254                        continue;
12255                    }
12256                    if (!printed) {
12257                        pw.println("  mScreenCompatPackages:");
12258                        printed = true;
12259                    }
12260                    pw.print("    "); pw.print(pkg); pw.print(": ");
12261                            pw.print(mode); pw.println();
12262                }
12263            }
12264        }
12265        if (dumpPackage == null) {
12266            if (mSleeping || mWentToSleep || mLockScreenShown) {
12267                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12268                        + " mLockScreenShown " + mLockScreenShown);
12269            }
12270            if (mShuttingDown || mRunningVoice) {
12271                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12272            }
12273        }
12274        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12275                || mOrigWaitForDebugger) {
12276            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12277                    || dumpPackage.equals(mOrigDebugApp)) {
12278                if (needSep) {
12279                    pw.println();
12280                    needSep = false;
12281                }
12282                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12283                        + " mDebugTransient=" + mDebugTransient
12284                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12285            }
12286        }
12287        if (mOpenGlTraceApp != null) {
12288            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12289                if (needSep) {
12290                    pw.println();
12291                    needSep = false;
12292                }
12293                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12294            }
12295        }
12296        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12297                || mProfileFd != null) {
12298            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12299                if (needSep) {
12300                    pw.println();
12301                    needSep = false;
12302                }
12303                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12304                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12305                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12306                        + mAutoStopProfiler);
12307                pw.println("  mProfileType=" + mProfileType);
12308            }
12309        }
12310        if (dumpPackage == null) {
12311            if (mAlwaysFinishActivities || mController != null) {
12312                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12313                        + " mController=" + mController);
12314            }
12315            if (dumpAll) {
12316                pw.println("  Total persistent processes: " + numPers);
12317                pw.println("  mProcessesReady=" + mProcessesReady
12318                        + " mSystemReady=" + mSystemReady);
12319                pw.println("  mBooting=" + mBooting
12320                        + " mBooted=" + mBooted
12321                        + " mFactoryTest=" + mFactoryTest);
12322                pw.print("  mLastPowerCheckRealtime=");
12323                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12324                        pw.println("");
12325                pw.print("  mLastPowerCheckUptime=");
12326                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12327                        pw.println("");
12328                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12329                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12330                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12331                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12332                        + " (" + mLruProcesses.size() + " total)"
12333                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12334                        + " mNumServiceProcs=" + mNumServiceProcs
12335                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12336                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12337                        + " mLastMemoryLevel" + mLastMemoryLevel
12338                        + " mLastNumProcesses" + mLastNumProcesses);
12339                long now = SystemClock.uptimeMillis();
12340                pw.print("  mLastIdleTime=");
12341                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12342                        pw.print(" mLowRamSinceLastIdle=");
12343                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12344                        pw.println();
12345            }
12346        }
12347
12348        if (!printedAnything) {
12349            pw.println("  (nothing)");
12350        }
12351    }
12352
12353    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12354            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12355        if (mProcessesToGc.size() > 0) {
12356            boolean printed = false;
12357            long now = SystemClock.uptimeMillis();
12358            for (int i=0; i<mProcessesToGc.size(); i++) {
12359                ProcessRecord proc = mProcessesToGc.get(i);
12360                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12361                    continue;
12362                }
12363                if (!printed) {
12364                    if (needSep) pw.println();
12365                    needSep = true;
12366                    pw.println("  Processes that are waiting to GC:");
12367                    printed = true;
12368                }
12369                pw.print("    Process "); pw.println(proc);
12370                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12371                        pw.print(", last gced=");
12372                        pw.print(now-proc.lastRequestedGc);
12373                        pw.print(" ms ago, last lowMem=");
12374                        pw.print(now-proc.lastLowMemory);
12375                        pw.println(" ms ago");
12376
12377            }
12378        }
12379        return needSep;
12380    }
12381
12382    void printOomLevel(PrintWriter pw, String name, int adj) {
12383        pw.print("    ");
12384        if (adj >= 0) {
12385            pw.print(' ');
12386            if (adj < 10) pw.print(' ');
12387        } else {
12388            if (adj > -10) pw.print(' ');
12389        }
12390        pw.print(adj);
12391        pw.print(": ");
12392        pw.print(name);
12393        pw.print(" (");
12394        pw.print(mProcessList.getMemLevel(adj)/1024);
12395        pw.println(" kB)");
12396    }
12397
12398    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12399            int opti, boolean dumpAll) {
12400        boolean needSep = false;
12401
12402        if (mLruProcesses.size() > 0) {
12403            if (needSep) pw.println();
12404            needSep = true;
12405            pw.println("  OOM levels:");
12406            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12407            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12408            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12409            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12410            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12411            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12412            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12413            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12414            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12415            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12416            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12417            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12418            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12419
12420            if (needSep) pw.println();
12421            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12422                    pw.print(" total, non-act at ");
12423                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12424                    pw.print(", non-svc at ");
12425                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12426                    pw.println("):");
12427            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12428            needSep = true;
12429        }
12430
12431        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12432
12433        pw.println();
12434        pw.println("  mHomeProcess: " + mHomeProcess);
12435        pw.println("  mPreviousProcess: " + mPreviousProcess);
12436        if (mHeavyWeightProcess != null) {
12437            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12438        }
12439
12440        return true;
12441    }
12442
12443    /**
12444     * There are three ways to call this:
12445     *  - no provider specified: dump all the providers
12446     *  - a flattened component name that matched an existing provider was specified as the
12447     *    first arg: dump that one provider
12448     *  - the first arg isn't the flattened component name of an existing provider:
12449     *    dump all providers whose component contains the first arg as a substring
12450     */
12451    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12452            int opti, boolean dumpAll) {
12453        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12454    }
12455
12456    static class ItemMatcher {
12457        ArrayList<ComponentName> components;
12458        ArrayList<String> strings;
12459        ArrayList<Integer> objects;
12460        boolean all;
12461
12462        ItemMatcher() {
12463            all = true;
12464        }
12465
12466        void build(String name) {
12467            ComponentName componentName = ComponentName.unflattenFromString(name);
12468            if (componentName != null) {
12469                if (components == null) {
12470                    components = new ArrayList<ComponentName>();
12471                }
12472                components.add(componentName);
12473                all = false;
12474            } else {
12475                int objectId = 0;
12476                // Not a '/' separated full component name; maybe an object ID?
12477                try {
12478                    objectId = Integer.parseInt(name, 16);
12479                    if (objects == null) {
12480                        objects = new ArrayList<Integer>();
12481                    }
12482                    objects.add(objectId);
12483                    all = false;
12484                } catch (RuntimeException e) {
12485                    // Not an integer; just do string match.
12486                    if (strings == null) {
12487                        strings = new ArrayList<String>();
12488                    }
12489                    strings.add(name);
12490                    all = false;
12491                }
12492            }
12493        }
12494
12495        int build(String[] args, int opti) {
12496            for (; opti<args.length; opti++) {
12497                String name = args[opti];
12498                if ("--".equals(name)) {
12499                    return opti+1;
12500                }
12501                build(name);
12502            }
12503            return opti;
12504        }
12505
12506        boolean match(Object object, ComponentName comp) {
12507            if (all) {
12508                return true;
12509            }
12510            if (components != null) {
12511                for (int i=0; i<components.size(); i++) {
12512                    if (components.get(i).equals(comp)) {
12513                        return true;
12514                    }
12515                }
12516            }
12517            if (objects != null) {
12518                for (int i=0; i<objects.size(); i++) {
12519                    if (System.identityHashCode(object) == objects.get(i)) {
12520                        return true;
12521                    }
12522                }
12523            }
12524            if (strings != null) {
12525                String flat = comp.flattenToString();
12526                for (int i=0; i<strings.size(); i++) {
12527                    if (flat.contains(strings.get(i))) {
12528                        return true;
12529                    }
12530                }
12531            }
12532            return false;
12533        }
12534    }
12535
12536    /**
12537     * There are three things that cmd can be:
12538     *  - a flattened component name that matches an existing activity
12539     *  - the cmd arg isn't the flattened component name of an existing activity:
12540     *    dump all activity whose component contains the cmd as a substring
12541     *  - A hex number of the ActivityRecord object instance.
12542     */
12543    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12544            int opti, boolean dumpAll) {
12545        ArrayList<ActivityRecord> activities;
12546
12547        synchronized (this) {
12548            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12549        }
12550
12551        if (activities.size() <= 0) {
12552            return false;
12553        }
12554
12555        String[] newArgs = new String[args.length - opti];
12556        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12557
12558        TaskRecord lastTask = null;
12559        boolean needSep = false;
12560        for (int i=activities.size()-1; i>=0; i--) {
12561            ActivityRecord r = activities.get(i);
12562            if (needSep) {
12563                pw.println();
12564            }
12565            needSep = true;
12566            synchronized (this) {
12567                if (lastTask != r.task) {
12568                    lastTask = r.task;
12569                    pw.print("TASK "); pw.print(lastTask.affinity);
12570                            pw.print(" id="); pw.println(lastTask.taskId);
12571                    if (dumpAll) {
12572                        lastTask.dump(pw, "  ");
12573                    }
12574                }
12575            }
12576            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12577        }
12578        return true;
12579    }
12580
12581    /**
12582     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12583     * there is a thread associated with the activity.
12584     */
12585    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12586            final ActivityRecord r, String[] args, boolean dumpAll) {
12587        String innerPrefix = prefix + "  ";
12588        synchronized (this) {
12589            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12590                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12591                    pw.print(" pid=");
12592                    if (r.app != null) pw.println(r.app.pid);
12593                    else pw.println("(not running)");
12594            if (dumpAll) {
12595                r.dump(pw, innerPrefix);
12596            }
12597        }
12598        if (r.app != null && r.app.thread != null) {
12599            // flush anything that is already in the PrintWriter since the thread is going
12600            // to write to the file descriptor directly
12601            pw.flush();
12602            try {
12603                TransferPipe tp = new TransferPipe();
12604                try {
12605                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12606                            r.appToken, innerPrefix, args);
12607                    tp.go(fd);
12608                } finally {
12609                    tp.kill();
12610                }
12611            } catch (IOException e) {
12612                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12613            } catch (RemoteException e) {
12614                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12615            }
12616        }
12617    }
12618
12619    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12620            int opti, boolean dumpAll, String dumpPackage) {
12621        boolean needSep = false;
12622        boolean onlyHistory = false;
12623        boolean printedAnything = false;
12624
12625        if ("history".equals(dumpPackage)) {
12626            if (opti < args.length && "-s".equals(args[opti])) {
12627                dumpAll = false;
12628            }
12629            onlyHistory = true;
12630            dumpPackage = null;
12631        }
12632
12633        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12634        if (!onlyHistory && dumpAll) {
12635            if (mRegisteredReceivers.size() > 0) {
12636                boolean printed = false;
12637                Iterator it = mRegisteredReceivers.values().iterator();
12638                while (it.hasNext()) {
12639                    ReceiverList r = (ReceiverList)it.next();
12640                    if (dumpPackage != null && (r.app == null ||
12641                            !dumpPackage.equals(r.app.info.packageName))) {
12642                        continue;
12643                    }
12644                    if (!printed) {
12645                        pw.println("  Registered Receivers:");
12646                        needSep = true;
12647                        printed = true;
12648                        printedAnything = true;
12649                    }
12650                    pw.print("  * "); pw.println(r);
12651                    r.dump(pw, "    ");
12652                }
12653            }
12654
12655            if (mReceiverResolver.dump(pw, needSep ?
12656                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12657                    "    ", dumpPackage, false)) {
12658                needSep = true;
12659                printedAnything = true;
12660            }
12661        }
12662
12663        for (BroadcastQueue q : mBroadcastQueues) {
12664            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12665            printedAnything |= needSep;
12666        }
12667
12668        needSep = true;
12669
12670        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12671            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12672                if (needSep) {
12673                    pw.println();
12674                }
12675                needSep = true;
12676                printedAnything = true;
12677                pw.print("  Sticky broadcasts for user ");
12678                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12679                StringBuilder sb = new StringBuilder(128);
12680                for (Map.Entry<String, ArrayList<Intent>> ent
12681                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12682                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12683                    if (dumpAll) {
12684                        pw.println(":");
12685                        ArrayList<Intent> intents = ent.getValue();
12686                        final int N = intents.size();
12687                        for (int i=0; i<N; i++) {
12688                            sb.setLength(0);
12689                            sb.append("    Intent: ");
12690                            intents.get(i).toShortString(sb, false, true, false, false);
12691                            pw.println(sb.toString());
12692                            Bundle bundle = intents.get(i).getExtras();
12693                            if (bundle != null) {
12694                                pw.print("      ");
12695                                pw.println(bundle.toString());
12696                            }
12697                        }
12698                    } else {
12699                        pw.println("");
12700                    }
12701                }
12702            }
12703        }
12704
12705        if (!onlyHistory && dumpAll) {
12706            pw.println();
12707            for (BroadcastQueue queue : mBroadcastQueues) {
12708                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12709                        + queue.mBroadcastsScheduled);
12710            }
12711            pw.println("  mHandler:");
12712            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12713            needSep = true;
12714            printedAnything = true;
12715        }
12716
12717        if (!printedAnything) {
12718            pw.println("  (nothing)");
12719        }
12720    }
12721
12722    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12723            int opti, boolean dumpAll, String dumpPackage) {
12724        boolean needSep;
12725        boolean printedAnything = false;
12726
12727        ItemMatcher matcher = new ItemMatcher();
12728        matcher.build(args, opti);
12729
12730        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12731
12732        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12733        printedAnything |= needSep;
12734
12735        if (mLaunchingProviders.size() > 0) {
12736            boolean printed = false;
12737            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12738                ContentProviderRecord r = mLaunchingProviders.get(i);
12739                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12740                    continue;
12741                }
12742                if (!printed) {
12743                    if (needSep) pw.println();
12744                    needSep = true;
12745                    pw.println("  Launching content providers:");
12746                    printed = true;
12747                    printedAnything = true;
12748                }
12749                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12750                        pw.println(r);
12751            }
12752        }
12753
12754        if (mGrantedUriPermissions.size() > 0) {
12755            boolean printed = false;
12756            int dumpUid = -2;
12757            if (dumpPackage != null) {
12758                try {
12759                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12760                } catch (NameNotFoundException e) {
12761                    dumpUid = -1;
12762                }
12763            }
12764            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12765                int uid = mGrantedUriPermissions.keyAt(i);
12766                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12767                    continue;
12768                }
12769                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12770                if (!printed) {
12771                    if (needSep) pw.println();
12772                    needSep = true;
12773                    pw.println("  Granted Uri Permissions:");
12774                    printed = true;
12775                    printedAnything = true;
12776                }
12777                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12778                for (UriPermission perm : perms.values()) {
12779                    pw.print("    "); pw.println(perm);
12780                    if (dumpAll) {
12781                        perm.dump(pw, "      ");
12782                    }
12783                }
12784            }
12785        }
12786
12787        if (!printedAnything) {
12788            pw.println("  (nothing)");
12789        }
12790    }
12791
12792    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12793            int opti, boolean dumpAll, String dumpPackage) {
12794        boolean printed = false;
12795
12796        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12797
12798        if (mIntentSenderRecords.size() > 0) {
12799            Iterator<WeakReference<PendingIntentRecord>> it
12800                    = mIntentSenderRecords.values().iterator();
12801            while (it.hasNext()) {
12802                WeakReference<PendingIntentRecord> ref = it.next();
12803                PendingIntentRecord rec = ref != null ? ref.get(): null;
12804                if (dumpPackage != null && (rec == null
12805                        || !dumpPackage.equals(rec.key.packageName))) {
12806                    continue;
12807                }
12808                printed = true;
12809                if (rec != null) {
12810                    pw.print("  * "); pw.println(rec);
12811                    if (dumpAll) {
12812                        rec.dump(pw, "    ");
12813                    }
12814                } else {
12815                    pw.print("  * "); pw.println(ref);
12816                }
12817            }
12818        }
12819
12820        if (!printed) {
12821            pw.println("  (nothing)");
12822        }
12823    }
12824
12825    private static final int dumpProcessList(PrintWriter pw,
12826            ActivityManagerService service, List list,
12827            String prefix, String normalLabel, String persistentLabel,
12828            String dumpPackage) {
12829        int numPers = 0;
12830        final int N = list.size()-1;
12831        for (int i=N; i>=0; i--) {
12832            ProcessRecord r = (ProcessRecord)list.get(i);
12833            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12834                continue;
12835            }
12836            pw.println(String.format("%s%s #%2d: %s",
12837                    prefix, (r.persistent ? persistentLabel : normalLabel),
12838                    i, r.toString()));
12839            if (r.persistent) {
12840                numPers++;
12841            }
12842        }
12843        return numPers;
12844    }
12845
12846    private static final boolean dumpProcessOomList(PrintWriter pw,
12847            ActivityManagerService service, List<ProcessRecord> origList,
12848            String prefix, String normalLabel, String persistentLabel,
12849            boolean inclDetails, String dumpPackage) {
12850
12851        ArrayList<Pair<ProcessRecord, Integer>> list
12852                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12853        for (int i=0; i<origList.size(); i++) {
12854            ProcessRecord r = origList.get(i);
12855            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12856                continue;
12857            }
12858            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12859        }
12860
12861        if (list.size() <= 0) {
12862            return false;
12863        }
12864
12865        Comparator<Pair<ProcessRecord, Integer>> comparator
12866                = new Comparator<Pair<ProcessRecord, Integer>>() {
12867            @Override
12868            public int compare(Pair<ProcessRecord, Integer> object1,
12869                    Pair<ProcessRecord, Integer> object2) {
12870                if (object1.first.setAdj != object2.first.setAdj) {
12871                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12872                }
12873                if (object1.second.intValue() != object2.second.intValue()) {
12874                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12875                }
12876                return 0;
12877            }
12878        };
12879
12880        Collections.sort(list, comparator);
12881
12882        final long curRealtime = SystemClock.elapsedRealtime();
12883        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12884        final long curUptime = SystemClock.uptimeMillis();
12885        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12886
12887        for (int i=list.size()-1; i>=0; i--) {
12888            ProcessRecord r = list.get(i).first;
12889            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12890            char schedGroup;
12891            switch (r.setSchedGroup) {
12892                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12893                    schedGroup = 'B';
12894                    break;
12895                case Process.THREAD_GROUP_DEFAULT:
12896                    schedGroup = 'F';
12897                    break;
12898                default:
12899                    schedGroup = '?';
12900                    break;
12901            }
12902            char foreground;
12903            if (r.foregroundActivities) {
12904                foreground = 'A';
12905            } else if (r.foregroundServices) {
12906                foreground = 'S';
12907            } else {
12908                foreground = ' ';
12909            }
12910            String procState = ProcessList.makeProcStateString(r.curProcState);
12911            pw.print(prefix);
12912            pw.print(r.persistent ? persistentLabel : normalLabel);
12913            pw.print(" #");
12914            int num = (origList.size()-1)-list.get(i).second;
12915            if (num < 10) pw.print(' ');
12916            pw.print(num);
12917            pw.print(": ");
12918            pw.print(oomAdj);
12919            pw.print(' ');
12920            pw.print(schedGroup);
12921            pw.print('/');
12922            pw.print(foreground);
12923            pw.print('/');
12924            pw.print(procState);
12925            pw.print(" trm:");
12926            if (r.trimMemoryLevel < 10) pw.print(' ');
12927            pw.print(r.trimMemoryLevel);
12928            pw.print(' ');
12929            pw.print(r.toShortString());
12930            pw.print(" (");
12931            pw.print(r.adjType);
12932            pw.println(')');
12933            if (r.adjSource != null || r.adjTarget != null) {
12934                pw.print(prefix);
12935                pw.print("    ");
12936                if (r.adjTarget instanceof ComponentName) {
12937                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12938                } else if (r.adjTarget != null) {
12939                    pw.print(r.adjTarget.toString());
12940                } else {
12941                    pw.print("{null}");
12942                }
12943                pw.print("<=");
12944                if (r.adjSource instanceof ProcessRecord) {
12945                    pw.print("Proc{");
12946                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12947                    pw.println("}");
12948                } else if (r.adjSource != null) {
12949                    pw.println(r.adjSource.toString());
12950                } else {
12951                    pw.println("{null}");
12952                }
12953            }
12954            if (inclDetails) {
12955                pw.print(prefix);
12956                pw.print("    ");
12957                pw.print("oom: max="); pw.print(r.maxAdj);
12958                pw.print(" curRaw="); pw.print(r.curRawAdj);
12959                pw.print(" setRaw="); pw.print(r.setRawAdj);
12960                pw.print(" cur="); pw.print(r.curAdj);
12961                pw.print(" set="); pw.println(r.setAdj);
12962                pw.print(prefix);
12963                pw.print("    ");
12964                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12965                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12966                pw.print(" lastPss="); pw.print(r.lastPss);
12967                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12968                pw.print(prefix);
12969                pw.print("    ");
12970                pw.print("cached="); pw.print(r.cached);
12971                pw.print(" empty="); pw.print(r.empty);
12972                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12973
12974                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12975                    if (r.lastWakeTime != 0) {
12976                        long wtime;
12977                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12978                        synchronized (stats) {
12979                            wtime = stats.getProcessWakeTime(r.info.uid,
12980                                    r.pid, curRealtime);
12981                        }
12982                        long timeUsed = wtime - r.lastWakeTime;
12983                        pw.print(prefix);
12984                        pw.print("    ");
12985                        pw.print("keep awake over ");
12986                        TimeUtils.formatDuration(realtimeSince, pw);
12987                        pw.print(" used ");
12988                        TimeUtils.formatDuration(timeUsed, pw);
12989                        pw.print(" (");
12990                        pw.print((timeUsed*100)/realtimeSince);
12991                        pw.println("%)");
12992                    }
12993                    if (r.lastCpuTime != 0) {
12994                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12995                        pw.print(prefix);
12996                        pw.print("    ");
12997                        pw.print("run cpu over ");
12998                        TimeUtils.formatDuration(uptimeSince, pw);
12999                        pw.print(" used ");
13000                        TimeUtils.formatDuration(timeUsed, pw);
13001                        pw.print(" (");
13002                        pw.print((timeUsed*100)/uptimeSince);
13003                        pw.println("%)");
13004                    }
13005                }
13006            }
13007        }
13008        return true;
13009    }
13010
13011    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13012        ArrayList<ProcessRecord> procs;
13013        synchronized (this) {
13014            if (args != null && args.length > start
13015                    && args[start].charAt(0) != '-') {
13016                procs = new ArrayList<ProcessRecord>();
13017                int pid = -1;
13018                try {
13019                    pid = Integer.parseInt(args[start]);
13020                } catch (NumberFormatException e) {
13021                }
13022                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13023                    ProcessRecord proc = mLruProcesses.get(i);
13024                    if (proc.pid == pid) {
13025                        procs.add(proc);
13026                    } else if (proc.processName.equals(args[start])) {
13027                        procs.add(proc);
13028                    }
13029                }
13030                if (procs.size() <= 0) {
13031                    return null;
13032                }
13033            } else {
13034                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13035            }
13036        }
13037        return procs;
13038    }
13039
13040    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13041            PrintWriter pw, String[] args) {
13042        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13043        if (procs == null) {
13044            pw.println("No process found for: " + args[0]);
13045            return;
13046        }
13047
13048        long uptime = SystemClock.uptimeMillis();
13049        long realtime = SystemClock.elapsedRealtime();
13050        pw.println("Applications Graphics Acceleration Info:");
13051        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13052
13053        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13054            ProcessRecord r = procs.get(i);
13055            if (r.thread != null) {
13056                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13057                pw.flush();
13058                try {
13059                    TransferPipe tp = new TransferPipe();
13060                    try {
13061                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13062                        tp.go(fd);
13063                    } finally {
13064                        tp.kill();
13065                    }
13066                } catch (IOException e) {
13067                    pw.println("Failure while dumping the app: " + r);
13068                    pw.flush();
13069                } catch (RemoteException e) {
13070                    pw.println("Got a RemoteException while dumping the app " + r);
13071                    pw.flush();
13072                }
13073            }
13074        }
13075    }
13076
13077    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13078        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13079        if (procs == null) {
13080            pw.println("No process found for: " + args[0]);
13081            return;
13082        }
13083
13084        pw.println("Applications Database Info:");
13085
13086        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13087            ProcessRecord r = procs.get(i);
13088            if (r.thread != null) {
13089                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13090                pw.flush();
13091                try {
13092                    TransferPipe tp = new TransferPipe();
13093                    try {
13094                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13095                        tp.go(fd);
13096                    } finally {
13097                        tp.kill();
13098                    }
13099                } catch (IOException e) {
13100                    pw.println("Failure while dumping the app: " + r);
13101                    pw.flush();
13102                } catch (RemoteException e) {
13103                    pw.println("Got a RemoteException while dumping the app " + r);
13104                    pw.flush();
13105                }
13106            }
13107        }
13108    }
13109
13110    final static class MemItem {
13111        final boolean isProc;
13112        final String label;
13113        final String shortLabel;
13114        final long pss;
13115        final int id;
13116        final boolean hasActivities;
13117        ArrayList<MemItem> subitems;
13118
13119        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13120                boolean _hasActivities) {
13121            isProc = true;
13122            label = _label;
13123            shortLabel = _shortLabel;
13124            pss = _pss;
13125            id = _id;
13126            hasActivities = _hasActivities;
13127        }
13128
13129        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13130            isProc = false;
13131            label = _label;
13132            shortLabel = _shortLabel;
13133            pss = _pss;
13134            id = _id;
13135            hasActivities = false;
13136        }
13137    }
13138
13139    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13140            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13141        if (sort && !isCompact) {
13142            Collections.sort(items, new Comparator<MemItem>() {
13143                @Override
13144                public int compare(MemItem lhs, MemItem rhs) {
13145                    if (lhs.pss < rhs.pss) {
13146                        return 1;
13147                    } else if (lhs.pss > rhs.pss) {
13148                        return -1;
13149                    }
13150                    return 0;
13151                }
13152            });
13153        }
13154
13155        for (int i=0; i<items.size(); i++) {
13156            MemItem mi = items.get(i);
13157            if (!isCompact) {
13158                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13159            } else if (mi.isProc) {
13160                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13161                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13162                pw.println(mi.hasActivities ? ",a" : ",e");
13163            } else {
13164                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13165                pw.println(mi.pss);
13166            }
13167            if (mi.subitems != null) {
13168                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13169                        true, isCompact);
13170            }
13171        }
13172    }
13173
13174    // These are in KB.
13175    static final long[] DUMP_MEM_BUCKETS = new long[] {
13176        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13177        120*1024, 160*1024, 200*1024,
13178        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13179        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13180    };
13181
13182    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13183            boolean stackLike) {
13184        int start = label.lastIndexOf('.');
13185        if (start >= 0) start++;
13186        else start = 0;
13187        int end = label.length();
13188        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13189            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13190                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13191                out.append(bucket);
13192                out.append(stackLike ? "MB." : "MB ");
13193                out.append(label, start, end);
13194                return;
13195            }
13196        }
13197        out.append(memKB/1024);
13198        out.append(stackLike ? "MB." : "MB ");
13199        out.append(label, start, end);
13200    }
13201
13202    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13203            ProcessList.NATIVE_ADJ,
13204            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13205            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13206            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13207            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13208            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13209    };
13210    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13211            "Native",
13212            "System", "Persistent", "Foreground",
13213            "Visible", "Perceptible",
13214            "Heavy Weight", "Backup",
13215            "A Services", "Home",
13216            "Previous", "B Services", "Cached"
13217    };
13218    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13219            "native",
13220            "sys", "pers", "fore",
13221            "vis", "percept",
13222            "heavy", "backup",
13223            "servicea", "home",
13224            "prev", "serviceb", "cached"
13225    };
13226
13227    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13228            long realtime, boolean isCheckinRequest, boolean isCompact) {
13229        if (isCheckinRequest || isCompact) {
13230            // short checkin version
13231            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13232        } else {
13233            pw.println("Applications Memory Usage (kB):");
13234            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13235        }
13236    }
13237
13238    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13239            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13240        boolean dumpDetails = false;
13241        boolean dumpFullDetails = false;
13242        boolean dumpDalvik = false;
13243        boolean oomOnly = false;
13244        boolean isCompact = false;
13245        boolean localOnly = false;
13246
13247        int opti = 0;
13248        while (opti < args.length) {
13249            String opt = args[opti];
13250            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13251                break;
13252            }
13253            opti++;
13254            if ("-a".equals(opt)) {
13255                dumpDetails = true;
13256                dumpFullDetails = true;
13257                dumpDalvik = true;
13258            } else if ("-d".equals(opt)) {
13259                dumpDalvik = true;
13260            } else if ("-c".equals(opt)) {
13261                isCompact = true;
13262            } else if ("--oom".equals(opt)) {
13263                oomOnly = true;
13264            } else if ("--local".equals(opt)) {
13265                localOnly = true;
13266            } else if ("-h".equals(opt)) {
13267                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13268                pw.println("  -a: include all available information for each process.");
13269                pw.println("  -d: include dalvik details when dumping process details.");
13270                pw.println("  -c: dump in a compact machine-parseable representation.");
13271                pw.println("  --oom: only show processes organized by oom adj.");
13272                pw.println("  --local: only collect details locally, don't call process.");
13273                pw.println("If [process] is specified it can be the name or ");
13274                pw.println("pid of a specific process to dump.");
13275                return;
13276            } else {
13277                pw.println("Unknown argument: " + opt + "; use -h for help");
13278            }
13279        }
13280
13281        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13282        long uptime = SystemClock.uptimeMillis();
13283        long realtime = SystemClock.elapsedRealtime();
13284        final long[] tmpLong = new long[1];
13285
13286        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13287        if (procs == null) {
13288            // No Java processes.  Maybe they want to print a native process.
13289            if (args != null && args.length > opti
13290                    && args[opti].charAt(0) != '-') {
13291                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13292                        = new ArrayList<ProcessCpuTracker.Stats>();
13293                updateCpuStatsNow();
13294                int findPid = -1;
13295                try {
13296                    findPid = Integer.parseInt(args[opti]);
13297                } catch (NumberFormatException e) {
13298                }
13299                synchronized (mProcessCpuThread) {
13300                    final int N = mProcessCpuTracker.countStats();
13301                    for (int i=0; i<N; i++) {
13302                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13303                        if (st.pid == findPid || (st.baseName != null
13304                                && st.baseName.equals(args[opti]))) {
13305                            nativeProcs.add(st);
13306                        }
13307                    }
13308                }
13309                if (nativeProcs.size() > 0) {
13310                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13311                            isCompact);
13312                    Debug.MemoryInfo mi = null;
13313                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13314                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13315                        final int pid = r.pid;
13316                        if (!isCheckinRequest && dumpDetails) {
13317                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13318                        }
13319                        if (mi == null) {
13320                            mi = new Debug.MemoryInfo();
13321                        }
13322                        if (dumpDetails || (!brief && !oomOnly)) {
13323                            Debug.getMemoryInfo(pid, mi);
13324                        } else {
13325                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13326                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13327                        }
13328                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13329                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13330                        if (isCheckinRequest) {
13331                            pw.println();
13332                        }
13333                    }
13334                    return;
13335                }
13336            }
13337            pw.println("No process found for: " + args[opti]);
13338            return;
13339        }
13340
13341        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13342            dumpDetails = true;
13343        }
13344
13345        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13346
13347        String[] innerArgs = new String[args.length-opti];
13348        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13349
13350        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13351        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13352        long nativePss=0, dalvikPss=0, otherPss=0;
13353        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13354
13355        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13356        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13357                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13358
13359        long totalPss = 0;
13360        long cachedPss = 0;
13361
13362        Debug.MemoryInfo mi = null;
13363        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13364            final ProcessRecord r = procs.get(i);
13365            final IApplicationThread thread;
13366            final int pid;
13367            final int oomAdj;
13368            final boolean hasActivities;
13369            synchronized (this) {
13370                thread = r.thread;
13371                pid = r.pid;
13372                oomAdj = r.getSetAdjWithServices();
13373                hasActivities = r.activities.size() > 0;
13374            }
13375            if (thread != null) {
13376                if (!isCheckinRequest && dumpDetails) {
13377                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13378                }
13379                if (mi == null) {
13380                    mi = new Debug.MemoryInfo();
13381                }
13382                if (dumpDetails || (!brief && !oomOnly)) {
13383                    Debug.getMemoryInfo(pid, mi);
13384                } else {
13385                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13386                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13387                }
13388                if (dumpDetails) {
13389                    if (localOnly) {
13390                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13391                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13392                        if (isCheckinRequest) {
13393                            pw.println();
13394                        }
13395                    } else {
13396                        try {
13397                            pw.flush();
13398                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13399                                    dumpDalvik, innerArgs);
13400                        } catch (RemoteException e) {
13401                            if (!isCheckinRequest) {
13402                                pw.println("Got RemoteException!");
13403                                pw.flush();
13404                            }
13405                        }
13406                    }
13407                }
13408
13409                final long myTotalPss = mi.getTotalPss();
13410                final long myTotalUss = mi.getTotalUss();
13411
13412                synchronized (this) {
13413                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13414                        // Record this for posterity if the process has been stable.
13415                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13416                    }
13417                }
13418
13419                if (!isCheckinRequest && mi != null) {
13420                    totalPss += myTotalPss;
13421                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13422                            (hasActivities ? " / activities)" : ")"),
13423                            r.processName, myTotalPss, pid, hasActivities);
13424                    procMems.add(pssItem);
13425                    procMemsMap.put(pid, pssItem);
13426
13427                    nativePss += mi.nativePss;
13428                    dalvikPss += mi.dalvikPss;
13429                    otherPss += mi.otherPss;
13430                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13431                        long mem = mi.getOtherPss(j);
13432                        miscPss[j] += mem;
13433                        otherPss -= mem;
13434                    }
13435
13436                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13437                        cachedPss += myTotalPss;
13438                    }
13439
13440                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13441                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13442                                || oomIndex == (oomPss.length-1)) {
13443                            oomPss[oomIndex] += myTotalPss;
13444                            if (oomProcs[oomIndex] == null) {
13445                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13446                            }
13447                            oomProcs[oomIndex].add(pssItem);
13448                            break;
13449                        }
13450                    }
13451                }
13452            }
13453        }
13454
13455        long nativeProcTotalPss = 0;
13456
13457        if (!isCheckinRequest && procs.size() > 1) {
13458            // If we are showing aggregations, also look for native processes to
13459            // include so that our aggregations are more accurate.
13460            updateCpuStatsNow();
13461            synchronized (mProcessCpuThread) {
13462                final int N = mProcessCpuTracker.countStats();
13463                for (int i=0; i<N; i++) {
13464                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13465                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13466                        if (mi == null) {
13467                            mi = new Debug.MemoryInfo();
13468                        }
13469                        if (!brief && !oomOnly) {
13470                            Debug.getMemoryInfo(st.pid, mi);
13471                        } else {
13472                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13473                            mi.nativePrivateDirty = (int)tmpLong[0];
13474                        }
13475
13476                        final long myTotalPss = mi.getTotalPss();
13477                        totalPss += myTotalPss;
13478                        nativeProcTotalPss += myTotalPss;
13479
13480                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13481                                st.name, myTotalPss, st.pid, false);
13482                        procMems.add(pssItem);
13483
13484                        nativePss += mi.nativePss;
13485                        dalvikPss += mi.dalvikPss;
13486                        otherPss += mi.otherPss;
13487                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13488                            long mem = mi.getOtherPss(j);
13489                            miscPss[j] += mem;
13490                            otherPss -= mem;
13491                        }
13492                        oomPss[0] += myTotalPss;
13493                        if (oomProcs[0] == null) {
13494                            oomProcs[0] = new ArrayList<MemItem>();
13495                        }
13496                        oomProcs[0].add(pssItem);
13497                    }
13498                }
13499            }
13500
13501            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13502
13503            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13504            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13505            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13506            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13507                String label = Debug.MemoryInfo.getOtherLabel(j);
13508                catMems.add(new MemItem(label, label, miscPss[j], j));
13509            }
13510
13511            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13512            for (int j=0; j<oomPss.length; j++) {
13513                if (oomPss[j] != 0) {
13514                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13515                            : DUMP_MEM_OOM_LABEL[j];
13516                    MemItem item = new MemItem(label, label, oomPss[j],
13517                            DUMP_MEM_OOM_ADJ[j]);
13518                    item.subitems = oomProcs[j];
13519                    oomMems.add(item);
13520                }
13521            }
13522
13523            if (!brief && !oomOnly && !isCompact) {
13524                pw.println();
13525                pw.println("Total PSS by process:");
13526                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13527                pw.println();
13528            }
13529            if (!isCompact) {
13530                pw.println("Total PSS by OOM adjustment:");
13531            }
13532            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13533            if (!brief && !oomOnly) {
13534                PrintWriter out = categoryPw != null ? categoryPw : pw;
13535                if (!isCompact) {
13536                    out.println();
13537                    out.println("Total PSS by category:");
13538                }
13539                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13540            }
13541            if (!isCompact) {
13542                pw.println();
13543            }
13544            MemInfoReader memInfo = new MemInfoReader();
13545            memInfo.readMemInfo();
13546            if (nativeProcTotalPss > 0) {
13547                synchronized (this) {
13548                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13549                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13550                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13551                            nativeProcTotalPss);
13552                }
13553            }
13554            if (!brief) {
13555                if (!isCompact) {
13556                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13557                    pw.print(" kB (status ");
13558                    switch (mLastMemoryLevel) {
13559                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13560                            pw.println("normal)");
13561                            break;
13562                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13563                            pw.println("moderate)");
13564                            break;
13565                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13566                            pw.println("low)");
13567                            break;
13568                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13569                            pw.println("critical)");
13570                            break;
13571                        default:
13572                            pw.print(mLastMemoryLevel);
13573                            pw.println(")");
13574                            break;
13575                    }
13576                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13577                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13578                            pw.print(cachedPss); pw.print(" cached pss + ");
13579                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13580                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13581                } else {
13582                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13583                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13584                            + memInfo.getFreeSizeKb()); pw.print(",");
13585                    pw.println(totalPss - cachedPss);
13586                }
13587            }
13588            if (!isCompact) {
13589                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13590                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13591                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13592                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13593                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13594                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13595                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13596                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13597                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13598                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13599                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13600            }
13601            if (!brief) {
13602                if (memInfo.getZramTotalSizeKb() != 0) {
13603                    if (!isCompact) {
13604                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13605                                pw.print(" kB physical used for ");
13606                                pw.print(memInfo.getSwapTotalSizeKb()
13607                                        - memInfo.getSwapFreeSizeKb());
13608                                pw.print(" kB in swap (");
13609                                pw.print(memInfo.getSwapTotalSizeKb());
13610                                pw.println(" kB total swap)");
13611                    } else {
13612                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13613                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13614                                pw.println(memInfo.getSwapFreeSizeKb());
13615                    }
13616                }
13617                final int[] SINGLE_LONG_FORMAT = new int[] {
13618                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13619                };
13620                long[] longOut = new long[1];
13621                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13622                        SINGLE_LONG_FORMAT, null, longOut, null);
13623                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13624                longOut[0] = 0;
13625                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13626                        SINGLE_LONG_FORMAT, null, longOut, null);
13627                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13628                longOut[0] = 0;
13629                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13630                        SINGLE_LONG_FORMAT, null, longOut, null);
13631                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13632                longOut[0] = 0;
13633                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13634                        SINGLE_LONG_FORMAT, null, longOut, null);
13635                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13636                if (!isCompact) {
13637                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13638                        pw.print("      KSM: "); pw.print(sharing);
13639                                pw.print(" kB saved from shared ");
13640                                pw.print(shared); pw.println(" kB");
13641                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13642                                pw.print(voltile); pw.println(" kB volatile");
13643                    }
13644                    pw.print("   Tuning: ");
13645                    pw.print(ActivityManager.staticGetMemoryClass());
13646                    pw.print(" (large ");
13647                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13648                    pw.print("), oom ");
13649                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13650                    pw.print(" kB");
13651                    pw.print(", restore limit ");
13652                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13653                    pw.print(" kB");
13654                    if (ActivityManager.isLowRamDeviceStatic()) {
13655                        pw.print(" (low-ram)");
13656                    }
13657                    if (ActivityManager.isHighEndGfx()) {
13658                        pw.print(" (high-end-gfx)");
13659                    }
13660                    pw.println();
13661                } else {
13662                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13663                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13664                    pw.println(voltile);
13665                    pw.print("tuning,");
13666                    pw.print(ActivityManager.staticGetMemoryClass());
13667                    pw.print(',');
13668                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13669                    pw.print(',');
13670                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13671                    if (ActivityManager.isLowRamDeviceStatic()) {
13672                        pw.print(",low-ram");
13673                    }
13674                    if (ActivityManager.isHighEndGfx()) {
13675                        pw.print(",high-end-gfx");
13676                    }
13677                    pw.println();
13678                }
13679            }
13680        }
13681    }
13682
13683    /**
13684     * Searches array of arguments for the specified string
13685     * @param args array of argument strings
13686     * @param value value to search for
13687     * @return true if the value is contained in the array
13688     */
13689    private static boolean scanArgs(String[] args, String value) {
13690        if (args != null) {
13691            for (String arg : args) {
13692                if (value.equals(arg)) {
13693                    return true;
13694                }
13695            }
13696        }
13697        return false;
13698    }
13699
13700    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13701            ContentProviderRecord cpr, boolean always) {
13702        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13703
13704        if (!inLaunching || always) {
13705            synchronized (cpr) {
13706                cpr.launchingApp = null;
13707                cpr.notifyAll();
13708            }
13709            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13710            String names[] = cpr.info.authority.split(";");
13711            for (int j = 0; j < names.length; j++) {
13712                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13713            }
13714        }
13715
13716        for (int i=0; i<cpr.connections.size(); i++) {
13717            ContentProviderConnection conn = cpr.connections.get(i);
13718            if (conn.waiting) {
13719                // If this connection is waiting for the provider, then we don't
13720                // need to mess with its process unless we are always removing
13721                // or for some reason the provider is not currently launching.
13722                if (inLaunching && !always) {
13723                    continue;
13724                }
13725            }
13726            ProcessRecord capp = conn.client;
13727            conn.dead = true;
13728            if (conn.stableCount > 0) {
13729                if (!capp.persistent && capp.thread != null
13730                        && capp.pid != 0
13731                        && capp.pid != MY_PID) {
13732                    capp.kill("depends on provider "
13733                            + cpr.name.flattenToShortString()
13734                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
13735                }
13736            } else if (capp.thread != null && conn.provider.provider != null) {
13737                try {
13738                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13739                } catch (RemoteException e) {
13740                }
13741                // In the protocol here, we don't expect the client to correctly
13742                // clean up this connection, we'll just remove it.
13743                cpr.connections.remove(i);
13744                conn.client.conProviders.remove(conn);
13745            }
13746        }
13747
13748        if (inLaunching && always) {
13749            mLaunchingProviders.remove(cpr);
13750        }
13751        return inLaunching;
13752    }
13753
13754    /**
13755     * Main code for cleaning up a process when it has gone away.  This is
13756     * called both as a result of the process dying, or directly when stopping
13757     * a process when running in single process mode.
13758     */
13759    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13760            boolean restarting, boolean allowRestart, int index) {
13761        if (index >= 0) {
13762            removeLruProcessLocked(app);
13763            ProcessList.remove(app.pid);
13764        }
13765
13766        mProcessesToGc.remove(app);
13767        mPendingPssProcesses.remove(app);
13768
13769        // Dismiss any open dialogs.
13770        if (app.crashDialog != null && !app.forceCrashReport) {
13771            app.crashDialog.dismiss();
13772            app.crashDialog = null;
13773        }
13774        if (app.anrDialog != null) {
13775            app.anrDialog.dismiss();
13776            app.anrDialog = null;
13777        }
13778        if (app.waitDialog != null) {
13779            app.waitDialog.dismiss();
13780            app.waitDialog = null;
13781        }
13782
13783        app.crashing = false;
13784        app.notResponding = false;
13785
13786        app.resetPackageList(mProcessStats);
13787        app.unlinkDeathRecipient();
13788        app.makeInactive(mProcessStats);
13789        app.waitingToKill = null;
13790        app.forcingToForeground = null;
13791        updateProcessForegroundLocked(app, false, false);
13792        app.foregroundActivities = false;
13793        app.hasShownUi = false;
13794        app.treatLikeActivity = false;
13795        app.hasAboveClient = false;
13796        app.hasClientActivities = false;
13797
13798        mServices.killServicesLocked(app, allowRestart);
13799
13800        boolean restart = false;
13801
13802        // Remove published content providers.
13803        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13804            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13805            final boolean always = app.bad || !allowRestart;
13806            if (removeDyingProviderLocked(app, cpr, always) || always) {
13807                // We left the provider in the launching list, need to
13808                // restart it.
13809                restart = true;
13810            }
13811
13812            cpr.provider = null;
13813            cpr.proc = null;
13814        }
13815        app.pubProviders.clear();
13816
13817        // Take care of any launching providers waiting for this process.
13818        if (checkAppInLaunchingProvidersLocked(app, false)) {
13819            restart = true;
13820        }
13821
13822        // Unregister from connected content providers.
13823        if (!app.conProviders.isEmpty()) {
13824            for (int i=0; i<app.conProviders.size(); i++) {
13825                ContentProviderConnection conn = app.conProviders.get(i);
13826                conn.provider.connections.remove(conn);
13827            }
13828            app.conProviders.clear();
13829        }
13830
13831        // At this point there may be remaining entries in mLaunchingProviders
13832        // where we were the only one waiting, so they are no longer of use.
13833        // Look for these and clean up if found.
13834        // XXX Commented out for now.  Trying to figure out a way to reproduce
13835        // the actual situation to identify what is actually going on.
13836        if (false) {
13837            for (int i=0; i<mLaunchingProviders.size(); i++) {
13838                ContentProviderRecord cpr = (ContentProviderRecord)
13839                        mLaunchingProviders.get(i);
13840                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13841                    synchronized (cpr) {
13842                        cpr.launchingApp = null;
13843                        cpr.notifyAll();
13844                    }
13845                }
13846            }
13847        }
13848
13849        skipCurrentReceiverLocked(app);
13850
13851        // Unregister any receivers.
13852        for (int i=app.receivers.size()-1; i>=0; i--) {
13853            removeReceiverLocked(app.receivers.valueAt(i));
13854        }
13855        app.receivers.clear();
13856
13857        // If the app is undergoing backup, tell the backup manager about it
13858        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13859            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13860                    + mBackupTarget.appInfo + " died during backup");
13861            try {
13862                IBackupManager bm = IBackupManager.Stub.asInterface(
13863                        ServiceManager.getService(Context.BACKUP_SERVICE));
13864                bm.agentDisconnected(app.info.packageName);
13865            } catch (RemoteException e) {
13866                // can't happen; backup manager is local
13867            }
13868        }
13869
13870        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13871            ProcessChangeItem item = mPendingProcessChanges.get(i);
13872            if (item.pid == app.pid) {
13873                mPendingProcessChanges.remove(i);
13874                mAvailProcessChanges.add(item);
13875            }
13876        }
13877        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13878
13879        // If the caller is restarting this app, then leave it in its
13880        // current lists and let the caller take care of it.
13881        if (restarting) {
13882            return;
13883        }
13884
13885        if (!app.persistent || app.isolated) {
13886            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13887                    "Removing non-persistent process during cleanup: " + app);
13888            mProcessNames.remove(app.processName, app.uid);
13889            mIsolatedProcesses.remove(app.uid);
13890            if (mHeavyWeightProcess == app) {
13891                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13892                        mHeavyWeightProcess.userId, 0));
13893                mHeavyWeightProcess = null;
13894            }
13895        } else if (!app.removed) {
13896            // This app is persistent, so we need to keep its record around.
13897            // If it is not already on the pending app list, add it there
13898            // and start a new process for it.
13899            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13900                mPersistentStartingProcesses.add(app);
13901                restart = true;
13902            }
13903        }
13904        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13905                "Clean-up removing on hold: " + app);
13906        mProcessesOnHold.remove(app);
13907
13908        if (app == mHomeProcess) {
13909            mHomeProcess = null;
13910        }
13911        if (app == mPreviousProcess) {
13912            mPreviousProcess = null;
13913        }
13914
13915        if (restart && !app.isolated) {
13916            // We have components that still need to be running in the
13917            // process, so re-launch it.
13918            mProcessNames.put(app.processName, app.uid, app);
13919            startProcessLocked(app, "restart", app.processName);
13920        } else if (app.pid > 0 && app.pid != MY_PID) {
13921            // Goodbye!
13922            boolean removed;
13923            synchronized (mPidsSelfLocked) {
13924                mPidsSelfLocked.remove(app.pid);
13925                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13926            }
13927            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13928            if (app.isolated) {
13929                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13930            }
13931            app.setPid(0);
13932        }
13933    }
13934
13935    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13936        // Look through the content providers we are waiting to have launched,
13937        // and if any run in this process then either schedule a restart of
13938        // the process or kill the client waiting for it if this process has
13939        // gone bad.
13940        int NL = mLaunchingProviders.size();
13941        boolean restart = false;
13942        for (int i=0; i<NL; i++) {
13943            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13944            if (cpr.launchingApp == app) {
13945                if (!alwaysBad && !app.bad) {
13946                    restart = true;
13947                } else {
13948                    removeDyingProviderLocked(app, cpr, true);
13949                    // cpr should have been removed from mLaunchingProviders
13950                    NL = mLaunchingProviders.size();
13951                    i--;
13952                }
13953            }
13954        }
13955        return restart;
13956    }
13957
13958    // =========================================================
13959    // SERVICES
13960    // =========================================================
13961
13962    @Override
13963    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13964            int flags) {
13965        enforceNotIsolatedCaller("getServices");
13966        synchronized (this) {
13967            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13968        }
13969    }
13970
13971    @Override
13972    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13973        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13974        synchronized (this) {
13975            return mServices.getRunningServiceControlPanelLocked(name);
13976        }
13977    }
13978
13979    @Override
13980    public ComponentName startService(IApplicationThread caller, Intent service,
13981            String resolvedType, int userId) {
13982        enforceNotIsolatedCaller("startService");
13983        // Refuse possible leaked file descriptors
13984        if (service != null && service.hasFileDescriptors() == true) {
13985            throw new IllegalArgumentException("File descriptors passed in Intent");
13986        }
13987
13988        if (DEBUG_SERVICE)
13989            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13990        synchronized(this) {
13991            final int callingPid = Binder.getCallingPid();
13992            final int callingUid = Binder.getCallingUid();
13993            final long origId = Binder.clearCallingIdentity();
13994            ComponentName res = mServices.startServiceLocked(caller, service,
13995                    resolvedType, callingPid, callingUid, userId);
13996            Binder.restoreCallingIdentity(origId);
13997            return res;
13998        }
13999    }
14000
14001    ComponentName startServiceInPackage(int uid,
14002            Intent service, String resolvedType, int userId) {
14003        synchronized(this) {
14004            if (DEBUG_SERVICE)
14005                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14006            final long origId = Binder.clearCallingIdentity();
14007            ComponentName res = mServices.startServiceLocked(null, service,
14008                    resolvedType, -1, uid, userId);
14009            Binder.restoreCallingIdentity(origId);
14010            return res;
14011        }
14012    }
14013
14014    @Override
14015    public int stopService(IApplicationThread caller, Intent service,
14016            String resolvedType, int userId) {
14017        enforceNotIsolatedCaller("stopService");
14018        // Refuse possible leaked file descriptors
14019        if (service != null && service.hasFileDescriptors() == true) {
14020            throw new IllegalArgumentException("File descriptors passed in Intent");
14021        }
14022
14023        synchronized(this) {
14024            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14025        }
14026    }
14027
14028    @Override
14029    public IBinder peekService(Intent service, String resolvedType) {
14030        enforceNotIsolatedCaller("peekService");
14031        // Refuse possible leaked file descriptors
14032        if (service != null && service.hasFileDescriptors() == true) {
14033            throw new IllegalArgumentException("File descriptors passed in Intent");
14034        }
14035        synchronized(this) {
14036            return mServices.peekServiceLocked(service, resolvedType);
14037        }
14038    }
14039
14040    @Override
14041    public boolean stopServiceToken(ComponentName className, IBinder token,
14042            int startId) {
14043        synchronized(this) {
14044            return mServices.stopServiceTokenLocked(className, token, startId);
14045        }
14046    }
14047
14048    @Override
14049    public void setServiceForeground(ComponentName className, IBinder token,
14050            int id, Notification notification, boolean removeNotification) {
14051        synchronized(this) {
14052            mServices.setServiceForegroundLocked(className, token, id, notification,
14053                    removeNotification);
14054        }
14055    }
14056
14057    @Override
14058    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14059            boolean requireFull, String name, String callerPackage) {
14060        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14061                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14062    }
14063
14064    int unsafeConvertIncomingUser(int userId) {
14065        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14066                ? mCurrentUserId : userId;
14067    }
14068
14069    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14070            int allowMode, String name, String callerPackage) {
14071        final int callingUserId = UserHandle.getUserId(callingUid);
14072        if (callingUserId == userId) {
14073            return userId;
14074        }
14075
14076        // Note that we may be accessing mCurrentUserId outside of a lock...
14077        // shouldn't be a big deal, if this is being called outside
14078        // of a locked context there is intrinsically a race with
14079        // the value the caller will receive and someone else changing it.
14080        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14081        // we will switch to the calling user if access to the current user fails.
14082        int targetUserId = unsafeConvertIncomingUser(userId);
14083
14084        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14085            final boolean allow;
14086            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14087                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14088                // If the caller has this permission, they always pass go.  And collect $200.
14089                allow = true;
14090            } else if (allowMode == ALLOW_FULL_ONLY) {
14091                // We require full access, sucks to be you.
14092                allow = false;
14093            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14094                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14095                // If the caller does not have either permission, they are always doomed.
14096                allow = false;
14097            } else if (allowMode == ALLOW_NON_FULL) {
14098                // We are blanket allowing non-full access, you lucky caller!
14099                allow = true;
14100            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14101                // We may or may not allow this depending on whether the two users are
14102                // in the same profile.
14103                synchronized (mUserProfileGroupIdsSelfLocked) {
14104                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14105                            UserInfo.NO_PROFILE_GROUP_ID);
14106                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14107                            UserInfo.NO_PROFILE_GROUP_ID);
14108                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14109                            && callingProfile == targetProfile;
14110                }
14111            } else {
14112                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14113            }
14114            if (!allow) {
14115                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14116                    // In this case, they would like to just execute as their
14117                    // owner user instead of failing.
14118                    targetUserId = callingUserId;
14119                } else {
14120                    StringBuilder builder = new StringBuilder(128);
14121                    builder.append("Permission Denial: ");
14122                    builder.append(name);
14123                    if (callerPackage != null) {
14124                        builder.append(" from ");
14125                        builder.append(callerPackage);
14126                    }
14127                    builder.append(" asks to run as user ");
14128                    builder.append(userId);
14129                    builder.append(" but is calling from user ");
14130                    builder.append(UserHandle.getUserId(callingUid));
14131                    builder.append("; this requires ");
14132                    builder.append(INTERACT_ACROSS_USERS_FULL);
14133                    if (allowMode != ALLOW_FULL_ONLY) {
14134                        builder.append(" or ");
14135                        builder.append(INTERACT_ACROSS_USERS);
14136                    }
14137                    String msg = builder.toString();
14138                    Slog.w(TAG, msg);
14139                    throw new SecurityException(msg);
14140                }
14141            }
14142        }
14143        if (!allowAll && targetUserId < 0) {
14144            throw new IllegalArgumentException(
14145                    "Call does not support special user #" + targetUserId);
14146        }
14147        return targetUserId;
14148    }
14149
14150    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14151            String className, int flags) {
14152        boolean result = false;
14153        // For apps that don't have pre-defined UIDs, check for permission
14154        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14155            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14156                if (ActivityManager.checkUidPermission(
14157                        INTERACT_ACROSS_USERS,
14158                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14159                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14160                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14161                            + " requests FLAG_SINGLE_USER, but app does not hold "
14162                            + INTERACT_ACROSS_USERS;
14163                    Slog.w(TAG, msg);
14164                    throw new SecurityException(msg);
14165                }
14166                // Permission passed
14167                result = true;
14168            }
14169        } else if ("system".equals(componentProcessName)) {
14170            result = true;
14171        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14172                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14173            // Phone app is allowed to export singleuser providers.
14174            result = true;
14175        } else {
14176            // App with pre-defined UID, check if it's a persistent app
14177            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14178        }
14179        if (DEBUG_MU) {
14180            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14181                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14182        }
14183        return result;
14184    }
14185
14186    /**
14187     * Checks to see if the caller is in the same app as the singleton
14188     * component, or the component is in a special app. It allows special apps
14189     * to export singleton components but prevents exporting singleton
14190     * components for regular apps.
14191     */
14192    boolean isValidSingletonCall(int callingUid, int componentUid) {
14193        int componentAppId = UserHandle.getAppId(componentUid);
14194        return UserHandle.isSameApp(callingUid, componentUid)
14195                || componentAppId == Process.SYSTEM_UID
14196                || componentAppId == Process.PHONE_UID
14197                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14198                        == PackageManager.PERMISSION_GRANTED;
14199    }
14200
14201    public int bindService(IApplicationThread caller, IBinder token,
14202            Intent service, String resolvedType,
14203            IServiceConnection connection, int flags, int userId) {
14204        enforceNotIsolatedCaller("bindService");
14205        // Refuse possible leaked file descriptors
14206        if (service != null && service.hasFileDescriptors() == true) {
14207            throw new IllegalArgumentException("File descriptors passed in Intent");
14208        }
14209
14210        synchronized(this) {
14211            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14212                    connection, flags, userId);
14213        }
14214    }
14215
14216    public boolean unbindService(IServiceConnection connection) {
14217        synchronized (this) {
14218            return mServices.unbindServiceLocked(connection);
14219        }
14220    }
14221
14222    public void publishService(IBinder token, Intent intent, IBinder service) {
14223        // Refuse possible leaked file descriptors
14224        if (intent != null && intent.hasFileDescriptors() == true) {
14225            throw new IllegalArgumentException("File descriptors passed in Intent");
14226        }
14227
14228        synchronized(this) {
14229            if (!(token instanceof ServiceRecord)) {
14230                throw new IllegalArgumentException("Invalid service token");
14231            }
14232            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14233        }
14234    }
14235
14236    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14237        // Refuse possible leaked file descriptors
14238        if (intent != null && intent.hasFileDescriptors() == true) {
14239            throw new IllegalArgumentException("File descriptors passed in Intent");
14240        }
14241
14242        synchronized(this) {
14243            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14244        }
14245    }
14246
14247    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14248        synchronized(this) {
14249            if (!(token instanceof ServiceRecord)) {
14250                throw new IllegalArgumentException("Invalid service token");
14251            }
14252            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14253        }
14254    }
14255
14256    // =========================================================
14257    // BACKUP AND RESTORE
14258    // =========================================================
14259
14260    // Cause the target app to be launched if necessary and its backup agent
14261    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14262    // activity manager to announce its creation.
14263    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14264        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14265        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14266
14267        synchronized(this) {
14268            // !!! TODO: currently no check here that we're already bound
14269            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14270            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14271            synchronized (stats) {
14272                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14273            }
14274
14275            // Backup agent is now in use, its package can't be stopped.
14276            try {
14277                AppGlobals.getPackageManager().setPackageStoppedState(
14278                        app.packageName, false, UserHandle.getUserId(app.uid));
14279            } catch (RemoteException e) {
14280            } catch (IllegalArgumentException e) {
14281                Slog.w(TAG, "Failed trying to unstop package "
14282                        + app.packageName + ": " + e);
14283            }
14284
14285            BackupRecord r = new BackupRecord(ss, app, backupMode);
14286            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14287                    ? new ComponentName(app.packageName, app.backupAgentName)
14288                    : new ComponentName("android", "FullBackupAgent");
14289            // startProcessLocked() returns existing proc's record if it's already running
14290            ProcessRecord proc = startProcessLocked(app.processName, app,
14291                    false, 0, "backup", hostingName, false, false, false);
14292            if (proc == null) {
14293                Slog.e(TAG, "Unable to start backup agent process " + r);
14294                return false;
14295            }
14296
14297            r.app = proc;
14298            mBackupTarget = r;
14299            mBackupAppName = app.packageName;
14300
14301            // Try not to kill the process during backup
14302            updateOomAdjLocked(proc);
14303
14304            // If the process is already attached, schedule the creation of the backup agent now.
14305            // If it is not yet live, this will be done when it attaches to the framework.
14306            if (proc.thread != null) {
14307                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14308                try {
14309                    proc.thread.scheduleCreateBackupAgent(app,
14310                            compatibilityInfoForPackageLocked(app), backupMode);
14311                } catch (RemoteException e) {
14312                    // Will time out on the backup manager side
14313                }
14314            } else {
14315                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14316            }
14317            // Invariants: at this point, the target app process exists and the application
14318            // is either already running or in the process of coming up.  mBackupTarget and
14319            // mBackupAppName describe the app, so that when it binds back to the AM we
14320            // know that it's scheduled for a backup-agent operation.
14321        }
14322
14323        return true;
14324    }
14325
14326    @Override
14327    public void clearPendingBackup() {
14328        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14329        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14330
14331        synchronized (this) {
14332            mBackupTarget = null;
14333            mBackupAppName = null;
14334        }
14335    }
14336
14337    // A backup agent has just come up
14338    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14339        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14340                + " = " + agent);
14341
14342        synchronized(this) {
14343            if (!agentPackageName.equals(mBackupAppName)) {
14344                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14345                return;
14346            }
14347        }
14348
14349        long oldIdent = Binder.clearCallingIdentity();
14350        try {
14351            IBackupManager bm = IBackupManager.Stub.asInterface(
14352                    ServiceManager.getService(Context.BACKUP_SERVICE));
14353            bm.agentConnected(agentPackageName, agent);
14354        } catch (RemoteException e) {
14355            // can't happen; the backup manager service is local
14356        } catch (Exception e) {
14357            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14358            e.printStackTrace();
14359        } finally {
14360            Binder.restoreCallingIdentity(oldIdent);
14361        }
14362    }
14363
14364    // done with this agent
14365    public void unbindBackupAgent(ApplicationInfo appInfo) {
14366        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14367        if (appInfo == null) {
14368            Slog.w(TAG, "unbind backup agent for null app");
14369            return;
14370        }
14371
14372        synchronized(this) {
14373            try {
14374                if (mBackupAppName == null) {
14375                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14376                    return;
14377                }
14378
14379                if (!mBackupAppName.equals(appInfo.packageName)) {
14380                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14381                    return;
14382                }
14383
14384                // Not backing this app up any more; reset its OOM adjustment
14385                final ProcessRecord proc = mBackupTarget.app;
14386                updateOomAdjLocked(proc);
14387
14388                // If the app crashed during backup, 'thread' will be null here
14389                if (proc.thread != null) {
14390                    try {
14391                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14392                                compatibilityInfoForPackageLocked(appInfo));
14393                    } catch (Exception e) {
14394                        Slog.e(TAG, "Exception when unbinding backup agent:");
14395                        e.printStackTrace();
14396                    }
14397                }
14398            } finally {
14399                mBackupTarget = null;
14400                mBackupAppName = null;
14401            }
14402        }
14403    }
14404    // =========================================================
14405    // BROADCASTS
14406    // =========================================================
14407
14408    private final List getStickiesLocked(String action, IntentFilter filter,
14409            List cur, int userId) {
14410        final ContentResolver resolver = mContext.getContentResolver();
14411        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14412        if (stickies == null) {
14413            return cur;
14414        }
14415        final ArrayList<Intent> list = stickies.get(action);
14416        if (list == null) {
14417            return cur;
14418        }
14419        int N = list.size();
14420        for (int i=0; i<N; i++) {
14421            Intent intent = list.get(i);
14422            if (filter.match(resolver, intent, true, TAG) >= 0) {
14423                if (cur == null) {
14424                    cur = new ArrayList<Intent>();
14425                }
14426                cur.add(intent);
14427            }
14428        }
14429        return cur;
14430    }
14431
14432    boolean isPendingBroadcastProcessLocked(int pid) {
14433        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14434                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14435    }
14436
14437    void skipPendingBroadcastLocked(int pid) {
14438            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14439            for (BroadcastQueue queue : mBroadcastQueues) {
14440                queue.skipPendingBroadcastLocked(pid);
14441            }
14442    }
14443
14444    // The app just attached; send any pending broadcasts that it should receive
14445    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14446        boolean didSomething = false;
14447        for (BroadcastQueue queue : mBroadcastQueues) {
14448            didSomething |= queue.sendPendingBroadcastsLocked(app);
14449        }
14450        return didSomething;
14451    }
14452
14453    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14454            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14455        enforceNotIsolatedCaller("registerReceiver");
14456        int callingUid;
14457        int callingPid;
14458        synchronized(this) {
14459            ProcessRecord callerApp = null;
14460            if (caller != null) {
14461                callerApp = getRecordForAppLocked(caller);
14462                if (callerApp == null) {
14463                    throw new SecurityException(
14464                            "Unable to find app for caller " + caller
14465                            + " (pid=" + Binder.getCallingPid()
14466                            + ") when registering receiver " + receiver);
14467                }
14468                if (callerApp.info.uid != Process.SYSTEM_UID &&
14469                        !callerApp.pkgList.containsKey(callerPackage) &&
14470                        !"android".equals(callerPackage)) {
14471                    throw new SecurityException("Given caller package " + callerPackage
14472                            + " is not running in process " + callerApp);
14473                }
14474                callingUid = callerApp.info.uid;
14475                callingPid = callerApp.pid;
14476            } else {
14477                callerPackage = null;
14478                callingUid = Binder.getCallingUid();
14479                callingPid = Binder.getCallingPid();
14480            }
14481
14482            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14483                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14484
14485            List allSticky = null;
14486
14487            // Look for any matching sticky broadcasts...
14488            Iterator actions = filter.actionsIterator();
14489            if (actions != null) {
14490                while (actions.hasNext()) {
14491                    String action = (String)actions.next();
14492                    allSticky = getStickiesLocked(action, filter, allSticky,
14493                            UserHandle.USER_ALL);
14494                    allSticky = getStickiesLocked(action, filter, allSticky,
14495                            UserHandle.getUserId(callingUid));
14496                }
14497            } else {
14498                allSticky = getStickiesLocked(null, filter, allSticky,
14499                        UserHandle.USER_ALL);
14500                allSticky = getStickiesLocked(null, filter, allSticky,
14501                        UserHandle.getUserId(callingUid));
14502            }
14503
14504            // The first sticky in the list is returned directly back to
14505            // the client.
14506            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14507
14508            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14509                    + ": " + sticky);
14510
14511            if (receiver == null) {
14512                return sticky;
14513            }
14514
14515            ReceiverList rl
14516                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14517            if (rl == null) {
14518                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14519                        userId, receiver);
14520                if (rl.app != null) {
14521                    rl.app.receivers.add(rl);
14522                } else {
14523                    try {
14524                        receiver.asBinder().linkToDeath(rl, 0);
14525                    } catch (RemoteException e) {
14526                        return sticky;
14527                    }
14528                    rl.linkedToDeath = true;
14529                }
14530                mRegisteredReceivers.put(receiver.asBinder(), rl);
14531            } else if (rl.uid != callingUid) {
14532                throw new IllegalArgumentException(
14533                        "Receiver requested to register for uid " + callingUid
14534                        + " was previously registered for uid " + rl.uid);
14535            } else if (rl.pid != callingPid) {
14536                throw new IllegalArgumentException(
14537                        "Receiver requested to register for pid " + callingPid
14538                        + " was previously registered for pid " + rl.pid);
14539            } else if (rl.userId != userId) {
14540                throw new IllegalArgumentException(
14541                        "Receiver requested to register for user " + userId
14542                        + " was previously registered for user " + rl.userId);
14543            }
14544            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14545                    permission, callingUid, userId);
14546            rl.add(bf);
14547            if (!bf.debugCheck()) {
14548                Slog.w(TAG, "==> For Dynamic broadast");
14549            }
14550            mReceiverResolver.addFilter(bf);
14551
14552            // Enqueue broadcasts for all existing stickies that match
14553            // this filter.
14554            if (allSticky != null) {
14555                ArrayList receivers = new ArrayList();
14556                receivers.add(bf);
14557
14558                int N = allSticky.size();
14559                for (int i=0; i<N; i++) {
14560                    Intent intent = (Intent)allSticky.get(i);
14561                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14562                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14563                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14564                            null, null, false, true, true, -1);
14565                    queue.enqueueParallelBroadcastLocked(r);
14566                    queue.scheduleBroadcastsLocked();
14567                }
14568            }
14569
14570            return sticky;
14571        }
14572    }
14573
14574    public void unregisterReceiver(IIntentReceiver receiver) {
14575        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14576
14577        final long origId = Binder.clearCallingIdentity();
14578        try {
14579            boolean doTrim = false;
14580
14581            synchronized(this) {
14582                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14583                if (rl != null) {
14584                    if (rl.curBroadcast != null) {
14585                        BroadcastRecord r = rl.curBroadcast;
14586                        final boolean doNext = finishReceiverLocked(
14587                                receiver.asBinder(), r.resultCode, r.resultData,
14588                                r.resultExtras, r.resultAbort);
14589                        if (doNext) {
14590                            doTrim = true;
14591                            r.queue.processNextBroadcast(false);
14592                        }
14593                    }
14594
14595                    if (rl.app != null) {
14596                        rl.app.receivers.remove(rl);
14597                    }
14598                    removeReceiverLocked(rl);
14599                    if (rl.linkedToDeath) {
14600                        rl.linkedToDeath = false;
14601                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14602                    }
14603                }
14604            }
14605
14606            // If we actually concluded any broadcasts, we might now be able
14607            // to trim the recipients' apps from our working set
14608            if (doTrim) {
14609                trimApplications();
14610                return;
14611            }
14612
14613        } finally {
14614            Binder.restoreCallingIdentity(origId);
14615        }
14616    }
14617
14618    void removeReceiverLocked(ReceiverList rl) {
14619        mRegisteredReceivers.remove(rl.receiver.asBinder());
14620        int N = rl.size();
14621        for (int i=0; i<N; i++) {
14622            mReceiverResolver.removeFilter(rl.get(i));
14623        }
14624    }
14625
14626    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14627        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14628            ProcessRecord r = mLruProcesses.get(i);
14629            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14630                try {
14631                    r.thread.dispatchPackageBroadcast(cmd, packages);
14632                } catch (RemoteException ex) {
14633                }
14634            }
14635        }
14636    }
14637
14638    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14639            int[] users) {
14640        List<ResolveInfo> receivers = null;
14641        try {
14642            HashSet<ComponentName> singleUserReceivers = null;
14643            boolean scannedFirstReceivers = false;
14644            for (int user : users) {
14645                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14646                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14647                if (user != 0 && newReceivers != null) {
14648                    // If this is not the primary user, we need to check for
14649                    // any receivers that should be filtered out.
14650                    for (int i=0; i<newReceivers.size(); i++) {
14651                        ResolveInfo ri = newReceivers.get(i);
14652                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14653                            newReceivers.remove(i);
14654                            i--;
14655                        }
14656                    }
14657                }
14658                if (newReceivers != null && newReceivers.size() == 0) {
14659                    newReceivers = null;
14660                }
14661                if (receivers == null) {
14662                    receivers = newReceivers;
14663                } else if (newReceivers != null) {
14664                    // We need to concatenate the additional receivers
14665                    // found with what we have do far.  This would be easy,
14666                    // but we also need to de-dup any receivers that are
14667                    // singleUser.
14668                    if (!scannedFirstReceivers) {
14669                        // Collect any single user receivers we had already retrieved.
14670                        scannedFirstReceivers = true;
14671                        for (int i=0; i<receivers.size(); i++) {
14672                            ResolveInfo ri = receivers.get(i);
14673                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14674                                ComponentName cn = new ComponentName(
14675                                        ri.activityInfo.packageName, ri.activityInfo.name);
14676                                if (singleUserReceivers == null) {
14677                                    singleUserReceivers = new HashSet<ComponentName>();
14678                                }
14679                                singleUserReceivers.add(cn);
14680                            }
14681                        }
14682                    }
14683                    // Add the new results to the existing results, tracking
14684                    // and de-dupping single user receivers.
14685                    for (int i=0; i<newReceivers.size(); i++) {
14686                        ResolveInfo ri = newReceivers.get(i);
14687                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14688                            ComponentName cn = new ComponentName(
14689                                    ri.activityInfo.packageName, ri.activityInfo.name);
14690                            if (singleUserReceivers == null) {
14691                                singleUserReceivers = new HashSet<ComponentName>();
14692                            }
14693                            if (!singleUserReceivers.contains(cn)) {
14694                                singleUserReceivers.add(cn);
14695                                receivers.add(ri);
14696                            }
14697                        } else {
14698                            receivers.add(ri);
14699                        }
14700                    }
14701                }
14702            }
14703        } catch (RemoteException ex) {
14704            // pm is in same process, this will never happen.
14705        }
14706        return receivers;
14707    }
14708
14709    private final int broadcastIntentLocked(ProcessRecord callerApp,
14710            String callerPackage, Intent intent, String resolvedType,
14711            IIntentReceiver resultTo, int resultCode, String resultData,
14712            Bundle map, String requiredPermission, int appOp,
14713            boolean ordered, boolean sticky, int callingPid, int callingUid,
14714            int userId) {
14715        intent = new Intent(intent);
14716
14717        // By default broadcasts do not go to stopped apps.
14718        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14719
14720        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14721            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14722            + " ordered=" + ordered + " userid=" + userId);
14723        if ((resultTo != null) && !ordered) {
14724            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14725        }
14726
14727        userId = handleIncomingUser(callingPid, callingUid, userId,
14728                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14729
14730        // Make sure that the user who is receiving this broadcast is started.
14731        // If not, we will just skip it.
14732
14733
14734        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14735            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14736                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14737                Slog.w(TAG, "Skipping broadcast of " + intent
14738                        + ": user " + userId + " is stopped");
14739                return ActivityManager.BROADCAST_SUCCESS;
14740            }
14741        }
14742
14743        /*
14744         * Prevent non-system code (defined here to be non-persistent
14745         * processes) from sending protected broadcasts.
14746         */
14747        int callingAppId = UserHandle.getAppId(callingUid);
14748        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14749            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14750            || callingAppId == Process.NFC_UID || callingUid == 0) {
14751            // Always okay.
14752        } else if (callerApp == null || !callerApp.persistent) {
14753            try {
14754                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14755                        intent.getAction())) {
14756                    String msg = "Permission Denial: not allowed to send broadcast "
14757                            + intent.getAction() + " from pid="
14758                            + callingPid + ", uid=" + callingUid;
14759                    Slog.w(TAG, msg);
14760                    throw new SecurityException(msg);
14761                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14762                    // Special case for compatibility: we don't want apps to send this,
14763                    // but historically it has not been protected and apps may be using it
14764                    // to poke their own app widget.  So, instead of making it protected,
14765                    // just limit it to the caller.
14766                    if (callerApp == null) {
14767                        String msg = "Permission Denial: not allowed to send broadcast "
14768                                + intent.getAction() + " from unknown caller.";
14769                        Slog.w(TAG, msg);
14770                        throw new SecurityException(msg);
14771                    } else if (intent.getComponent() != null) {
14772                        // They are good enough to send to an explicit component...  verify
14773                        // it is being sent to the calling app.
14774                        if (!intent.getComponent().getPackageName().equals(
14775                                callerApp.info.packageName)) {
14776                            String msg = "Permission Denial: not allowed to send broadcast "
14777                                    + intent.getAction() + " to "
14778                                    + intent.getComponent().getPackageName() + " from "
14779                                    + callerApp.info.packageName;
14780                            Slog.w(TAG, msg);
14781                            throw new SecurityException(msg);
14782                        }
14783                    } else {
14784                        // Limit broadcast to their own package.
14785                        intent.setPackage(callerApp.info.packageName);
14786                    }
14787                }
14788            } catch (RemoteException e) {
14789                Slog.w(TAG, "Remote exception", e);
14790                return ActivityManager.BROADCAST_SUCCESS;
14791            }
14792        }
14793
14794        // Handle special intents: if this broadcast is from the package
14795        // manager about a package being removed, we need to remove all of
14796        // its activities from the history stack.
14797        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14798                intent.getAction());
14799        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14800                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14801                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14802                || uidRemoved) {
14803            if (checkComponentPermission(
14804                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14805                    callingPid, callingUid, -1, true)
14806                    == PackageManager.PERMISSION_GRANTED) {
14807                if (uidRemoved) {
14808                    final Bundle intentExtras = intent.getExtras();
14809                    final int uid = intentExtras != null
14810                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14811                    if (uid >= 0) {
14812                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14813                        synchronized (bs) {
14814                            bs.removeUidStatsLocked(uid);
14815                        }
14816                        mAppOpsService.uidRemoved(uid);
14817                    }
14818                } else {
14819                    // If resources are unavailable just force stop all
14820                    // those packages and flush the attribute cache as well.
14821                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14822                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14823                        if (list != null && (list.length > 0)) {
14824                            for (String pkg : list) {
14825                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14826                                        "storage unmount");
14827                            }
14828                            sendPackageBroadcastLocked(
14829                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14830                        }
14831                    } else {
14832                        Uri data = intent.getData();
14833                        String ssp;
14834                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14835                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14836                                    intent.getAction());
14837                            boolean fullUninstall = removed &&
14838                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14839                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14840                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14841                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14842                                        false, fullUninstall, userId,
14843                                        removed ? "pkg removed" : "pkg changed");
14844                            }
14845                            if (removed) {
14846                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14847                                        new String[] {ssp}, userId);
14848                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14849                                    mAppOpsService.packageRemoved(
14850                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14851
14852                                    // Remove all permissions granted from/to this package
14853                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14854                                }
14855                            }
14856                        }
14857                    }
14858                }
14859            } else {
14860                String msg = "Permission Denial: " + intent.getAction()
14861                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14862                        + ", uid=" + callingUid + ")"
14863                        + " requires "
14864                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14865                Slog.w(TAG, msg);
14866                throw new SecurityException(msg);
14867            }
14868
14869        // Special case for adding a package: by default turn on compatibility
14870        // mode.
14871        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14872            Uri data = intent.getData();
14873            String ssp;
14874            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14875                mCompatModePackages.handlePackageAddedLocked(ssp,
14876                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14877            }
14878        }
14879
14880        /*
14881         * If this is the time zone changed action, queue up a message that will reset the timezone
14882         * of all currently running processes. This message will get queued up before the broadcast
14883         * happens.
14884         */
14885        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14886            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14887        }
14888
14889        /*
14890         * If the user set the time, let all running processes know.
14891         */
14892        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14893            final int is24Hour = intent.getBooleanExtra(
14894                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14895            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14896        }
14897
14898        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14899            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14900        }
14901
14902        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14903            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14904            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14905        }
14906
14907        // Add to the sticky list if requested.
14908        if (sticky) {
14909            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14910                    callingPid, callingUid)
14911                    != PackageManager.PERMISSION_GRANTED) {
14912                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14913                        + callingPid + ", uid=" + callingUid
14914                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14915                Slog.w(TAG, msg);
14916                throw new SecurityException(msg);
14917            }
14918            if (requiredPermission != null) {
14919                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14920                        + " and enforce permission " + requiredPermission);
14921                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14922            }
14923            if (intent.getComponent() != null) {
14924                throw new SecurityException(
14925                        "Sticky broadcasts can't target a specific component");
14926            }
14927            // We use userId directly here, since the "all" target is maintained
14928            // as a separate set of sticky broadcasts.
14929            if (userId != UserHandle.USER_ALL) {
14930                // But first, if this is not a broadcast to all users, then
14931                // make sure it doesn't conflict with an existing broadcast to
14932                // all users.
14933                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14934                        UserHandle.USER_ALL);
14935                if (stickies != null) {
14936                    ArrayList<Intent> list = stickies.get(intent.getAction());
14937                    if (list != null) {
14938                        int N = list.size();
14939                        int i;
14940                        for (i=0; i<N; i++) {
14941                            if (intent.filterEquals(list.get(i))) {
14942                                throw new IllegalArgumentException(
14943                                        "Sticky broadcast " + intent + " for user "
14944                                        + userId + " conflicts with existing global broadcast");
14945                            }
14946                        }
14947                    }
14948                }
14949            }
14950            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14951            if (stickies == null) {
14952                stickies = new ArrayMap<String, ArrayList<Intent>>();
14953                mStickyBroadcasts.put(userId, stickies);
14954            }
14955            ArrayList<Intent> list = stickies.get(intent.getAction());
14956            if (list == null) {
14957                list = new ArrayList<Intent>();
14958                stickies.put(intent.getAction(), list);
14959            }
14960            int N = list.size();
14961            int i;
14962            for (i=0; i<N; i++) {
14963                if (intent.filterEquals(list.get(i))) {
14964                    // This sticky already exists, replace it.
14965                    list.set(i, new Intent(intent));
14966                    break;
14967                }
14968            }
14969            if (i >= N) {
14970                list.add(new Intent(intent));
14971            }
14972        }
14973
14974        int[] users;
14975        if (userId == UserHandle.USER_ALL) {
14976            // Caller wants broadcast to go to all started users.
14977            users = mStartedUserArray;
14978        } else {
14979            // Caller wants broadcast to go to one specific user.
14980            users = new int[] {userId};
14981        }
14982
14983        // Figure out who all will receive this broadcast.
14984        List receivers = null;
14985        List<BroadcastFilter> registeredReceivers = null;
14986        // Need to resolve the intent to interested receivers...
14987        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14988                 == 0) {
14989            receivers = collectReceiverComponents(intent, resolvedType, users);
14990        }
14991        if (intent.getComponent() == null) {
14992            registeredReceivers = mReceiverResolver.queryIntent(intent,
14993                    resolvedType, false, userId);
14994        }
14995
14996        final boolean replacePending =
14997                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14998
14999        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15000                + " replacePending=" + replacePending);
15001
15002        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15003        if (!ordered && NR > 0) {
15004            // If we are not serializing this broadcast, then send the
15005            // registered receivers separately so they don't wait for the
15006            // components to be launched.
15007            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15008            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15009                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15010                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15011                    ordered, sticky, false, userId);
15012            if (DEBUG_BROADCAST) Slog.v(
15013                    TAG, "Enqueueing parallel broadcast " + r);
15014            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15015            if (!replaced) {
15016                queue.enqueueParallelBroadcastLocked(r);
15017                queue.scheduleBroadcastsLocked();
15018            }
15019            registeredReceivers = null;
15020            NR = 0;
15021        }
15022
15023        // Merge into one list.
15024        int ir = 0;
15025        if (receivers != null) {
15026            // A special case for PACKAGE_ADDED: do not allow the package
15027            // being added to see this broadcast.  This prevents them from
15028            // using this as a back door to get run as soon as they are
15029            // installed.  Maybe in the future we want to have a special install
15030            // broadcast or such for apps, but we'd like to deliberately make
15031            // this decision.
15032            String skipPackages[] = null;
15033            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15034                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15035                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15036                Uri data = intent.getData();
15037                if (data != null) {
15038                    String pkgName = data.getSchemeSpecificPart();
15039                    if (pkgName != null) {
15040                        skipPackages = new String[] { pkgName };
15041                    }
15042                }
15043            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15044                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15045            }
15046            if (skipPackages != null && (skipPackages.length > 0)) {
15047                for (String skipPackage : skipPackages) {
15048                    if (skipPackage != null) {
15049                        int NT = receivers.size();
15050                        for (int it=0; it<NT; it++) {
15051                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15052                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15053                                receivers.remove(it);
15054                                it--;
15055                                NT--;
15056                            }
15057                        }
15058                    }
15059                }
15060            }
15061
15062            int NT = receivers != null ? receivers.size() : 0;
15063            int it = 0;
15064            ResolveInfo curt = null;
15065            BroadcastFilter curr = null;
15066            while (it < NT && ir < NR) {
15067                if (curt == null) {
15068                    curt = (ResolveInfo)receivers.get(it);
15069                }
15070                if (curr == null) {
15071                    curr = registeredReceivers.get(ir);
15072                }
15073                if (curr.getPriority() >= curt.priority) {
15074                    // Insert this broadcast record into the final list.
15075                    receivers.add(it, curr);
15076                    ir++;
15077                    curr = null;
15078                    it++;
15079                    NT++;
15080                } else {
15081                    // Skip to the next ResolveInfo in the final list.
15082                    it++;
15083                    curt = null;
15084                }
15085            }
15086        }
15087        while (ir < NR) {
15088            if (receivers == null) {
15089                receivers = new ArrayList();
15090            }
15091            receivers.add(registeredReceivers.get(ir));
15092            ir++;
15093        }
15094
15095        if ((receivers != null && receivers.size() > 0)
15096                || resultTo != null) {
15097            BroadcastQueue queue = broadcastQueueForIntent(intent);
15098            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15099                    callerPackage, callingPid, callingUid, resolvedType,
15100                    requiredPermission, appOp, receivers, resultTo, resultCode,
15101                    resultData, map, ordered, sticky, false, userId);
15102            if (DEBUG_BROADCAST) Slog.v(
15103                    TAG, "Enqueueing ordered broadcast " + r
15104                    + ": prev had " + queue.mOrderedBroadcasts.size());
15105            if (DEBUG_BROADCAST) {
15106                int seq = r.intent.getIntExtra("seq", -1);
15107                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15108            }
15109            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15110            if (!replaced) {
15111                queue.enqueueOrderedBroadcastLocked(r);
15112                queue.scheduleBroadcastsLocked();
15113            }
15114        }
15115
15116        return ActivityManager.BROADCAST_SUCCESS;
15117    }
15118
15119    final Intent verifyBroadcastLocked(Intent intent) {
15120        // Refuse possible leaked file descriptors
15121        if (intent != null && intent.hasFileDescriptors() == true) {
15122            throw new IllegalArgumentException("File descriptors passed in Intent");
15123        }
15124
15125        int flags = intent.getFlags();
15126
15127        if (!mProcessesReady) {
15128            // if the caller really truly claims to know what they're doing, go
15129            // ahead and allow the broadcast without launching any receivers
15130            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15131                intent = new Intent(intent);
15132                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15133            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15134                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15135                        + " before boot completion");
15136                throw new IllegalStateException("Cannot broadcast before boot completed");
15137            }
15138        }
15139
15140        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15141            throw new IllegalArgumentException(
15142                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15143        }
15144
15145        return intent;
15146    }
15147
15148    public final int broadcastIntent(IApplicationThread caller,
15149            Intent intent, String resolvedType, IIntentReceiver resultTo,
15150            int resultCode, String resultData, Bundle map,
15151            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15152        enforceNotIsolatedCaller("broadcastIntent");
15153        synchronized(this) {
15154            intent = verifyBroadcastLocked(intent);
15155
15156            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15157            final int callingPid = Binder.getCallingPid();
15158            final int callingUid = Binder.getCallingUid();
15159            final long origId = Binder.clearCallingIdentity();
15160            int res = broadcastIntentLocked(callerApp,
15161                    callerApp != null ? callerApp.info.packageName : null,
15162                    intent, resolvedType, resultTo,
15163                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15164                    callingPid, callingUid, userId);
15165            Binder.restoreCallingIdentity(origId);
15166            return res;
15167        }
15168    }
15169
15170    int broadcastIntentInPackage(String packageName, int uid,
15171            Intent intent, String resolvedType, IIntentReceiver resultTo,
15172            int resultCode, String resultData, Bundle map,
15173            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15174        synchronized(this) {
15175            intent = verifyBroadcastLocked(intent);
15176
15177            final long origId = Binder.clearCallingIdentity();
15178            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15179                    resultTo, resultCode, resultData, map, requiredPermission,
15180                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15181            Binder.restoreCallingIdentity(origId);
15182            return res;
15183        }
15184    }
15185
15186    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15187        // Refuse possible leaked file descriptors
15188        if (intent != null && intent.hasFileDescriptors() == true) {
15189            throw new IllegalArgumentException("File descriptors passed in Intent");
15190        }
15191
15192        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15193                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15194
15195        synchronized(this) {
15196            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15197                    != PackageManager.PERMISSION_GRANTED) {
15198                String msg = "Permission Denial: unbroadcastIntent() from pid="
15199                        + Binder.getCallingPid()
15200                        + ", uid=" + Binder.getCallingUid()
15201                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15202                Slog.w(TAG, msg);
15203                throw new SecurityException(msg);
15204            }
15205            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15206            if (stickies != null) {
15207                ArrayList<Intent> list = stickies.get(intent.getAction());
15208                if (list != null) {
15209                    int N = list.size();
15210                    int i;
15211                    for (i=0; i<N; i++) {
15212                        if (intent.filterEquals(list.get(i))) {
15213                            list.remove(i);
15214                            break;
15215                        }
15216                    }
15217                    if (list.size() <= 0) {
15218                        stickies.remove(intent.getAction());
15219                    }
15220                }
15221                if (stickies.size() <= 0) {
15222                    mStickyBroadcasts.remove(userId);
15223                }
15224            }
15225        }
15226    }
15227
15228    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15229            String resultData, Bundle resultExtras, boolean resultAbort) {
15230        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15231        if (r == null) {
15232            Slog.w(TAG, "finishReceiver called but not found on queue");
15233            return false;
15234        }
15235
15236        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15237    }
15238
15239    void backgroundServicesFinishedLocked(int userId) {
15240        for (BroadcastQueue queue : mBroadcastQueues) {
15241            queue.backgroundServicesFinishedLocked(userId);
15242        }
15243    }
15244
15245    public void finishReceiver(IBinder who, int resultCode, String resultData,
15246            Bundle resultExtras, boolean resultAbort) {
15247        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15248
15249        // Refuse possible leaked file descriptors
15250        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15251            throw new IllegalArgumentException("File descriptors passed in Bundle");
15252        }
15253
15254        final long origId = Binder.clearCallingIdentity();
15255        try {
15256            boolean doNext = false;
15257            BroadcastRecord r;
15258
15259            synchronized(this) {
15260                r = broadcastRecordForReceiverLocked(who);
15261                if (r != null) {
15262                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15263                        resultData, resultExtras, resultAbort, true);
15264                }
15265            }
15266
15267            if (doNext) {
15268                r.queue.processNextBroadcast(false);
15269            }
15270            trimApplications();
15271        } finally {
15272            Binder.restoreCallingIdentity(origId);
15273        }
15274    }
15275
15276    // =========================================================
15277    // INSTRUMENTATION
15278    // =========================================================
15279
15280    public boolean startInstrumentation(ComponentName className,
15281            String profileFile, int flags, Bundle arguments,
15282            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15283            int userId, String abiOverride) {
15284        enforceNotIsolatedCaller("startInstrumentation");
15285        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15286                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15287        // Refuse possible leaked file descriptors
15288        if (arguments != null && arguments.hasFileDescriptors()) {
15289            throw new IllegalArgumentException("File descriptors passed in Bundle");
15290        }
15291
15292        synchronized(this) {
15293            InstrumentationInfo ii = null;
15294            ApplicationInfo ai = null;
15295            try {
15296                ii = mContext.getPackageManager().getInstrumentationInfo(
15297                    className, STOCK_PM_FLAGS);
15298                ai = AppGlobals.getPackageManager().getApplicationInfo(
15299                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15300            } catch (PackageManager.NameNotFoundException e) {
15301            } catch (RemoteException e) {
15302            }
15303            if (ii == null) {
15304                reportStartInstrumentationFailure(watcher, className,
15305                        "Unable to find instrumentation info for: " + className);
15306                return false;
15307            }
15308            if (ai == null) {
15309                reportStartInstrumentationFailure(watcher, className,
15310                        "Unable to find instrumentation target package: " + ii.targetPackage);
15311                return false;
15312            }
15313
15314            int match = mContext.getPackageManager().checkSignatures(
15315                    ii.targetPackage, ii.packageName);
15316            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15317                String msg = "Permission Denial: starting instrumentation "
15318                        + className + " from pid="
15319                        + Binder.getCallingPid()
15320                        + ", uid=" + Binder.getCallingPid()
15321                        + " not allowed because package " + ii.packageName
15322                        + " does not have a signature matching the target "
15323                        + ii.targetPackage;
15324                reportStartInstrumentationFailure(watcher, className, msg);
15325                throw new SecurityException(msg);
15326            }
15327
15328            final long origId = Binder.clearCallingIdentity();
15329            // Instrumentation can kill and relaunch even persistent processes
15330            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15331                    "start instr");
15332            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15333            app.instrumentationClass = className;
15334            app.instrumentationInfo = ai;
15335            app.instrumentationProfileFile = profileFile;
15336            app.instrumentationArguments = arguments;
15337            app.instrumentationWatcher = watcher;
15338            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15339            app.instrumentationResultClass = className;
15340            Binder.restoreCallingIdentity(origId);
15341        }
15342
15343        return true;
15344    }
15345
15346    /**
15347     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15348     * error to the logs, but if somebody is watching, send the report there too.  This enables
15349     * the "am" command to report errors with more information.
15350     *
15351     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15352     * @param cn The component name of the instrumentation.
15353     * @param report The error report.
15354     */
15355    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15356            ComponentName cn, String report) {
15357        Slog.w(TAG, report);
15358        try {
15359            if (watcher != null) {
15360                Bundle results = new Bundle();
15361                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15362                results.putString("Error", report);
15363                watcher.instrumentationStatus(cn, -1, results);
15364            }
15365        } catch (RemoteException e) {
15366            Slog.w(TAG, e);
15367        }
15368    }
15369
15370    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15371        if (app.instrumentationWatcher != null) {
15372            try {
15373                // NOTE:  IInstrumentationWatcher *must* be oneway here
15374                app.instrumentationWatcher.instrumentationFinished(
15375                    app.instrumentationClass,
15376                    resultCode,
15377                    results);
15378            } catch (RemoteException e) {
15379            }
15380        }
15381        if (app.instrumentationUiAutomationConnection != null) {
15382            try {
15383                app.instrumentationUiAutomationConnection.shutdown();
15384            } catch (RemoteException re) {
15385                /* ignore */
15386            }
15387            // Only a UiAutomation can set this flag and now that
15388            // it is finished we make sure it is reset to its default.
15389            mUserIsMonkey = false;
15390        }
15391        app.instrumentationWatcher = null;
15392        app.instrumentationUiAutomationConnection = null;
15393        app.instrumentationClass = null;
15394        app.instrumentationInfo = null;
15395        app.instrumentationProfileFile = null;
15396        app.instrumentationArguments = null;
15397
15398        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15399                "finished inst");
15400    }
15401
15402    public void finishInstrumentation(IApplicationThread target,
15403            int resultCode, Bundle results) {
15404        int userId = UserHandle.getCallingUserId();
15405        // Refuse possible leaked file descriptors
15406        if (results != null && results.hasFileDescriptors()) {
15407            throw new IllegalArgumentException("File descriptors passed in Intent");
15408        }
15409
15410        synchronized(this) {
15411            ProcessRecord app = getRecordForAppLocked(target);
15412            if (app == null) {
15413                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15414                return;
15415            }
15416            final long origId = Binder.clearCallingIdentity();
15417            finishInstrumentationLocked(app, resultCode, results);
15418            Binder.restoreCallingIdentity(origId);
15419        }
15420    }
15421
15422    // =========================================================
15423    // CONFIGURATION
15424    // =========================================================
15425
15426    public ConfigurationInfo getDeviceConfigurationInfo() {
15427        ConfigurationInfo config = new ConfigurationInfo();
15428        synchronized (this) {
15429            config.reqTouchScreen = mConfiguration.touchscreen;
15430            config.reqKeyboardType = mConfiguration.keyboard;
15431            config.reqNavigation = mConfiguration.navigation;
15432            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15433                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15434                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15435            }
15436            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15437                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15438                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15439            }
15440            config.reqGlEsVersion = GL_ES_VERSION;
15441        }
15442        return config;
15443    }
15444
15445    ActivityStack getFocusedStack() {
15446        return mStackSupervisor.getFocusedStack();
15447    }
15448
15449    public Configuration getConfiguration() {
15450        Configuration ci;
15451        synchronized(this) {
15452            ci = new Configuration(mConfiguration);
15453        }
15454        return ci;
15455    }
15456
15457    public void updatePersistentConfiguration(Configuration values) {
15458        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15459                "updateConfiguration()");
15460        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15461                "updateConfiguration()");
15462        if (values == null) {
15463            throw new NullPointerException("Configuration must not be null");
15464        }
15465
15466        synchronized(this) {
15467            final long origId = Binder.clearCallingIdentity();
15468            updateConfigurationLocked(values, null, true, false);
15469            Binder.restoreCallingIdentity(origId);
15470        }
15471    }
15472
15473    public void updateConfiguration(Configuration values) {
15474        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15475                "updateConfiguration()");
15476
15477        synchronized(this) {
15478            if (values == null && mWindowManager != null) {
15479                // sentinel: fetch the current configuration from the window manager
15480                values = mWindowManager.computeNewConfiguration();
15481            }
15482
15483            if (mWindowManager != null) {
15484                mProcessList.applyDisplaySize(mWindowManager);
15485            }
15486
15487            final long origId = Binder.clearCallingIdentity();
15488            if (values != null) {
15489                Settings.System.clearConfiguration(values);
15490            }
15491            updateConfigurationLocked(values, null, false, false);
15492            Binder.restoreCallingIdentity(origId);
15493        }
15494    }
15495
15496    /**
15497     * Do either or both things: (1) change the current configuration, and (2)
15498     * make sure the given activity is running with the (now) current
15499     * configuration.  Returns true if the activity has been left running, or
15500     * false if <var>starting</var> is being destroyed to match the new
15501     * configuration.
15502     * @param persistent TODO
15503     */
15504    boolean updateConfigurationLocked(Configuration values,
15505            ActivityRecord starting, boolean persistent, boolean initLocale) {
15506        int changes = 0;
15507
15508        if (values != null) {
15509            Configuration newConfig = new Configuration(mConfiguration);
15510            changes = newConfig.updateFrom(values);
15511            if (changes != 0) {
15512                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15513                    Slog.i(TAG, "Updating configuration to: " + values);
15514                }
15515
15516                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15517
15518                if (values.locale != null && !initLocale) {
15519                    saveLocaleLocked(values.locale,
15520                                     !values.locale.equals(mConfiguration.locale),
15521                                     values.userSetLocale);
15522                }
15523
15524                mConfigurationSeq++;
15525                if (mConfigurationSeq <= 0) {
15526                    mConfigurationSeq = 1;
15527                }
15528                newConfig.seq = mConfigurationSeq;
15529                mConfiguration = newConfig;
15530                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15531                //mUsageStatsService.noteStartConfig(newConfig);
15532
15533                final Configuration configCopy = new Configuration(mConfiguration);
15534
15535                // TODO: If our config changes, should we auto dismiss any currently
15536                // showing dialogs?
15537                mShowDialogs = shouldShowDialogs(newConfig);
15538
15539                AttributeCache ac = AttributeCache.instance();
15540                if (ac != null) {
15541                    ac.updateConfiguration(configCopy);
15542                }
15543
15544                // Make sure all resources in our process are updated
15545                // right now, so that anyone who is going to retrieve
15546                // resource values after we return will be sure to get
15547                // the new ones.  This is especially important during
15548                // boot, where the first config change needs to guarantee
15549                // all resources have that config before following boot
15550                // code is executed.
15551                mSystemThread.applyConfigurationToResources(configCopy);
15552
15553                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15554                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15555                    msg.obj = new Configuration(configCopy);
15556                    mHandler.sendMessage(msg);
15557                }
15558
15559                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15560                    ProcessRecord app = mLruProcesses.get(i);
15561                    try {
15562                        if (app.thread != null) {
15563                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15564                                    + app.processName + " new config " + mConfiguration);
15565                            app.thread.scheduleConfigurationChanged(configCopy);
15566                        }
15567                    } catch (Exception e) {
15568                    }
15569                }
15570                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15571                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15572                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15573                        | Intent.FLAG_RECEIVER_FOREGROUND);
15574                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15575                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15576                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15577                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15578                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15579                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15580                    broadcastIntentLocked(null, null, intent,
15581                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15582                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15583                }
15584            }
15585        }
15586
15587        boolean kept = true;
15588        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15589        // mainStack is null during startup.
15590        if (mainStack != null) {
15591            if (changes != 0 && starting == null) {
15592                // If the configuration changed, and the caller is not already
15593                // in the process of starting an activity, then find the top
15594                // activity to check if its configuration needs to change.
15595                starting = mainStack.topRunningActivityLocked(null);
15596            }
15597
15598            if (starting != null) {
15599                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15600                // And we need to make sure at this point that all other activities
15601                // are made visible with the correct configuration.
15602                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15603            }
15604        }
15605
15606        if (values != null && mWindowManager != null) {
15607            mWindowManager.setNewConfiguration(mConfiguration);
15608        }
15609
15610        return kept;
15611    }
15612
15613    /**
15614     * Decide based on the configuration whether we should shouw the ANR,
15615     * crash, etc dialogs.  The idea is that if there is no affordnace to
15616     * press the on-screen buttons, we shouldn't show the dialog.
15617     *
15618     * A thought: SystemUI might also want to get told about this, the Power
15619     * dialog / global actions also might want different behaviors.
15620     */
15621    private static final boolean shouldShowDialogs(Configuration config) {
15622        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15623                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15624    }
15625
15626    /**
15627     * Save the locale.  You must be inside a synchronized (this) block.
15628     */
15629    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15630        if(isDiff) {
15631            SystemProperties.set("user.language", l.getLanguage());
15632            SystemProperties.set("user.region", l.getCountry());
15633        }
15634
15635        if(isPersist) {
15636            SystemProperties.set("persist.sys.language", l.getLanguage());
15637            SystemProperties.set("persist.sys.country", l.getCountry());
15638            SystemProperties.set("persist.sys.localevar", l.getVariant());
15639        }
15640    }
15641
15642    @Override
15643    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15644        synchronized (this) {
15645            ActivityRecord srec = ActivityRecord.forToken(token);
15646            if (srec.task != null && srec.task.stack != null) {
15647                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15648            }
15649        }
15650        return false;
15651    }
15652
15653    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15654            Intent resultData) {
15655
15656        synchronized (this) {
15657            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15658            if (stack != null) {
15659                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15660            }
15661            return false;
15662        }
15663    }
15664
15665    public int getLaunchedFromUid(IBinder activityToken) {
15666        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15667        if (srec == null) {
15668            return -1;
15669        }
15670        return srec.launchedFromUid;
15671    }
15672
15673    public String getLaunchedFromPackage(IBinder activityToken) {
15674        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15675        if (srec == null) {
15676            return null;
15677        }
15678        return srec.launchedFromPackage;
15679    }
15680
15681    // =========================================================
15682    // LIFETIME MANAGEMENT
15683    // =========================================================
15684
15685    // Returns which broadcast queue the app is the current [or imminent] receiver
15686    // on, or 'null' if the app is not an active broadcast recipient.
15687    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15688        BroadcastRecord r = app.curReceiver;
15689        if (r != null) {
15690            return r.queue;
15691        }
15692
15693        // It's not the current receiver, but it might be starting up to become one
15694        synchronized (this) {
15695            for (BroadcastQueue queue : mBroadcastQueues) {
15696                r = queue.mPendingBroadcast;
15697                if (r != null && r.curApp == app) {
15698                    // found it; report which queue it's in
15699                    return queue;
15700                }
15701            }
15702        }
15703
15704        return null;
15705    }
15706
15707    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15708            boolean doingAll, long now) {
15709        if (mAdjSeq == app.adjSeq) {
15710            // This adjustment has already been computed.
15711            return app.curRawAdj;
15712        }
15713
15714        if (app.thread == null) {
15715            app.adjSeq = mAdjSeq;
15716            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15717            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15718            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15719        }
15720
15721        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15722        app.adjSource = null;
15723        app.adjTarget = null;
15724        app.empty = false;
15725        app.cached = false;
15726
15727        final int activitiesSize = app.activities.size();
15728
15729        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15730            // The max adjustment doesn't allow this app to be anything
15731            // below foreground, so it is not worth doing work for it.
15732            app.adjType = "fixed";
15733            app.adjSeq = mAdjSeq;
15734            app.curRawAdj = app.maxAdj;
15735            app.foregroundActivities = false;
15736            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15737            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15738            // System processes can do UI, and when they do we want to have
15739            // them trim their memory after the user leaves the UI.  To
15740            // facilitate this, here we need to determine whether or not it
15741            // is currently showing UI.
15742            app.systemNoUi = true;
15743            if (app == TOP_APP) {
15744                app.systemNoUi = false;
15745            } else if (activitiesSize > 0) {
15746                for (int j = 0; j < activitiesSize; j++) {
15747                    final ActivityRecord r = app.activities.get(j);
15748                    if (r.visible) {
15749                        app.systemNoUi = false;
15750                    }
15751                }
15752            }
15753            if (!app.systemNoUi) {
15754                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15755            }
15756            return (app.curAdj=app.maxAdj);
15757        }
15758
15759        app.systemNoUi = false;
15760
15761        // Determine the importance of the process, starting with most
15762        // important to least, and assign an appropriate OOM adjustment.
15763        int adj;
15764        int schedGroup;
15765        int procState;
15766        boolean foregroundActivities = false;
15767        BroadcastQueue queue;
15768        if (app == TOP_APP) {
15769            // The last app on the list is the foreground app.
15770            adj = ProcessList.FOREGROUND_APP_ADJ;
15771            schedGroup = Process.THREAD_GROUP_DEFAULT;
15772            app.adjType = "top-activity";
15773            foregroundActivities = true;
15774            procState = ActivityManager.PROCESS_STATE_TOP;
15775        } else if (app.instrumentationClass != null) {
15776            // Don't want to kill running instrumentation.
15777            adj = ProcessList.FOREGROUND_APP_ADJ;
15778            schedGroup = Process.THREAD_GROUP_DEFAULT;
15779            app.adjType = "instrumentation";
15780            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15781        } else if ((queue = isReceivingBroadcast(app)) != null) {
15782            // An app that is currently receiving a broadcast also
15783            // counts as being in the foreground for OOM killer purposes.
15784            // It's placed in a sched group based on the nature of the
15785            // broadcast as reflected by which queue it's active in.
15786            adj = ProcessList.FOREGROUND_APP_ADJ;
15787            schedGroup = (queue == mFgBroadcastQueue)
15788                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15789            app.adjType = "broadcast";
15790            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15791        } else if (app.executingServices.size() > 0) {
15792            // An app that is currently executing a service callback also
15793            // counts as being in the foreground.
15794            adj = ProcessList.FOREGROUND_APP_ADJ;
15795            schedGroup = app.execServicesFg ?
15796                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15797            app.adjType = "exec-service";
15798            procState = ActivityManager.PROCESS_STATE_SERVICE;
15799            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15800        } else {
15801            // As far as we know the process is empty.  We may change our mind later.
15802            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15803            // At this point we don't actually know the adjustment.  Use the cached adj
15804            // value that the caller wants us to.
15805            adj = cachedAdj;
15806            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15807            app.cached = true;
15808            app.empty = true;
15809            app.adjType = "cch-empty";
15810        }
15811
15812        // Examine all activities if not already foreground.
15813        if (!foregroundActivities && activitiesSize > 0) {
15814            for (int j = 0; j < activitiesSize; j++) {
15815                final ActivityRecord r = app.activities.get(j);
15816                if (r.app != app) {
15817                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15818                            + app + "?!?");
15819                    continue;
15820                }
15821                if (r.visible) {
15822                    // App has a visible activity; only upgrade adjustment.
15823                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15824                        adj = ProcessList.VISIBLE_APP_ADJ;
15825                        app.adjType = "visible";
15826                    }
15827                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15828                        procState = ActivityManager.PROCESS_STATE_TOP;
15829                    }
15830                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15831                    app.cached = false;
15832                    app.empty = false;
15833                    foregroundActivities = true;
15834                    break;
15835                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15836                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15837                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15838                        app.adjType = "pausing";
15839                    }
15840                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15841                        procState = ActivityManager.PROCESS_STATE_TOP;
15842                    }
15843                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15844                    app.cached = false;
15845                    app.empty = false;
15846                    foregroundActivities = true;
15847                } else if (r.state == ActivityState.STOPPING) {
15848                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15849                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15850                        app.adjType = "stopping";
15851                    }
15852                    // For the process state, we will at this point consider the
15853                    // process to be cached.  It will be cached either as an activity
15854                    // or empty depending on whether the activity is finishing.  We do
15855                    // this so that we can treat the process as cached for purposes of
15856                    // memory trimming (determing current memory level, trim command to
15857                    // send to process) since there can be an arbitrary number of stopping
15858                    // processes and they should soon all go into the cached state.
15859                    if (!r.finishing) {
15860                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15861                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15862                        }
15863                    }
15864                    app.cached = false;
15865                    app.empty = false;
15866                    foregroundActivities = true;
15867                } else {
15868                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15869                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15870                        app.adjType = "cch-act";
15871                    }
15872                }
15873            }
15874        }
15875
15876        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15877            if (app.foregroundServices) {
15878                // The user is aware of this app, so make it visible.
15879                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15880                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15881                app.cached = false;
15882                app.adjType = "fg-service";
15883                schedGroup = Process.THREAD_GROUP_DEFAULT;
15884            } else if (app.forcingToForeground != null) {
15885                // The user is aware of this app, so make it visible.
15886                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15887                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15888                app.cached = false;
15889                app.adjType = "force-fg";
15890                app.adjSource = app.forcingToForeground;
15891                schedGroup = Process.THREAD_GROUP_DEFAULT;
15892            }
15893        }
15894
15895        if (app == mHeavyWeightProcess) {
15896            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15897                // We don't want to kill the current heavy-weight process.
15898                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15899                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15900                app.cached = false;
15901                app.adjType = "heavy";
15902            }
15903            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15904                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15905            }
15906        }
15907
15908        if (app == mHomeProcess) {
15909            if (adj > ProcessList.HOME_APP_ADJ) {
15910                // This process is hosting what we currently consider to be the
15911                // home app, so we don't want to let it go into the background.
15912                adj = ProcessList.HOME_APP_ADJ;
15913                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15914                app.cached = false;
15915                app.adjType = "home";
15916            }
15917            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15918                procState = ActivityManager.PROCESS_STATE_HOME;
15919            }
15920        }
15921
15922        if (app == mPreviousProcess && app.activities.size() > 0) {
15923            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15924                // This was the previous process that showed UI to the user.
15925                // We want to try to keep it around more aggressively, to give
15926                // a good experience around switching between two apps.
15927                adj = ProcessList.PREVIOUS_APP_ADJ;
15928                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15929                app.cached = false;
15930                app.adjType = "previous";
15931            }
15932            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15933                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15934            }
15935        }
15936
15937        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15938                + " reason=" + app.adjType);
15939
15940        // By default, we use the computed adjustment.  It may be changed if
15941        // there are applications dependent on our services or providers, but
15942        // this gives us a baseline and makes sure we don't get into an
15943        // infinite recursion.
15944        app.adjSeq = mAdjSeq;
15945        app.curRawAdj = adj;
15946        app.hasStartedServices = false;
15947
15948        if (mBackupTarget != null && app == mBackupTarget.app) {
15949            // If possible we want to avoid killing apps while they're being backed up
15950            if (adj > ProcessList.BACKUP_APP_ADJ) {
15951                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15952                adj = ProcessList.BACKUP_APP_ADJ;
15953                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15954                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15955                }
15956                app.adjType = "backup";
15957                app.cached = false;
15958            }
15959            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15960                procState = ActivityManager.PROCESS_STATE_BACKUP;
15961            }
15962        }
15963
15964        boolean mayBeTop = false;
15965
15966        for (int is = app.services.size()-1;
15967                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15968                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15969                        || procState > ActivityManager.PROCESS_STATE_TOP);
15970                is--) {
15971            ServiceRecord s = app.services.valueAt(is);
15972            if (s.startRequested) {
15973                app.hasStartedServices = true;
15974                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15975                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15976                }
15977                if (app.hasShownUi && app != mHomeProcess) {
15978                    // If this process has shown some UI, let it immediately
15979                    // go to the LRU list because it may be pretty heavy with
15980                    // UI stuff.  We'll tag it with a label just to help
15981                    // debug and understand what is going on.
15982                    if (adj > ProcessList.SERVICE_ADJ) {
15983                        app.adjType = "cch-started-ui-services";
15984                    }
15985                } else {
15986                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15987                        // This service has seen some activity within
15988                        // recent memory, so we will keep its process ahead
15989                        // of the background processes.
15990                        if (adj > ProcessList.SERVICE_ADJ) {
15991                            adj = ProcessList.SERVICE_ADJ;
15992                            app.adjType = "started-services";
15993                            app.cached = false;
15994                        }
15995                    }
15996                    // If we have let the service slide into the background
15997                    // state, still have some text describing what it is doing
15998                    // even though the service no longer has an impact.
15999                    if (adj > ProcessList.SERVICE_ADJ) {
16000                        app.adjType = "cch-started-services";
16001                    }
16002                }
16003            }
16004            for (int conni = s.connections.size()-1;
16005                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16006                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16007                            || procState > ActivityManager.PROCESS_STATE_TOP);
16008                    conni--) {
16009                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16010                for (int i = 0;
16011                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16012                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16013                                || procState > ActivityManager.PROCESS_STATE_TOP);
16014                        i++) {
16015                    // XXX should compute this based on the max of
16016                    // all connected clients.
16017                    ConnectionRecord cr = clist.get(i);
16018                    if (cr.binding.client == app) {
16019                        // Binding to ourself is not interesting.
16020                        continue;
16021                    }
16022                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16023                        ProcessRecord client = cr.binding.client;
16024                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16025                                TOP_APP, doingAll, now);
16026                        int clientProcState = client.curProcState;
16027                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16028                            // If the other app is cached for any reason, for purposes here
16029                            // we are going to consider it empty.  The specific cached state
16030                            // doesn't propagate except under certain conditions.
16031                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16032                        }
16033                        String adjType = null;
16034                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16035                            // Not doing bind OOM management, so treat
16036                            // this guy more like a started service.
16037                            if (app.hasShownUi && app != mHomeProcess) {
16038                                // If this process has shown some UI, let it immediately
16039                                // go to the LRU list because it may be pretty heavy with
16040                                // UI stuff.  We'll tag it with a label just to help
16041                                // debug and understand what is going on.
16042                                if (adj > clientAdj) {
16043                                    adjType = "cch-bound-ui-services";
16044                                }
16045                                app.cached = false;
16046                                clientAdj = adj;
16047                                clientProcState = procState;
16048                            } else {
16049                                if (now >= (s.lastActivity
16050                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16051                                    // This service has not seen activity within
16052                                    // recent memory, so allow it to drop to the
16053                                    // LRU list if there is no other reason to keep
16054                                    // it around.  We'll also tag it with a label just
16055                                    // to help debug and undertand what is going on.
16056                                    if (adj > clientAdj) {
16057                                        adjType = "cch-bound-services";
16058                                    }
16059                                    clientAdj = adj;
16060                                }
16061                            }
16062                        }
16063                        if (adj > clientAdj) {
16064                            // If this process has recently shown UI, and
16065                            // the process that is binding to it is less
16066                            // important than being visible, then we don't
16067                            // care about the binding as much as we care
16068                            // about letting this process get into the LRU
16069                            // list to be killed and restarted if needed for
16070                            // memory.
16071                            if (app.hasShownUi && app != mHomeProcess
16072                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16073                                adjType = "cch-bound-ui-services";
16074                            } else {
16075                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16076                                        |Context.BIND_IMPORTANT)) != 0) {
16077                                    adj = clientAdj;
16078                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16079                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16080                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16081                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16082                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16083                                    adj = clientAdj;
16084                                } else {
16085                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16086                                        adj = ProcessList.VISIBLE_APP_ADJ;
16087                                    }
16088                                }
16089                                if (!client.cached) {
16090                                    app.cached = false;
16091                                }
16092                                adjType = "service";
16093                            }
16094                        }
16095                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16096                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16097                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16098                            }
16099                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16100                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16101                                    // Special handling of clients who are in the top state.
16102                                    // We *may* want to consider this process to be in the
16103                                    // top state as well, but only if there is not another
16104                                    // reason for it to be running.  Being on the top is a
16105                                    // special state, meaning you are specifically running
16106                                    // for the current top app.  If the process is already
16107                                    // running in the background for some other reason, it
16108                                    // is more important to continue considering it to be
16109                                    // in the background state.
16110                                    mayBeTop = true;
16111                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16112                                } else {
16113                                    // Special handling for above-top states (persistent
16114                                    // processes).  These should not bring the current process
16115                                    // into the top state, since they are not on top.  Instead
16116                                    // give them the best state after that.
16117                                    clientProcState =
16118                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16119                                }
16120                            }
16121                        } else {
16122                            if (clientProcState <
16123                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16124                                clientProcState =
16125                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16126                            }
16127                        }
16128                        if (procState > clientProcState) {
16129                            procState = clientProcState;
16130                        }
16131                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16132                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16133                            app.pendingUiClean = true;
16134                        }
16135                        if (adjType != null) {
16136                            app.adjType = adjType;
16137                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16138                                    .REASON_SERVICE_IN_USE;
16139                            app.adjSource = cr.binding.client;
16140                            app.adjSourceProcState = clientProcState;
16141                            app.adjTarget = s.name;
16142                        }
16143                    }
16144                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16145                        app.treatLikeActivity = true;
16146                    }
16147                    final ActivityRecord a = cr.activity;
16148                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16149                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16150                                (a.visible || a.state == ActivityState.RESUMED
16151                                 || a.state == ActivityState.PAUSING)) {
16152                            adj = ProcessList.FOREGROUND_APP_ADJ;
16153                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16154                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16155                            }
16156                            app.cached = false;
16157                            app.adjType = "service";
16158                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16159                                    .REASON_SERVICE_IN_USE;
16160                            app.adjSource = a;
16161                            app.adjSourceProcState = procState;
16162                            app.adjTarget = s.name;
16163                        }
16164                    }
16165                }
16166            }
16167        }
16168
16169        for (int provi = app.pubProviders.size()-1;
16170                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16171                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16172                        || procState > ActivityManager.PROCESS_STATE_TOP);
16173                provi--) {
16174            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16175            for (int i = cpr.connections.size()-1;
16176                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16177                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16178                            || procState > ActivityManager.PROCESS_STATE_TOP);
16179                    i--) {
16180                ContentProviderConnection conn = cpr.connections.get(i);
16181                ProcessRecord client = conn.client;
16182                if (client == app) {
16183                    // Being our own client is not interesting.
16184                    continue;
16185                }
16186                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16187                int clientProcState = client.curProcState;
16188                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16189                    // If the other app is cached for any reason, for purposes here
16190                    // we are going to consider it empty.
16191                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16192                }
16193                if (adj > clientAdj) {
16194                    if (app.hasShownUi && app != mHomeProcess
16195                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16196                        app.adjType = "cch-ui-provider";
16197                    } else {
16198                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16199                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16200                        app.adjType = "provider";
16201                    }
16202                    app.cached &= client.cached;
16203                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16204                            .REASON_PROVIDER_IN_USE;
16205                    app.adjSource = client;
16206                    app.adjSourceProcState = clientProcState;
16207                    app.adjTarget = cpr.name;
16208                }
16209                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16210                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16211                        // Special handling of clients who are in the top state.
16212                        // We *may* want to consider this process to be in the
16213                        // top state as well, but only if there is not another
16214                        // reason for it to be running.  Being on the top is a
16215                        // special state, meaning you are specifically running
16216                        // for the current top app.  If the process is already
16217                        // running in the background for some other reason, it
16218                        // is more important to continue considering it to be
16219                        // in the background state.
16220                        mayBeTop = true;
16221                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16222                    } else {
16223                        // Special handling for above-top states (persistent
16224                        // processes).  These should not bring the current process
16225                        // into the top state, since they are not on top.  Instead
16226                        // give them the best state after that.
16227                        clientProcState =
16228                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16229                    }
16230                }
16231                if (procState > clientProcState) {
16232                    procState = clientProcState;
16233                }
16234                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16235                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16236                }
16237            }
16238            // If the provider has external (non-framework) process
16239            // dependencies, ensure that its adjustment is at least
16240            // FOREGROUND_APP_ADJ.
16241            if (cpr.hasExternalProcessHandles()) {
16242                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16243                    adj = ProcessList.FOREGROUND_APP_ADJ;
16244                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16245                    app.cached = false;
16246                    app.adjType = "provider";
16247                    app.adjTarget = cpr.name;
16248                }
16249                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16250                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16251                }
16252            }
16253        }
16254
16255        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16256            // A client of one of our services or providers is in the top state.  We
16257            // *may* want to be in the top state, but not if we are already running in
16258            // the background for some other reason.  For the decision here, we are going
16259            // to pick out a few specific states that we want to remain in when a client
16260            // is top (states that tend to be longer-term) and otherwise allow it to go
16261            // to the top state.
16262            switch (procState) {
16263                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16264                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16265                case ActivityManager.PROCESS_STATE_SERVICE:
16266                    // These all are longer-term states, so pull them up to the top
16267                    // of the background states, but not all the way to the top state.
16268                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16269                    break;
16270                default:
16271                    // Otherwise, top is a better choice, so take it.
16272                    procState = ActivityManager.PROCESS_STATE_TOP;
16273                    break;
16274            }
16275        }
16276
16277        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16278            if (app.hasClientActivities) {
16279                // This is a cached process, but with client activities.  Mark it so.
16280                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16281                app.adjType = "cch-client-act";
16282            } else if (app.treatLikeActivity) {
16283                // This is a cached process, but somebody wants us to treat it like it has
16284                // an activity, okay!
16285                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16286                app.adjType = "cch-as-act";
16287            }
16288        }
16289
16290        if (adj == ProcessList.SERVICE_ADJ) {
16291            if (doingAll) {
16292                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16293                mNewNumServiceProcs++;
16294                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16295                if (!app.serviceb) {
16296                    // This service isn't far enough down on the LRU list to
16297                    // normally be a B service, but if we are low on RAM and it
16298                    // is large we want to force it down since we would prefer to
16299                    // keep launcher over it.
16300                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16301                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16302                        app.serviceHighRam = true;
16303                        app.serviceb = true;
16304                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16305                    } else {
16306                        mNewNumAServiceProcs++;
16307                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16308                    }
16309                } else {
16310                    app.serviceHighRam = false;
16311                }
16312            }
16313            if (app.serviceb) {
16314                adj = ProcessList.SERVICE_B_ADJ;
16315            }
16316        }
16317
16318        app.curRawAdj = adj;
16319
16320        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16321        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16322        if (adj > app.maxAdj) {
16323            adj = app.maxAdj;
16324            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16325                schedGroup = Process.THREAD_GROUP_DEFAULT;
16326            }
16327        }
16328
16329        // Do final modification to adj.  Everything we do between here and applying
16330        // the final setAdj must be done in this function, because we will also use
16331        // it when computing the final cached adj later.  Note that we don't need to
16332        // worry about this for max adj above, since max adj will always be used to
16333        // keep it out of the cached vaues.
16334        app.curAdj = app.modifyRawOomAdj(adj);
16335        app.curSchedGroup = schedGroup;
16336        app.curProcState = procState;
16337        app.foregroundActivities = foregroundActivities;
16338
16339        return app.curRawAdj;
16340    }
16341
16342    /**
16343     * Schedule PSS collection of a process.
16344     */
16345    void requestPssLocked(ProcessRecord proc, int procState) {
16346        if (mPendingPssProcesses.contains(proc)) {
16347            return;
16348        }
16349        if (mPendingPssProcesses.size() == 0) {
16350            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16351        }
16352        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16353        proc.pssProcState = procState;
16354        mPendingPssProcesses.add(proc);
16355    }
16356
16357    /**
16358     * Schedule PSS collection of all processes.
16359     */
16360    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16361        if (!always) {
16362            if (now < (mLastFullPssTime +
16363                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16364                return;
16365            }
16366        }
16367        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16368        mLastFullPssTime = now;
16369        mFullPssPending = true;
16370        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16371        mPendingPssProcesses.clear();
16372        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16373            ProcessRecord app = mLruProcesses.get(i);
16374            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16375                app.pssProcState = app.setProcState;
16376                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16377                        isSleeping(), now);
16378                mPendingPssProcesses.add(app);
16379            }
16380        }
16381        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16382    }
16383
16384    /**
16385     * Ask a given process to GC right now.
16386     */
16387    final void performAppGcLocked(ProcessRecord app) {
16388        try {
16389            app.lastRequestedGc = SystemClock.uptimeMillis();
16390            if (app.thread != null) {
16391                if (app.reportLowMemory) {
16392                    app.reportLowMemory = false;
16393                    app.thread.scheduleLowMemory();
16394                } else {
16395                    app.thread.processInBackground();
16396                }
16397            }
16398        } catch (Exception e) {
16399            // whatever.
16400        }
16401    }
16402
16403    /**
16404     * Returns true if things are idle enough to perform GCs.
16405     */
16406    private final boolean canGcNowLocked() {
16407        boolean processingBroadcasts = false;
16408        for (BroadcastQueue q : mBroadcastQueues) {
16409            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16410                processingBroadcasts = true;
16411            }
16412        }
16413        return !processingBroadcasts
16414                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16415    }
16416
16417    /**
16418     * Perform GCs on all processes that are waiting for it, but only
16419     * if things are idle.
16420     */
16421    final void performAppGcsLocked() {
16422        final int N = mProcessesToGc.size();
16423        if (N <= 0) {
16424            return;
16425        }
16426        if (canGcNowLocked()) {
16427            while (mProcessesToGc.size() > 0) {
16428                ProcessRecord proc = mProcessesToGc.remove(0);
16429                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16430                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16431                            <= SystemClock.uptimeMillis()) {
16432                        // To avoid spamming the system, we will GC processes one
16433                        // at a time, waiting a few seconds between each.
16434                        performAppGcLocked(proc);
16435                        scheduleAppGcsLocked();
16436                        return;
16437                    } else {
16438                        // It hasn't been long enough since we last GCed this
16439                        // process...  put it in the list to wait for its time.
16440                        addProcessToGcListLocked(proc);
16441                        break;
16442                    }
16443                }
16444            }
16445
16446            scheduleAppGcsLocked();
16447        }
16448    }
16449
16450    /**
16451     * If all looks good, perform GCs on all processes waiting for them.
16452     */
16453    final void performAppGcsIfAppropriateLocked() {
16454        if (canGcNowLocked()) {
16455            performAppGcsLocked();
16456            return;
16457        }
16458        // Still not idle, wait some more.
16459        scheduleAppGcsLocked();
16460    }
16461
16462    /**
16463     * Schedule the execution of all pending app GCs.
16464     */
16465    final void scheduleAppGcsLocked() {
16466        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16467
16468        if (mProcessesToGc.size() > 0) {
16469            // Schedule a GC for the time to the next process.
16470            ProcessRecord proc = mProcessesToGc.get(0);
16471            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16472
16473            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16474            long now = SystemClock.uptimeMillis();
16475            if (when < (now+GC_TIMEOUT)) {
16476                when = now + GC_TIMEOUT;
16477            }
16478            mHandler.sendMessageAtTime(msg, when);
16479        }
16480    }
16481
16482    /**
16483     * Add a process to the array of processes waiting to be GCed.  Keeps the
16484     * list in sorted order by the last GC time.  The process can't already be
16485     * on the list.
16486     */
16487    final void addProcessToGcListLocked(ProcessRecord proc) {
16488        boolean added = false;
16489        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16490            if (mProcessesToGc.get(i).lastRequestedGc <
16491                    proc.lastRequestedGc) {
16492                added = true;
16493                mProcessesToGc.add(i+1, proc);
16494                break;
16495            }
16496        }
16497        if (!added) {
16498            mProcessesToGc.add(0, proc);
16499        }
16500    }
16501
16502    /**
16503     * Set up to ask a process to GC itself.  This will either do it
16504     * immediately, or put it on the list of processes to gc the next
16505     * time things are idle.
16506     */
16507    final void scheduleAppGcLocked(ProcessRecord app) {
16508        long now = SystemClock.uptimeMillis();
16509        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16510            return;
16511        }
16512        if (!mProcessesToGc.contains(app)) {
16513            addProcessToGcListLocked(app);
16514            scheduleAppGcsLocked();
16515        }
16516    }
16517
16518    final void checkExcessivePowerUsageLocked(boolean doKills) {
16519        updateCpuStatsNow();
16520
16521        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16522        boolean doWakeKills = doKills;
16523        boolean doCpuKills = doKills;
16524        if (mLastPowerCheckRealtime == 0) {
16525            doWakeKills = false;
16526        }
16527        if (mLastPowerCheckUptime == 0) {
16528            doCpuKills = false;
16529        }
16530        if (stats.isScreenOn()) {
16531            doWakeKills = false;
16532        }
16533        final long curRealtime = SystemClock.elapsedRealtime();
16534        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16535        final long curUptime = SystemClock.uptimeMillis();
16536        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16537        mLastPowerCheckRealtime = curRealtime;
16538        mLastPowerCheckUptime = curUptime;
16539        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16540            doWakeKills = false;
16541        }
16542        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16543            doCpuKills = false;
16544        }
16545        int i = mLruProcesses.size();
16546        while (i > 0) {
16547            i--;
16548            ProcessRecord app = mLruProcesses.get(i);
16549            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16550                long wtime;
16551                synchronized (stats) {
16552                    wtime = stats.getProcessWakeTime(app.info.uid,
16553                            app.pid, curRealtime);
16554                }
16555                long wtimeUsed = wtime - app.lastWakeTime;
16556                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16557                if (DEBUG_POWER) {
16558                    StringBuilder sb = new StringBuilder(128);
16559                    sb.append("Wake for ");
16560                    app.toShortString(sb);
16561                    sb.append(": over ");
16562                    TimeUtils.formatDuration(realtimeSince, sb);
16563                    sb.append(" used ");
16564                    TimeUtils.formatDuration(wtimeUsed, sb);
16565                    sb.append(" (");
16566                    sb.append((wtimeUsed*100)/realtimeSince);
16567                    sb.append("%)");
16568                    Slog.i(TAG, sb.toString());
16569                    sb.setLength(0);
16570                    sb.append("CPU for ");
16571                    app.toShortString(sb);
16572                    sb.append(": over ");
16573                    TimeUtils.formatDuration(uptimeSince, sb);
16574                    sb.append(" used ");
16575                    TimeUtils.formatDuration(cputimeUsed, sb);
16576                    sb.append(" (");
16577                    sb.append((cputimeUsed*100)/uptimeSince);
16578                    sb.append("%)");
16579                    Slog.i(TAG, sb.toString());
16580                }
16581                // If a process has held a wake lock for more
16582                // than 50% of the time during this period,
16583                // that sounds bad.  Kill!
16584                if (doWakeKills && realtimeSince > 0
16585                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16586                    synchronized (stats) {
16587                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16588                                realtimeSince, wtimeUsed);
16589                    }
16590                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16591                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16592                } else if (doCpuKills && uptimeSince > 0
16593                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16594                    synchronized (stats) {
16595                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16596                                uptimeSince, cputimeUsed);
16597                    }
16598                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16599                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16600                } else {
16601                    app.lastWakeTime = wtime;
16602                    app.lastCpuTime = app.curCpuTime;
16603                }
16604            }
16605        }
16606    }
16607
16608    private final boolean applyOomAdjLocked(ProcessRecord app,
16609            ProcessRecord TOP_APP, boolean doingAll, long now) {
16610        boolean success = true;
16611
16612        if (app.curRawAdj != app.setRawAdj) {
16613            app.setRawAdj = app.curRawAdj;
16614        }
16615
16616        int changes = 0;
16617
16618        if (app.curAdj != app.setAdj) {
16619            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16620            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16621                TAG, "Set " + app.pid + " " + app.processName +
16622                " adj " + app.curAdj + ": " + app.adjType);
16623            app.setAdj = app.curAdj;
16624        }
16625
16626        if (app.setSchedGroup != app.curSchedGroup) {
16627            app.setSchedGroup = app.curSchedGroup;
16628            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16629                    "Setting process group of " + app.processName
16630                    + " to " + app.curSchedGroup);
16631            if (app.waitingToKill != null &&
16632                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16633                app.kill(app.waitingToKill, true);
16634                success = false;
16635            } else {
16636                if (true) {
16637                    long oldId = Binder.clearCallingIdentity();
16638                    try {
16639                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16640                    } catch (Exception e) {
16641                        Slog.w(TAG, "Failed setting process group of " + app.pid
16642                                + " to " + app.curSchedGroup);
16643                        e.printStackTrace();
16644                    } finally {
16645                        Binder.restoreCallingIdentity(oldId);
16646                    }
16647                } else {
16648                    if (app.thread != null) {
16649                        try {
16650                            app.thread.setSchedulingGroup(app.curSchedGroup);
16651                        } catch (RemoteException e) {
16652                        }
16653                    }
16654                }
16655                Process.setSwappiness(app.pid,
16656                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16657            }
16658        }
16659        if (app.repForegroundActivities != app.foregroundActivities) {
16660            app.repForegroundActivities = app.foregroundActivities;
16661            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16662        }
16663        if (app.repProcState != app.curProcState) {
16664            app.repProcState = app.curProcState;
16665            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16666            if (app.thread != null) {
16667                try {
16668                    if (false) {
16669                        //RuntimeException h = new RuntimeException("here");
16670                        Slog.i(TAG, "Sending new process state " + app.repProcState
16671                                + " to " + app /*, h*/);
16672                    }
16673                    app.thread.setProcessState(app.repProcState);
16674                } catch (RemoteException e) {
16675                }
16676            }
16677        }
16678        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16679                app.setProcState)) {
16680            app.lastStateTime = now;
16681            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16682                    isSleeping(), now);
16683            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16684                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16685                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16686                    + (app.nextPssTime-now) + ": " + app);
16687        } else {
16688            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16689                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16690                requestPssLocked(app, app.setProcState);
16691                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16692                        isSleeping(), now);
16693            } else if (false && DEBUG_PSS) {
16694                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16695            }
16696        }
16697        if (app.setProcState != app.curProcState) {
16698            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16699                    "Proc state change of " + app.processName
16700                    + " to " + app.curProcState);
16701            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16702            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16703            if (setImportant && !curImportant) {
16704                // This app is no longer something we consider important enough to allow to
16705                // use arbitrary amounts of battery power.  Note
16706                // its current wake lock time to later know to kill it if
16707                // it is not behaving well.
16708                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16709                synchronized (stats) {
16710                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16711                            app.pid, SystemClock.elapsedRealtime());
16712                }
16713                app.lastCpuTime = app.curCpuTime;
16714
16715            }
16716            app.setProcState = app.curProcState;
16717            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16718                app.notCachedSinceIdle = false;
16719            }
16720            if (!doingAll) {
16721                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16722            } else {
16723                app.procStateChanged = true;
16724            }
16725        }
16726
16727        if (changes != 0) {
16728            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16729            int i = mPendingProcessChanges.size()-1;
16730            ProcessChangeItem item = null;
16731            while (i >= 0) {
16732                item = mPendingProcessChanges.get(i);
16733                if (item.pid == app.pid) {
16734                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16735                    break;
16736                }
16737                i--;
16738            }
16739            if (i < 0) {
16740                // No existing item in pending changes; need a new one.
16741                final int NA = mAvailProcessChanges.size();
16742                if (NA > 0) {
16743                    item = mAvailProcessChanges.remove(NA-1);
16744                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16745                } else {
16746                    item = new ProcessChangeItem();
16747                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16748                }
16749                item.changes = 0;
16750                item.pid = app.pid;
16751                item.uid = app.info.uid;
16752                if (mPendingProcessChanges.size() == 0) {
16753                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16754                            "*** Enqueueing dispatch processes changed!");
16755                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16756                }
16757                mPendingProcessChanges.add(item);
16758            }
16759            item.changes |= changes;
16760            item.processState = app.repProcState;
16761            item.foregroundActivities = app.repForegroundActivities;
16762            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16763                    + Integer.toHexString(System.identityHashCode(item))
16764                    + " " + app.toShortString() + ": changes=" + item.changes
16765                    + " procState=" + item.processState
16766                    + " foreground=" + item.foregroundActivities
16767                    + " type=" + app.adjType + " source=" + app.adjSource
16768                    + " target=" + app.adjTarget);
16769        }
16770
16771        return success;
16772    }
16773
16774    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16775        if (proc.thread != null) {
16776            if (proc.baseProcessTracker != null) {
16777                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16778            }
16779            if (proc.repProcState >= 0) {
16780                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16781                        proc.repProcState);
16782            }
16783        }
16784    }
16785
16786    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16787            ProcessRecord TOP_APP, boolean doingAll, long now) {
16788        if (app.thread == null) {
16789            return false;
16790        }
16791
16792        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16793
16794        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16795    }
16796
16797    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16798            boolean oomAdj) {
16799        if (isForeground != proc.foregroundServices) {
16800            proc.foregroundServices = isForeground;
16801            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16802                    proc.info.uid);
16803            if (isForeground) {
16804                if (curProcs == null) {
16805                    curProcs = new ArrayList<ProcessRecord>();
16806                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16807                }
16808                if (!curProcs.contains(proc)) {
16809                    curProcs.add(proc);
16810                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16811                            proc.info.packageName, proc.info.uid);
16812                }
16813            } else {
16814                if (curProcs != null) {
16815                    if (curProcs.remove(proc)) {
16816                        mBatteryStatsService.noteEvent(
16817                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16818                                proc.info.packageName, proc.info.uid);
16819                        if (curProcs.size() <= 0) {
16820                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16821                        }
16822                    }
16823                }
16824            }
16825            if (oomAdj) {
16826                updateOomAdjLocked();
16827            }
16828        }
16829    }
16830
16831    private final ActivityRecord resumedAppLocked() {
16832        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16833        String pkg;
16834        int uid;
16835        if (act != null) {
16836            pkg = act.packageName;
16837            uid = act.info.applicationInfo.uid;
16838        } else {
16839            pkg = null;
16840            uid = -1;
16841        }
16842        // Has the UID or resumed package name changed?
16843        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16844                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16845            if (mCurResumedPackage != null) {
16846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16847                        mCurResumedPackage, mCurResumedUid);
16848            }
16849            mCurResumedPackage = pkg;
16850            mCurResumedUid = uid;
16851            if (mCurResumedPackage != null) {
16852                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16853                        mCurResumedPackage, mCurResumedUid);
16854            }
16855        }
16856        return act;
16857    }
16858
16859    final boolean updateOomAdjLocked(ProcessRecord app) {
16860        final ActivityRecord TOP_ACT = resumedAppLocked();
16861        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16862        final boolean wasCached = app.cached;
16863
16864        mAdjSeq++;
16865
16866        // This is the desired cached adjusment we want to tell it to use.
16867        // If our app is currently cached, we know it, and that is it.  Otherwise,
16868        // we don't know it yet, and it needs to now be cached we will then
16869        // need to do a complete oom adj.
16870        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16871                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16872        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16873                SystemClock.uptimeMillis());
16874        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16875            // Changed to/from cached state, so apps after it in the LRU
16876            // list may also be changed.
16877            updateOomAdjLocked();
16878        }
16879        return success;
16880    }
16881
16882    final void updateOomAdjLocked() {
16883        final ActivityRecord TOP_ACT = resumedAppLocked();
16884        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16885        final long now = SystemClock.uptimeMillis();
16886        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16887        final int N = mLruProcesses.size();
16888
16889        if (false) {
16890            RuntimeException e = new RuntimeException();
16891            e.fillInStackTrace();
16892            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16893        }
16894
16895        mAdjSeq++;
16896        mNewNumServiceProcs = 0;
16897        mNewNumAServiceProcs = 0;
16898
16899        final int emptyProcessLimit;
16900        final int cachedProcessLimit;
16901        if (mProcessLimit <= 0) {
16902            emptyProcessLimit = cachedProcessLimit = 0;
16903        } else if (mProcessLimit == 1) {
16904            emptyProcessLimit = 1;
16905            cachedProcessLimit = 0;
16906        } else {
16907            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16908            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16909        }
16910
16911        // Let's determine how many processes we have running vs.
16912        // how many slots we have for background processes; we may want
16913        // to put multiple processes in a slot of there are enough of
16914        // them.
16915        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16916                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16917        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16918        if (numEmptyProcs > cachedProcessLimit) {
16919            // If there are more empty processes than our limit on cached
16920            // processes, then use the cached process limit for the factor.
16921            // This ensures that the really old empty processes get pushed
16922            // down to the bottom, so if we are running low on memory we will
16923            // have a better chance at keeping around more cached processes
16924            // instead of a gazillion empty processes.
16925            numEmptyProcs = cachedProcessLimit;
16926        }
16927        int emptyFactor = numEmptyProcs/numSlots;
16928        if (emptyFactor < 1) emptyFactor = 1;
16929        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16930        if (cachedFactor < 1) cachedFactor = 1;
16931        int stepCached = 0;
16932        int stepEmpty = 0;
16933        int numCached = 0;
16934        int numEmpty = 0;
16935        int numTrimming = 0;
16936
16937        mNumNonCachedProcs = 0;
16938        mNumCachedHiddenProcs = 0;
16939
16940        // First update the OOM adjustment for each of the
16941        // application processes based on their current state.
16942        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16943        int nextCachedAdj = curCachedAdj+1;
16944        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16945        int nextEmptyAdj = curEmptyAdj+2;
16946        for (int i=N-1; i>=0; i--) {
16947            ProcessRecord app = mLruProcesses.get(i);
16948            if (!app.killedByAm && app.thread != null) {
16949                app.procStateChanged = false;
16950                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16951
16952                // If we haven't yet assigned the final cached adj
16953                // to the process, do that now.
16954                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16955                    switch (app.curProcState) {
16956                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16957                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16958                            // This process is a cached process holding activities...
16959                            // assign it the next cached value for that type, and then
16960                            // step that cached level.
16961                            app.curRawAdj = curCachedAdj;
16962                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16963                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16964                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16965                                    + ")");
16966                            if (curCachedAdj != nextCachedAdj) {
16967                                stepCached++;
16968                                if (stepCached >= cachedFactor) {
16969                                    stepCached = 0;
16970                                    curCachedAdj = nextCachedAdj;
16971                                    nextCachedAdj += 2;
16972                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16973                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16974                                    }
16975                                }
16976                            }
16977                            break;
16978                        default:
16979                            // For everything else, assign next empty cached process
16980                            // level and bump that up.  Note that this means that
16981                            // long-running services that have dropped down to the
16982                            // cached level will be treated as empty (since their process
16983                            // state is still as a service), which is what we want.
16984                            app.curRawAdj = curEmptyAdj;
16985                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16986                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16987                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16988                                    + ")");
16989                            if (curEmptyAdj != nextEmptyAdj) {
16990                                stepEmpty++;
16991                                if (stepEmpty >= emptyFactor) {
16992                                    stepEmpty = 0;
16993                                    curEmptyAdj = nextEmptyAdj;
16994                                    nextEmptyAdj += 2;
16995                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16996                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16997                                    }
16998                                }
16999                            }
17000                            break;
17001                    }
17002                }
17003
17004                applyOomAdjLocked(app, TOP_APP, true, now);
17005
17006                // Count the number of process types.
17007                switch (app.curProcState) {
17008                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17009                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17010                        mNumCachedHiddenProcs++;
17011                        numCached++;
17012                        if (numCached > cachedProcessLimit) {
17013                            app.kill("cached #" + numCached, true);
17014                        }
17015                        break;
17016                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17017                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17018                                && app.lastActivityTime < oldTime) {
17019                            app.kill("empty for "
17020                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17021                                    / 1000) + "s", true);
17022                        } else {
17023                            numEmpty++;
17024                            if (numEmpty > emptyProcessLimit) {
17025                                app.kill("empty #" + numEmpty, true);
17026                            }
17027                        }
17028                        break;
17029                    default:
17030                        mNumNonCachedProcs++;
17031                        break;
17032                }
17033
17034                if (app.isolated && app.services.size() <= 0) {
17035                    // If this is an isolated process, and there are no
17036                    // services running in it, then the process is no longer
17037                    // needed.  We agressively kill these because we can by
17038                    // definition not re-use the same process again, and it is
17039                    // good to avoid having whatever code was running in them
17040                    // left sitting around after no longer needed.
17041                    app.kill("isolated not needed", true);
17042                }
17043
17044                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17045                        && !app.killedByAm) {
17046                    numTrimming++;
17047                }
17048            }
17049        }
17050
17051        mNumServiceProcs = mNewNumServiceProcs;
17052
17053        // Now determine the memory trimming level of background processes.
17054        // Unfortunately we need to start at the back of the list to do this
17055        // properly.  We only do this if the number of background apps we
17056        // are managing to keep around is less than half the maximum we desire;
17057        // if we are keeping a good number around, we'll let them use whatever
17058        // memory they want.
17059        final int numCachedAndEmpty = numCached + numEmpty;
17060        int memFactor;
17061        if (numCached <= ProcessList.TRIM_CACHED_APPS
17062                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17063            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17064                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17065            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17066                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17067            } else {
17068                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17069            }
17070        } else {
17071            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17072        }
17073        // We always allow the memory level to go up (better).  We only allow it to go
17074        // down if we are in a state where that is allowed, *and* the total number of processes
17075        // has gone down since last time.
17076        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17077                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17078                + " last=" + mLastNumProcesses);
17079        if (memFactor > mLastMemoryLevel) {
17080            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17081                memFactor = mLastMemoryLevel;
17082                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17083            }
17084        }
17085        mLastMemoryLevel = memFactor;
17086        mLastNumProcesses = mLruProcesses.size();
17087        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17088        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17089        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17090            if (mLowRamStartTime == 0) {
17091                mLowRamStartTime = now;
17092            }
17093            int step = 0;
17094            int fgTrimLevel;
17095            switch (memFactor) {
17096                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17097                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17098                    break;
17099                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17100                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17101                    break;
17102                default:
17103                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17104                    break;
17105            }
17106            int factor = numTrimming/3;
17107            int minFactor = 2;
17108            if (mHomeProcess != null) minFactor++;
17109            if (mPreviousProcess != null) minFactor++;
17110            if (factor < minFactor) factor = minFactor;
17111            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17112            for (int i=N-1; i>=0; i--) {
17113                ProcessRecord app = mLruProcesses.get(i);
17114                if (allChanged || app.procStateChanged) {
17115                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17116                    app.procStateChanged = false;
17117                }
17118                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17119                        && !app.killedByAm) {
17120                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17121                        try {
17122                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17123                                    "Trimming memory of " + app.processName
17124                                    + " to " + curLevel);
17125                            app.thread.scheduleTrimMemory(curLevel);
17126                        } catch (RemoteException e) {
17127                        }
17128                        if (false) {
17129                            // For now we won't do this; our memory trimming seems
17130                            // to be good enough at this point that destroying
17131                            // activities causes more harm than good.
17132                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17133                                    && app != mHomeProcess && app != mPreviousProcess) {
17134                                // Need to do this on its own message because the stack may not
17135                                // be in a consistent state at this point.
17136                                // For these apps we will also finish their activities
17137                                // to help them free memory.
17138                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17139                            }
17140                        }
17141                    }
17142                    app.trimMemoryLevel = curLevel;
17143                    step++;
17144                    if (step >= factor) {
17145                        step = 0;
17146                        switch (curLevel) {
17147                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17148                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17149                                break;
17150                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17151                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17152                                break;
17153                        }
17154                    }
17155                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17156                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17157                            && app.thread != null) {
17158                        try {
17159                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17160                                    "Trimming memory of heavy-weight " + app.processName
17161                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17162                            app.thread.scheduleTrimMemory(
17163                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17164                        } catch (RemoteException e) {
17165                        }
17166                    }
17167                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17168                } else {
17169                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17170                            || app.systemNoUi) && app.pendingUiClean) {
17171                        // If this application is now in the background and it
17172                        // had done UI, then give it the special trim level to
17173                        // have it free UI resources.
17174                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17175                        if (app.trimMemoryLevel < level && app.thread != null) {
17176                            try {
17177                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17178                                        "Trimming memory of bg-ui " + app.processName
17179                                        + " to " + level);
17180                                app.thread.scheduleTrimMemory(level);
17181                            } catch (RemoteException e) {
17182                            }
17183                        }
17184                        app.pendingUiClean = false;
17185                    }
17186                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17187                        try {
17188                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17189                                    "Trimming memory of fg " + app.processName
17190                                    + " to " + fgTrimLevel);
17191                            app.thread.scheduleTrimMemory(fgTrimLevel);
17192                        } catch (RemoteException e) {
17193                        }
17194                    }
17195                    app.trimMemoryLevel = fgTrimLevel;
17196                }
17197            }
17198        } else {
17199            if (mLowRamStartTime != 0) {
17200                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17201                mLowRamStartTime = 0;
17202            }
17203            for (int i=N-1; i>=0; i--) {
17204                ProcessRecord app = mLruProcesses.get(i);
17205                if (allChanged || app.procStateChanged) {
17206                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17207                    app.procStateChanged = false;
17208                }
17209                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17210                        || app.systemNoUi) && app.pendingUiClean) {
17211                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17212                            && app.thread != null) {
17213                        try {
17214                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17215                                    "Trimming memory of ui hidden " + app.processName
17216                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17217                            app.thread.scheduleTrimMemory(
17218                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17219                        } catch (RemoteException e) {
17220                        }
17221                    }
17222                    app.pendingUiClean = false;
17223                }
17224                app.trimMemoryLevel = 0;
17225            }
17226        }
17227
17228        if (mAlwaysFinishActivities) {
17229            // Need to do this on its own message because the stack may not
17230            // be in a consistent state at this point.
17231            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17232        }
17233
17234        if (allChanged) {
17235            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17236        }
17237
17238        if (mProcessStats.shouldWriteNowLocked(now)) {
17239            mHandler.post(new Runnable() {
17240                @Override public void run() {
17241                    synchronized (ActivityManagerService.this) {
17242                        mProcessStats.writeStateAsyncLocked();
17243                    }
17244                }
17245            });
17246        }
17247
17248        if (DEBUG_OOM_ADJ) {
17249            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17250        }
17251    }
17252
17253    final void trimApplications() {
17254        synchronized (this) {
17255            int i;
17256
17257            // First remove any unused application processes whose package
17258            // has been removed.
17259            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17260                final ProcessRecord app = mRemovedProcesses.get(i);
17261                if (app.activities.size() == 0
17262                        && app.curReceiver == null && app.services.size() == 0) {
17263                    Slog.i(
17264                        TAG, "Exiting empty application process "
17265                        + app.processName + " ("
17266                        + (app.thread != null ? app.thread.asBinder() : null)
17267                        + ")\n");
17268                    if (app.pid > 0 && app.pid != MY_PID) {
17269                        app.kill("empty", false);
17270                    } else {
17271                        try {
17272                            app.thread.scheduleExit();
17273                        } catch (Exception e) {
17274                            // Ignore exceptions.
17275                        }
17276                    }
17277                    cleanUpApplicationRecordLocked(app, false, true, -1);
17278                    mRemovedProcesses.remove(i);
17279
17280                    if (app.persistent) {
17281                        addAppLocked(app.info, false, null /* ABI override */);
17282                    }
17283                }
17284            }
17285
17286            // Now update the oom adj for all processes.
17287            updateOomAdjLocked();
17288        }
17289    }
17290
17291    /** This method sends the specified signal to each of the persistent apps */
17292    public void signalPersistentProcesses(int sig) throws RemoteException {
17293        if (sig != Process.SIGNAL_USR1) {
17294            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17295        }
17296
17297        synchronized (this) {
17298            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17299                    != PackageManager.PERMISSION_GRANTED) {
17300                throw new SecurityException("Requires permission "
17301                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17302            }
17303
17304            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17305                ProcessRecord r = mLruProcesses.get(i);
17306                if (r.thread != null && r.persistent) {
17307                    Process.sendSignal(r.pid, sig);
17308                }
17309            }
17310        }
17311    }
17312
17313    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17314        if (proc == null || proc == mProfileProc) {
17315            proc = mProfileProc;
17316            profileType = mProfileType;
17317            clearProfilerLocked();
17318        }
17319        if (proc == null) {
17320            return;
17321        }
17322        try {
17323            proc.thread.profilerControl(false, null, profileType);
17324        } catch (RemoteException e) {
17325            throw new IllegalStateException("Process disappeared");
17326        }
17327    }
17328
17329    private void clearProfilerLocked() {
17330        if (mProfileFd != null) {
17331            try {
17332                mProfileFd.close();
17333            } catch (IOException e) {
17334            }
17335        }
17336        mProfileApp = null;
17337        mProfileProc = null;
17338        mProfileFile = null;
17339        mProfileType = 0;
17340        mAutoStopProfiler = false;
17341        mSamplingInterval = 0;
17342    }
17343
17344    public boolean profileControl(String process, int userId, boolean start,
17345            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17346
17347        try {
17348            synchronized (this) {
17349                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17350                // its own permission.
17351                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17352                        != PackageManager.PERMISSION_GRANTED) {
17353                    throw new SecurityException("Requires permission "
17354                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17355                }
17356
17357                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17358                    throw new IllegalArgumentException("null profile info or fd");
17359                }
17360
17361                ProcessRecord proc = null;
17362                if (process != null) {
17363                    proc = findProcessLocked(process, userId, "profileControl");
17364                }
17365
17366                if (start && (proc == null || proc.thread == null)) {
17367                    throw new IllegalArgumentException("Unknown process: " + process);
17368                }
17369
17370                if (start) {
17371                    stopProfilerLocked(null, 0);
17372                    setProfileApp(proc.info, proc.processName, profilerInfo);
17373                    mProfileProc = proc;
17374                    mProfileType = profileType;
17375                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17376                    try {
17377                        fd = fd.dup();
17378                    } catch (IOException e) {
17379                        fd = null;
17380                    }
17381                    profilerInfo.profileFd = fd;
17382                    proc.thread.profilerControl(start, profilerInfo, profileType);
17383                    fd = null;
17384                    mProfileFd = null;
17385                } else {
17386                    stopProfilerLocked(proc, profileType);
17387                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17388                        try {
17389                            profilerInfo.profileFd.close();
17390                        } catch (IOException e) {
17391                        }
17392                    }
17393                }
17394
17395                return true;
17396            }
17397        } catch (RemoteException e) {
17398            throw new IllegalStateException("Process disappeared");
17399        } finally {
17400            if (profilerInfo != null && profilerInfo.profileFd != null) {
17401                try {
17402                    profilerInfo.profileFd.close();
17403                } catch (IOException e) {
17404                }
17405            }
17406        }
17407    }
17408
17409    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17410        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17411                userId, true, ALLOW_FULL_ONLY, callName, null);
17412        ProcessRecord proc = null;
17413        try {
17414            int pid = Integer.parseInt(process);
17415            synchronized (mPidsSelfLocked) {
17416                proc = mPidsSelfLocked.get(pid);
17417            }
17418        } catch (NumberFormatException e) {
17419        }
17420
17421        if (proc == null) {
17422            ArrayMap<String, SparseArray<ProcessRecord>> all
17423                    = mProcessNames.getMap();
17424            SparseArray<ProcessRecord> procs = all.get(process);
17425            if (procs != null && procs.size() > 0) {
17426                proc = procs.valueAt(0);
17427                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17428                    for (int i=1; i<procs.size(); i++) {
17429                        ProcessRecord thisProc = procs.valueAt(i);
17430                        if (thisProc.userId == userId) {
17431                            proc = thisProc;
17432                            break;
17433                        }
17434                    }
17435                }
17436            }
17437        }
17438
17439        return proc;
17440    }
17441
17442    public boolean dumpHeap(String process, int userId, boolean managed,
17443            String path, ParcelFileDescriptor fd) throws RemoteException {
17444
17445        try {
17446            synchronized (this) {
17447                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17448                // its own permission (same as profileControl).
17449                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17450                        != PackageManager.PERMISSION_GRANTED) {
17451                    throw new SecurityException("Requires permission "
17452                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17453                }
17454
17455                if (fd == null) {
17456                    throw new IllegalArgumentException("null fd");
17457                }
17458
17459                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17460                if (proc == null || proc.thread == null) {
17461                    throw new IllegalArgumentException("Unknown process: " + process);
17462                }
17463
17464                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17465                if (!isDebuggable) {
17466                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17467                        throw new SecurityException("Process not debuggable: " + proc);
17468                    }
17469                }
17470
17471                proc.thread.dumpHeap(managed, path, fd);
17472                fd = null;
17473                return true;
17474            }
17475        } catch (RemoteException e) {
17476            throw new IllegalStateException("Process disappeared");
17477        } finally {
17478            if (fd != null) {
17479                try {
17480                    fd.close();
17481                } catch (IOException e) {
17482                }
17483            }
17484        }
17485    }
17486
17487    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17488    public void monitor() {
17489        synchronized (this) { }
17490    }
17491
17492    void onCoreSettingsChange(Bundle settings) {
17493        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17494            ProcessRecord processRecord = mLruProcesses.get(i);
17495            try {
17496                if (processRecord.thread != null) {
17497                    processRecord.thread.setCoreSettings(settings);
17498                }
17499            } catch (RemoteException re) {
17500                /* ignore */
17501            }
17502        }
17503    }
17504
17505    // Multi-user methods
17506
17507    /**
17508     * Start user, if its not already running, but don't bring it to foreground.
17509     */
17510    @Override
17511    public boolean startUserInBackground(final int userId) {
17512        return startUser(userId, /* foreground */ false);
17513    }
17514
17515    /**
17516     * Start user, if its not already running, and bring it to foreground.
17517     */
17518    boolean startUserInForeground(final int userId, Dialog dlg) {
17519        boolean result = startUser(userId, /* foreground */ true);
17520        dlg.dismiss();
17521        return result;
17522    }
17523
17524    /**
17525     * Refreshes the list of users related to the current user when either a
17526     * user switch happens or when a new related user is started in the
17527     * background.
17528     */
17529    private void updateCurrentProfileIdsLocked() {
17530        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17531                mCurrentUserId, false /* enabledOnly */);
17532        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17533        for (int i = 0; i < currentProfileIds.length; i++) {
17534            currentProfileIds[i] = profiles.get(i).id;
17535        }
17536        mCurrentProfileIds = currentProfileIds;
17537
17538        synchronized (mUserProfileGroupIdsSelfLocked) {
17539            mUserProfileGroupIdsSelfLocked.clear();
17540            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17541            for (int i = 0; i < users.size(); i++) {
17542                UserInfo user = users.get(i);
17543                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17544                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17545                }
17546            }
17547        }
17548    }
17549
17550    private Set getProfileIdsLocked(int userId) {
17551        Set userIds = new HashSet<Integer>();
17552        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17553                userId, false /* enabledOnly */);
17554        for (UserInfo user : profiles) {
17555            userIds.add(Integer.valueOf(user.id));
17556        }
17557        return userIds;
17558    }
17559
17560    @Override
17561    public boolean switchUser(final int userId) {
17562        String userName;
17563        synchronized (this) {
17564            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17565            if (userInfo == null) {
17566                Slog.w(TAG, "No user info for user #" + userId);
17567                return false;
17568            }
17569            if (userInfo.isManagedProfile()) {
17570                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17571                return false;
17572            }
17573            userName = userInfo.name;
17574        }
17575        mHandler.removeMessages(START_USER_SWITCH_MSG);
17576        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17577        return true;
17578    }
17579
17580    private void showUserSwitchDialog(int userId, String userName) {
17581        // The dialog will show and then initiate the user switch by calling startUserInForeground
17582        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17583                true /* above system */);
17584        d.show();
17585    }
17586
17587    private boolean startUser(final int userId, final boolean foreground) {
17588        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17589                != PackageManager.PERMISSION_GRANTED) {
17590            String msg = "Permission Denial: switchUser() from pid="
17591                    + Binder.getCallingPid()
17592                    + ", uid=" + Binder.getCallingUid()
17593                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17594            Slog.w(TAG, msg);
17595            throw new SecurityException(msg);
17596        }
17597
17598        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17599
17600        final long ident = Binder.clearCallingIdentity();
17601        try {
17602            synchronized (this) {
17603                final int oldUserId = mCurrentUserId;
17604                if (oldUserId == userId) {
17605                    return true;
17606                }
17607
17608                mStackSupervisor.setLockTaskModeLocked(null, false);
17609
17610                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17611                if (userInfo == null) {
17612                    Slog.w(TAG, "No user info for user #" + userId);
17613                    return false;
17614                }
17615                if (foreground && userInfo.isManagedProfile()) {
17616                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17617                    return false;
17618                }
17619
17620                if (foreground) {
17621                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17622                            R.anim.screen_user_enter);
17623                }
17624
17625                boolean needStart = false;
17626
17627                // If the user we are switching to is not currently started, then
17628                // we need to start it now.
17629                if (mStartedUsers.get(userId) == null) {
17630                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17631                    updateStartedUserArrayLocked();
17632                    needStart = true;
17633                }
17634
17635                final Integer userIdInt = Integer.valueOf(userId);
17636                mUserLru.remove(userIdInt);
17637                mUserLru.add(userIdInt);
17638
17639                if (foreground) {
17640                    mCurrentUserId = userId;
17641                    updateCurrentProfileIdsLocked();
17642                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17643                    // Once the internal notion of the active user has switched, we lock the device
17644                    // with the option to show the user switcher on the keyguard.
17645                    mWindowManager.lockNow(null);
17646                } else {
17647                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17648                    updateCurrentProfileIdsLocked();
17649                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17650                    mUserLru.remove(currentUserIdInt);
17651                    mUserLru.add(currentUserIdInt);
17652                }
17653
17654                final UserStartedState uss = mStartedUsers.get(userId);
17655
17656                // Make sure user is in the started state.  If it is currently
17657                // stopping, we need to knock that off.
17658                if (uss.mState == UserStartedState.STATE_STOPPING) {
17659                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17660                    // so we can just fairly silently bring the user back from
17661                    // the almost-dead.
17662                    uss.mState = UserStartedState.STATE_RUNNING;
17663                    updateStartedUserArrayLocked();
17664                    needStart = true;
17665                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17666                    // This means ACTION_SHUTDOWN has been sent, so we will
17667                    // need to treat this as a new boot of the user.
17668                    uss.mState = UserStartedState.STATE_BOOTING;
17669                    updateStartedUserArrayLocked();
17670                    needStart = true;
17671                }
17672
17673                if (uss.mState == UserStartedState.STATE_BOOTING) {
17674                    // Booting up a new user, need to tell system services about it.
17675                    // Note that this is on the same handler as scheduling of broadcasts,
17676                    // which is important because it needs to go first.
17677                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17678                }
17679
17680                if (foreground) {
17681                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17682                            oldUserId));
17683                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17684                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17685                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17686                            oldUserId, userId, uss));
17687                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17688                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17689                }
17690
17691                if (needStart) {
17692                    // Send USER_STARTED broadcast
17693                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17694                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17695                            | Intent.FLAG_RECEIVER_FOREGROUND);
17696                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17697                    broadcastIntentLocked(null, null, intent,
17698                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17699                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17700                }
17701
17702                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17703                    if (userId != UserHandle.USER_OWNER) {
17704                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17705                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17706                        broadcastIntentLocked(null, null, intent, null,
17707                                new IIntentReceiver.Stub() {
17708                                    public void performReceive(Intent intent, int resultCode,
17709                                            String data, Bundle extras, boolean ordered,
17710                                            boolean sticky, int sendingUser) {
17711                                        onUserInitialized(uss, foreground, oldUserId, userId);
17712                                    }
17713                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17714                                true, false, MY_PID, Process.SYSTEM_UID,
17715                                userId);
17716                        uss.initializing = true;
17717                    } else {
17718                        getUserManagerLocked().makeInitialized(userInfo.id);
17719                    }
17720                }
17721
17722                if (foreground) {
17723                    if (!uss.initializing) {
17724                        moveUserToForeground(uss, oldUserId, userId);
17725                    }
17726                } else {
17727                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17728                }
17729
17730                if (needStart) {
17731                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17732                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17733                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17734                    broadcastIntentLocked(null, null, intent,
17735                            null, new IIntentReceiver.Stub() {
17736                                @Override
17737                                public void performReceive(Intent intent, int resultCode, String data,
17738                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17739                                        throws RemoteException {
17740                                }
17741                            }, 0, null, null,
17742                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17743                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17744                }
17745            }
17746        } finally {
17747            Binder.restoreCallingIdentity(ident);
17748        }
17749
17750        return true;
17751    }
17752
17753    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17754        long ident = Binder.clearCallingIdentity();
17755        try {
17756            Intent intent;
17757            if (oldUserId >= 0) {
17758                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17759                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17760                int count = profiles.size();
17761                for (int i = 0; i < count; i++) {
17762                    int profileUserId = profiles.get(i).id;
17763                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17764                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17765                            | Intent.FLAG_RECEIVER_FOREGROUND);
17766                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17767                    broadcastIntentLocked(null, null, intent,
17768                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17769                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17770                }
17771            }
17772            if (newUserId >= 0) {
17773                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17774                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17775                int count = profiles.size();
17776                for (int i = 0; i < count; i++) {
17777                    int profileUserId = profiles.get(i).id;
17778                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17779                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17780                            | Intent.FLAG_RECEIVER_FOREGROUND);
17781                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17782                    broadcastIntentLocked(null, null, intent,
17783                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17784                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17785                }
17786                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17787                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17788                        | Intent.FLAG_RECEIVER_FOREGROUND);
17789                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17790                broadcastIntentLocked(null, null, intent,
17791                        null, null, 0, null, null,
17792                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17793                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17794            }
17795        } finally {
17796            Binder.restoreCallingIdentity(ident);
17797        }
17798    }
17799
17800    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17801            final int newUserId) {
17802        final int N = mUserSwitchObservers.beginBroadcast();
17803        if (N > 0) {
17804            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17805                int mCount = 0;
17806                @Override
17807                public void sendResult(Bundle data) throws RemoteException {
17808                    synchronized (ActivityManagerService.this) {
17809                        if (mCurUserSwitchCallback == this) {
17810                            mCount++;
17811                            if (mCount == N) {
17812                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17813                            }
17814                        }
17815                    }
17816                }
17817            };
17818            synchronized (this) {
17819                uss.switching = true;
17820                mCurUserSwitchCallback = callback;
17821            }
17822            for (int i=0; i<N; i++) {
17823                try {
17824                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17825                            newUserId, callback);
17826                } catch (RemoteException e) {
17827                }
17828            }
17829        } else {
17830            synchronized (this) {
17831                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17832            }
17833        }
17834        mUserSwitchObservers.finishBroadcast();
17835    }
17836
17837    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17838        synchronized (this) {
17839            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17840            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17841        }
17842    }
17843
17844    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17845        mCurUserSwitchCallback = null;
17846        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17847        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17848                oldUserId, newUserId, uss));
17849    }
17850
17851    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
17852        synchronized (this) {
17853            if (foreground) {
17854                moveUserToForeground(uss, oldUserId, newUserId);
17855            }
17856        }
17857
17858        completeSwitchAndInitalize(uss, newUserId, true, false);
17859    }
17860
17861    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
17862        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
17863        if (homeInFront) {
17864            startHomeActivityLocked(newUserId);
17865        } else {
17866            mStackSupervisor.resumeTopActivitiesLocked();
17867        }
17868        EventLogTags.writeAmSwitchUser(newUserId);
17869        getUserManagerLocked().userForeground(newUserId);
17870        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
17871    }
17872
17873    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17874        completeSwitchAndInitalize(uss, newUserId, false, true);
17875    }
17876
17877    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17878            boolean clearInitializing, boolean clearSwitching) {
17879        boolean unfrozen = false;
17880        synchronized (this) {
17881            if (clearInitializing) {
17882                uss.initializing = false;
17883                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17884            }
17885            if (clearSwitching) {
17886                uss.switching = false;
17887            }
17888            if (!uss.switching && !uss.initializing) {
17889                mWindowManager.stopFreezingScreen();
17890                unfrozen = true;
17891            }
17892        }
17893        if (unfrozen) {
17894            final int N = mUserSwitchObservers.beginBroadcast();
17895            for (int i=0; i<N; i++) {
17896                try {
17897                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17898                } catch (RemoteException e) {
17899                }
17900            }
17901            mUserSwitchObservers.finishBroadcast();
17902        }
17903    }
17904
17905    void scheduleStartProfilesLocked() {
17906        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17907            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17908                    DateUtils.SECOND_IN_MILLIS);
17909        }
17910    }
17911
17912    void startProfilesLocked() {
17913        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17914        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17915                mCurrentUserId, false /* enabledOnly */);
17916        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17917        for (UserInfo user : profiles) {
17918            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17919                    && user.id != mCurrentUserId) {
17920                toStart.add(user);
17921            }
17922        }
17923        final int n = toStart.size();
17924        int i = 0;
17925        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17926            startUserInBackground(toStart.get(i).id);
17927        }
17928        if (i < n) {
17929            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17930        }
17931    }
17932
17933    void finishUserBoot(UserStartedState uss) {
17934        synchronized (this) {
17935            if (uss.mState == UserStartedState.STATE_BOOTING
17936                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17937                uss.mState = UserStartedState.STATE_RUNNING;
17938                final int userId = uss.mHandle.getIdentifier();
17939                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17940                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17941                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17942                broadcastIntentLocked(null, null, intent,
17943                        null, null, 0, null, null,
17944                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17945                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17946            }
17947        }
17948    }
17949
17950    void finishUserSwitch(UserStartedState uss) {
17951        synchronized (this) {
17952            finishUserBoot(uss);
17953
17954            startProfilesLocked();
17955
17956            int num = mUserLru.size();
17957            int i = 0;
17958            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17959                Integer oldUserId = mUserLru.get(i);
17960                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17961                if (oldUss == null) {
17962                    // Shouldn't happen, but be sane if it does.
17963                    mUserLru.remove(i);
17964                    num--;
17965                    continue;
17966                }
17967                if (oldUss.mState == UserStartedState.STATE_STOPPING
17968                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17969                    // This user is already stopping, doesn't count.
17970                    num--;
17971                    i++;
17972                    continue;
17973                }
17974                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17975                    // Owner and current can't be stopped, but count as running.
17976                    i++;
17977                    continue;
17978                }
17979                // This is a user to be stopped.
17980                stopUserLocked(oldUserId, null);
17981                num--;
17982                i++;
17983            }
17984        }
17985    }
17986
17987    @Override
17988    public int stopUser(final int userId, final IStopUserCallback callback) {
17989        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17990                != PackageManager.PERMISSION_GRANTED) {
17991            String msg = "Permission Denial: switchUser() from pid="
17992                    + Binder.getCallingPid()
17993                    + ", uid=" + Binder.getCallingUid()
17994                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17995            Slog.w(TAG, msg);
17996            throw new SecurityException(msg);
17997        }
17998        if (userId <= 0) {
17999            throw new IllegalArgumentException("Can't stop primary user " + userId);
18000        }
18001        synchronized (this) {
18002            return stopUserLocked(userId, callback);
18003        }
18004    }
18005
18006    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18007        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18008        if (mCurrentUserId == userId) {
18009            return ActivityManager.USER_OP_IS_CURRENT;
18010        }
18011
18012        final UserStartedState uss = mStartedUsers.get(userId);
18013        if (uss == null) {
18014            // User is not started, nothing to do...  but we do need to
18015            // callback if requested.
18016            if (callback != null) {
18017                mHandler.post(new Runnable() {
18018                    @Override
18019                    public void run() {
18020                        try {
18021                            callback.userStopped(userId);
18022                        } catch (RemoteException e) {
18023                        }
18024                    }
18025                });
18026            }
18027            return ActivityManager.USER_OP_SUCCESS;
18028        }
18029
18030        if (callback != null) {
18031            uss.mStopCallbacks.add(callback);
18032        }
18033
18034        if (uss.mState != UserStartedState.STATE_STOPPING
18035                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18036            uss.mState = UserStartedState.STATE_STOPPING;
18037            updateStartedUserArrayLocked();
18038
18039            long ident = Binder.clearCallingIdentity();
18040            try {
18041                // We are going to broadcast ACTION_USER_STOPPING and then
18042                // once that is done send a final ACTION_SHUTDOWN and then
18043                // stop the user.
18044                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18045                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18046                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18047                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18048                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18049                // This is the result receiver for the final shutdown broadcast.
18050                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18051                    @Override
18052                    public void performReceive(Intent intent, int resultCode, String data,
18053                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18054                        finishUserStop(uss);
18055                    }
18056                };
18057                // This is the result receiver for the initial stopping broadcast.
18058                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18059                    @Override
18060                    public void performReceive(Intent intent, int resultCode, String data,
18061                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18062                        // On to the next.
18063                        synchronized (ActivityManagerService.this) {
18064                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18065                                // Whoops, we are being started back up.  Abort, abort!
18066                                return;
18067                            }
18068                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18069                        }
18070                        mBatteryStatsService.noteEvent(
18071                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18072                                Integer.toString(userId), userId);
18073                        mSystemServiceManager.stopUser(userId);
18074                        broadcastIntentLocked(null, null, shutdownIntent,
18075                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18076                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18077                    }
18078                };
18079                // Kick things off.
18080                broadcastIntentLocked(null, null, stoppingIntent,
18081                        null, stoppingReceiver, 0, null, null,
18082                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18083                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18084            } finally {
18085                Binder.restoreCallingIdentity(ident);
18086            }
18087        }
18088
18089        return ActivityManager.USER_OP_SUCCESS;
18090    }
18091
18092    void finishUserStop(UserStartedState uss) {
18093        final int userId = uss.mHandle.getIdentifier();
18094        boolean stopped;
18095        ArrayList<IStopUserCallback> callbacks;
18096        synchronized (this) {
18097            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18098            if (mStartedUsers.get(userId) != uss) {
18099                stopped = false;
18100            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18101                stopped = false;
18102            } else {
18103                stopped = true;
18104                // User can no longer run.
18105                mStartedUsers.remove(userId);
18106                mUserLru.remove(Integer.valueOf(userId));
18107                updateStartedUserArrayLocked();
18108
18109                // Clean up all state and processes associated with the user.
18110                // Kill all the processes for the user.
18111                forceStopUserLocked(userId, "finish user");
18112            }
18113
18114            // Explicitly remove the old information in mRecentTasks.
18115            removeRecentTasksForUserLocked(userId);
18116        }
18117
18118        for (int i=0; i<callbacks.size(); i++) {
18119            try {
18120                if (stopped) callbacks.get(i).userStopped(userId);
18121                else callbacks.get(i).userStopAborted(userId);
18122            } catch (RemoteException e) {
18123            }
18124        }
18125
18126        if (stopped) {
18127            mSystemServiceManager.cleanupUser(userId);
18128            synchronized (this) {
18129                mStackSupervisor.removeUserLocked(userId);
18130            }
18131        }
18132    }
18133
18134    @Override
18135    public UserInfo getCurrentUser() {
18136        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18137                != PackageManager.PERMISSION_GRANTED) && (
18138                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18139                != PackageManager.PERMISSION_GRANTED)) {
18140            String msg = "Permission Denial: getCurrentUser() 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 getUserManagerLocked().getUserInfo(mCurrentUserId);
18149        }
18150    }
18151
18152    int getCurrentUserIdLocked() {
18153        return mCurrentUserId;
18154    }
18155
18156    @Override
18157    public boolean isUserRunning(int userId, boolean orStopped) {
18158        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18159                != PackageManager.PERMISSION_GRANTED) {
18160            String msg = "Permission Denial: isUserRunning() from pid="
18161                    + Binder.getCallingPid()
18162                    + ", uid=" + Binder.getCallingUid()
18163                    + " requires " + INTERACT_ACROSS_USERS;
18164            Slog.w(TAG, msg);
18165            throw new SecurityException(msg);
18166        }
18167        synchronized (this) {
18168            return isUserRunningLocked(userId, orStopped);
18169        }
18170    }
18171
18172    boolean isUserRunningLocked(int userId, boolean orStopped) {
18173        UserStartedState state = mStartedUsers.get(userId);
18174        if (state == null) {
18175            return false;
18176        }
18177        if (orStopped) {
18178            return true;
18179        }
18180        return state.mState != UserStartedState.STATE_STOPPING
18181                && state.mState != UserStartedState.STATE_SHUTDOWN;
18182    }
18183
18184    @Override
18185    public int[] getRunningUserIds() {
18186        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18187                != PackageManager.PERMISSION_GRANTED) {
18188            String msg = "Permission Denial: isUserRunning() from pid="
18189                    + Binder.getCallingPid()
18190                    + ", uid=" + Binder.getCallingUid()
18191                    + " requires " + INTERACT_ACROSS_USERS;
18192            Slog.w(TAG, msg);
18193            throw new SecurityException(msg);
18194        }
18195        synchronized (this) {
18196            return mStartedUserArray;
18197        }
18198    }
18199
18200    private void updateStartedUserArrayLocked() {
18201        int num = 0;
18202        for (int i=0; i<mStartedUsers.size();  i++) {
18203            UserStartedState uss = mStartedUsers.valueAt(i);
18204            // This list does not include stopping users.
18205            if (uss.mState != UserStartedState.STATE_STOPPING
18206                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18207                num++;
18208            }
18209        }
18210        mStartedUserArray = new int[num];
18211        num = 0;
18212        for (int i=0; i<mStartedUsers.size();  i++) {
18213            UserStartedState uss = mStartedUsers.valueAt(i);
18214            if (uss.mState != UserStartedState.STATE_STOPPING
18215                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18216                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18217                num++;
18218            }
18219        }
18220    }
18221
18222    @Override
18223    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18224        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18225                != PackageManager.PERMISSION_GRANTED) {
18226            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18227                    + Binder.getCallingPid()
18228                    + ", uid=" + Binder.getCallingUid()
18229                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18230            Slog.w(TAG, msg);
18231            throw new SecurityException(msg);
18232        }
18233
18234        mUserSwitchObservers.register(observer);
18235    }
18236
18237    @Override
18238    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18239        mUserSwitchObservers.unregister(observer);
18240    }
18241
18242    private boolean userExists(int userId) {
18243        if (userId == 0) {
18244            return true;
18245        }
18246        UserManagerService ums = getUserManagerLocked();
18247        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18248    }
18249
18250    int[] getUsersLocked() {
18251        UserManagerService ums = getUserManagerLocked();
18252        return ums != null ? ums.getUserIds() : new int[] { 0 };
18253    }
18254
18255    UserManagerService getUserManagerLocked() {
18256        if (mUserManager == null) {
18257            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18258            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18259        }
18260        return mUserManager;
18261    }
18262
18263    private int applyUserId(int uid, int userId) {
18264        return UserHandle.getUid(userId, uid);
18265    }
18266
18267    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18268        if (info == null) return null;
18269        ApplicationInfo newInfo = new ApplicationInfo(info);
18270        newInfo.uid = applyUserId(info.uid, userId);
18271        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18272                + info.packageName;
18273        return newInfo;
18274    }
18275
18276    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18277        if (aInfo == null
18278                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18279            return aInfo;
18280        }
18281
18282        ActivityInfo info = new ActivityInfo(aInfo);
18283        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18284        return info;
18285    }
18286
18287    private final class LocalService extends ActivityManagerInternal {
18288        @Override
18289        public void goingToSleep() {
18290            ActivityManagerService.this.goingToSleep();
18291        }
18292
18293        @Override
18294        public void wakingUp() {
18295            ActivityManagerService.this.wakingUp();
18296        }
18297
18298        @Override
18299        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18300                String processName, String abiOverride, int uid, Runnable crashHandler) {
18301            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18302                    processName, abiOverride, uid, crashHandler);
18303        }
18304    }
18305
18306    /**
18307     * An implementation of IAppTask, that allows an app to manage its own tasks via
18308     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18309     * only the process that calls getAppTasks() can call the AppTask methods.
18310     */
18311    class AppTaskImpl extends IAppTask.Stub {
18312        private int mTaskId;
18313        private int mCallingUid;
18314
18315        public AppTaskImpl(int taskId, int callingUid) {
18316            mTaskId = taskId;
18317            mCallingUid = callingUid;
18318        }
18319
18320        private void checkCaller() {
18321            if (mCallingUid != Binder.getCallingUid()) {
18322                throw new SecurityException("Caller " + mCallingUid
18323                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18324            }
18325        }
18326
18327        @Override
18328        public void finishAndRemoveTask() {
18329            checkCaller();
18330
18331            synchronized (ActivityManagerService.this) {
18332                long origId = Binder.clearCallingIdentity();
18333                try {
18334                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18335                    if (tr == null) {
18336                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18337                    }
18338                    // Only kill the process if we are not a new document
18339                    int flags = tr.getBaseIntent().getFlags();
18340                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18341                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18342                    removeTaskByIdLocked(mTaskId,
18343                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18344                } finally {
18345                    Binder.restoreCallingIdentity(origId);
18346                }
18347            }
18348        }
18349
18350        @Override
18351        public ActivityManager.RecentTaskInfo getTaskInfo() {
18352            checkCaller();
18353
18354            synchronized (ActivityManagerService.this) {
18355                long origId = Binder.clearCallingIdentity();
18356                try {
18357                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18358                    if (tr == null) {
18359                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18360                    }
18361                    return createRecentTaskInfoFromTaskRecord(tr);
18362                } finally {
18363                    Binder.restoreCallingIdentity(origId);
18364                }
18365            }
18366        }
18367
18368        @Override
18369        public void moveToFront() {
18370            checkCaller();
18371
18372            final TaskRecord tr;
18373            synchronized (ActivityManagerService.this) {
18374                tr = recentTaskForIdLocked(mTaskId);
18375                if (tr == null) {
18376                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18377                }
18378                if (tr.getRootActivity() != null) {
18379                    long origId = Binder.clearCallingIdentity();
18380                    try {
18381                        moveTaskToFrontLocked(tr.taskId, 0, null);
18382                        return;
18383                    } finally {
18384                        Binder.restoreCallingIdentity(origId);
18385                    }
18386                }
18387            }
18388
18389            startActivityFromRecentsInner(tr.taskId, null);
18390        }
18391
18392        @Override
18393        public int startActivity(IBinder whoThread, String callingPackage,
18394                Intent intent, String resolvedType, Bundle options) {
18395            checkCaller();
18396
18397            int callingUser = UserHandle.getCallingUserId();
18398            TaskRecord tr;
18399            IApplicationThread appThread;
18400            synchronized (ActivityManagerService.this) {
18401                tr = recentTaskForIdLocked(mTaskId);
18402                if (tr == null) {
18403                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18404                }
18405                appThread = ApplicationThreadNative.asInterface(whoThread);
18406                if (appThread == null) {
18407                    throw new IllegalArgumentException("Bad app thread " + appThread);
18408                }
18409            }
18410            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18411                    resolvedType, null, null, null, null, 0, 0, null, null,
18412                    null, options, callingUser, null, tr);
18413        }
18414
18415        @Override
18416        public void setExcludeFromRecents(boolean exclude) {
18417            checkCaller();
18418
18419            synchronized (ActivityManagerService.this) {
18420                long origId = Binder.clearCallingIdentity();
18421                try {
18422                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18423                    if (tr == null) {
18424                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18425                    }
18426                    Intent intent = tr.getBaseIntent();
18427                    if (exclude) {
18428                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18429                    } else {
18430                        intent.setFlags(intent.getFlags()
18431                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18432                    }
18433                } finally {
18434                    Binder.restoreCallingIdentity(origId);
18435                }
18436            }
18437        }
18438    }
18439}
18440