ActivityManagerService.java revision fbe96706bb9754f9ea3f6345f32e058a45ad10b4
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.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PowerManagerInternal;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203import dalvik.system.VMRuntime;
204
205import java.io.BufferedInputStream;
206import java.io.BufferedOutputStream;
207import java.io.DataInputStream;
208import java.io.DataOutputStream;
209import java.io.File;
210import java.io.FileDescriptor;
211import java.io.FileInputStream;
212import java.io.FileNotFoundException;
213import java.io.FileOutputStream;
214import java.io.IOException;
215import java.io.InputStreamReader;
216import java.io.PrintWriter;
217import java.io.StringWriter;
218import java.lang.ref.WeakReference;
219import java.util.ArrayList;
220import java.util.Arrays;
221import java.util.Collections;
222import java.util.Comparator;
223import java.util.HashMap;
224import java.util.HashSet;
225import java.util.Iterator;
226import java.util.List;
227import java.util.Locale;
228import java.util.Map;
229import java.util.Set;
230import java.util.concurrent.atomic.AtomicBoolean;
231import java.util.concurrent.atomic.AtomicLong;
232
233public final class ActivityManagerService extends ActivityManagerNative
234        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
235
236    private static final String USER_DATA_DIR = "/data/user/";
237    // File that stores last updated system version and called preboot receivers
238    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
239
240    static final String TAG = "ActivityManager";
241    static final String TAG_MU = "ActivityManagerServiceMU";
242    static final boolean DEBUG = false;
243    static final boolean localLOGV = DEBUG;
244    static final boolean DEBUG_BACKUP = localLOGV || false;
245    static final boolean DEBUG_BROADCAST = localLOGV || false;
246    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_CLEANUP = localLOGV || false;
249    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
250    static final boolean DEBUG_FOCUS = false;
251    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
252    static final boolean DEBUG_MU = localLOGV || false;
253    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
254    static final boolean DEBUG_LRU = localLOGV || false;
255    static final boolean DEBUG_PAUSE = localLOGV || false;
256    static final boolean DEBUG_POWER = localLOGV || false;
257    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
258    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
259    static final boolean DEBUG_PROCESSES = localLOGV || false;
260    static final boolean DEBUG_PROVIDER = localLOGV || false;
261    static final boolean DEBUG_RESULTS = localLOGV || false;
262    static final boolean DEBUG_SERVICE = localLOGV || false;
263    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
264    static final boolean DEBUG_STACK = localLOGV || false;
265    static final boolean DEBUG_SWITCH = localLOGV || false;
266    static final boolean DEBUG_TASKS = localLOGV || false;
267    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
268    static final boolean DEBUG_TRANSITION = localLOGV || false;
269    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
270    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
271    static final boolean DEBUG_VISBILITY = localLOGV || false;
272    static final boolean DEBUG_PSS = localLOGV || false;
273    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
274    static final boolean DEBUG_RECENTS = localLOGV || false;
275    static final boolean VALIDATE_TOKENS = false;
276    static final boolean SHOW_ACTIVITY_START_TIME = true;
277
278    // Control over CPU and battery monitoring.
279    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
280    static final boolean MONITOR_CPU_USAGE = true;
281    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
282    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
283    static final boolean MONITOR_THREAD_CPU_USAGE = false;
284
285    // The flags that are set for all calls we make to the package manager.
286    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
287
288    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
289
290    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
291
292    // Maximum number recent bitmaps to keep in memory.
293    static final int MAX_RECENT_BITMAPS = 5;
294
295    // Amount of time after a call to stopAppSwitches() during which we will
296    // prevent further untrusted switches from happening.
297    static final long APP_SWITCH_DELAY_TIME = 5*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real.
301    static final int PROC_START_TIMEOUT = 10*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real, when the process was
305    // started with a wrapper for instrumentation (such as Valgrind) because it
306    // could take much longer than usual.
307    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
308
309    // How long to wait after going idle before forcing apps to GC.
310    static final int GC_TIMEOUT = 5*1000;
311
312    // The minimum amount of time between successive GC requests for a process.
313    static final int GC_MIN_INTERVAL = 60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process.
316    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process
319    // when the request is due to the memory state being lowered.
320    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
321
322    // The rate at which we check for apps using excessive power -- 15 mins.
323    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on wake locks to start killing things.
327    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on CPU usage to start killing things.
331    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // How long we allow a receiver to run before giving up on it.
334    static final int BROADCAST_FG_TIMEOUT = 10*1000;
335    static final int BROADCAST_BG_TIMEOUT = 60*1000;
336
337    // How long we wait until we timeout on key dispatching.
338    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
339
340    // How long we wait until we timeout on key dispatching during instrumentation.
341    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
342
343    // Amount of time we wait for observers to handle a user switch before
344    // giving up on them and unfreezing the screen.
345    static final int USER_SWITCH_TIMEOUT = 2*1000;
346
347    // Maximum number of users we allow to be running at a time.
348    static final int MAX_RUNNING_USERS = 3;
349
350    // How long to wait in getAssistContextExtras for the activity and foreground services
351    // to respond with the result.
352    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
353
354    // Maximum number of persisted Uri grants a package is allowed
355    static final int MAX_PERSISTED_URI_GRANTS = 128;
356
357    static final int MY_PID = Process.myPid();
358
359    static final String[] EMPTY_STRING_ARRAY = new String[0];
360
361    // How many bytes to write into the dropbox log before truncating
362    static final int DROPBOX_MAX_SIZE = 256 * 1024;
363
364    // Access modes for handleIncomingUser.
365    static final int ALLOW_NON_FULL = 0;
366    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
367    static final int ALLOW_FULL_ONLY = 2;
368
369    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
370
371    /** All system services */
372    SystemServiceManager mSystemServiceManager;
373
374    /** Run all ActivityStacks through this */
375    ActivityStackSupervisor mStackSupervisor;
376
377    public IntentFirewall mIntentFirewall;
378
379    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
380    // default actuion automatically.  Important for devices without direct input
381    // devices.
382    private boolean mShowDialogs = true;
383
384    BroadcastQueue mFgBroadcastQueue;
385    BroadcastQueue mBgBroadcastQueue;
386    // Convenient for easy iteration over the queues. Foreground is first
387    // so that dispatch of foreground broadcasts gets precedence.
388    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
389
390    BroadcastQueue broadcastQueueForIntent(Intent intent) {
391        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
392        if (DEBUG_BACKGROUND_BROADCAST) {
393            Slog.i(TAG, "Broadcast intent " + intent + " on "
394                    + (isFg ? "foreground" : "background")
395                    + " queue");
396        }
397        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
398    }
399
400    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
401        for (BroadcastQueue queue : mBroadcastQueues) {
402            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
403            if (r != null) {
404                return r;
405            }
406        }
407        return null;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    ArrayList<TaskRecord> mRecentTasks;
419    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
420
421    /**
422     * For addAppTask: cached of the last activity component that was added.
423     */
424    ComponentName mLastAddedTaskComponent;
425
426    /**
427     * For addAppTask: cached of the last activity uid that was added.
428     */
429    int mLastAddedTaskUid;
430
431    /**
432     * For addAppTask: cached of the last ActivityInfo that was added.
433     */
434    ActivityInfo mLastAddedTaskActivity;
435
436    public class PendingAssistExtras extends Binder implements Runnable {
437        public final ActivityRecord activity;
438        public final Bundle extras;
439        public final Intent intent;
440        public final String hint;
441        public final int userHandle;
442        public boolean haveResult = false;
443        public Bundle result = null;
444        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
445                String _hint, int _userHandle) {
446            activity = _activity;
447            extras = _extras;
448            intent = _intent;
449            hint = _hint;
450            userHandle = _userHandle;
451        }
452        @Override
453        public void run() {
454            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
455            synchronized (this) {
456                haveResult = true;
457                notifyAll();
458            }
459        }
460    }
461
462    final ArrayList<PendingAssistExtras> mPendingAssistExtras
463            = new ArrayList<PendingAssistExtras>();
464
465    /**
466     * Process management.
467     */
468    final ProcessList mProcessList = new ProcessList();
469
470    /**
471     * All of the applications we currently have running organized by name.
472     * The keys are strings of the application package name (as
473     * returned by the package manager), and the keys are ApplicationRecord
474     * objects.
475     */
476    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
477
478    /**
479     * Tracking long-term execution of processes to look for abuse and other
480     * bad app behavior.
481     */
482    final ProcessStatsService mProcessStats;
483
484    /**
485     * The currently running isolated processes.
486     */
487    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
488
489    /**
490     * Counter for assigning isolated process uids, to avoid frequently reusing the
491     * same ones.
492     */
493    int mNextIsolatedProcessUid = 0;
494
495    /**
496     * The currently running heavy-weight process, if any.
497     */
498    ProcessRecord mHeavyWeightProcess = null;
499
500    /**
501     * The last time that various processes have crashed.
502     */
503    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
504
505    /**
506     * Information about a process that is currently marked as bad.
507     */
508    static final class BadProcessInfo {
509        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
510            this.time = time;
511            this.shortMsg = shortMsg;
512            this.longMsg = longMsg;
513            this.stack = stack;
514        }
515
516        final long time;
517        final String shortMsg;
518        final String longMsg;
519        final String stack;
520    }
521
522    /**
523     * Set of applications that we consider to be bad, and will reject
524     * incoming broadcasts from (which the user has no control over).
525     * Processes are added to this set when they have crashed twice within
526     * a minimum amount of time; they are removed from it when they are
527     * later restarted (hopefully due to some user action).  The value is the
528     * time it was added to the list.
529     */
530    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
531
532    /**
533     * All of the processes we currently have running organized by pid.
534     * The keys are the pid running the application.
535     *
536     * <p>NOTE: This object is protected by its own lock, NOT the global
537     * activity manager lock!
538     */
539    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
540
541    /**
542     * All of the processes that have been forced to be foreground.  The key
543     * is the pid of the caller who requested it (we hold a death
544     * link on it).
545     */
546    abstract class ForegroundToken implements IBinder.DeathRecipient {
547        int pid;
548        IBinder token;
549    }
550    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
551
552    /**
553     * List of records for processes that someone had tried to start before the
554     * system was ready.  We don't start them at that point, but ensure they
555     * are started by the time booting is complete.
556     */
557    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
558
559    /**
560     * List of persistent applications that are in the process
561     * of being started.
562     */
563    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Processes that are being forcibly torn down.
567     */
568    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * List of running applications, sorted by recent usage.
572     * The first entry in the list is the least recently used.
573     */
574    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
575
576    /**
577     * Where in mLruProcesses that the processes hosting activities start.
578     */
579    int mLruProcessActivityStart = 0;
580
581    /**
582     * Where in mLruProcesses that the processes hosting services start.
583     * This is after (lower index) than mLruProcessesActivityStart.
584     */
585    int mLruProcessServiceStart = 0;
586
587    /**
588     * List of processes that should gc as soon as things are idle.
589     */
590    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
591
592    /**
593     * Processes we want to collect PSS data from.
594     */
595    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
596
597    /**
598     * Last time we requested PSS data of all processes.
599     */
600    long mLastFullPssTime = SystemClock.uptimeMillis();
601
602    /**
603     * If set, the next time we collect PSS data we should do a full collection
604     * with data from native processes and the kernel.
605     */
606    boolean mFullPssPending = false;
607
608    /**
609     * This is the process holding what we currently consider to be
610     * the "home" activity.
611     */
612    ProcessRecord mHomeProcess;
613
614    /**
615     * This is the process holding the activity the user last visited that
616     * is in a different process from the one they are currently in.
617     */
618    ProcessRecord mPreviousProcess;
619
620    /**
621     * The time at which the previous process was last visible.
622     */
623    long mPreviousProcessVisibleTime;
624
625    /**
626     * Which uses have been started, so are allowed to run code.
627     */
628    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
629
630    /**
631     * LRU list of history of current users.  Most recently current is at the end.
632     */
633    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
634
635    /**
636     * Constant array of the users that are currently started.
637     */
638    int[] mStartedUserArray = new int[] { 0 };
639
640    /**
641     * Registered observers of the user switching mechanics.
642     */
643    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
644            = new RemoteCallbackList<IUserSwitchObserver>();
645
646    /**
647     * Currently active user switch.
648     */
649    Object mCurUserSwitchCallback;
650
651    /**
652     * Packages that the user has asked to have run in screen size
653     * compatibility mode instead of filling the screen.
654     */
655    final CompatModePackages mCompatModePackages;
656
657    /**
658     * Set of IntentSenderRecord objects that are currently active.
659     */
660    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
661            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
662
663    /**
664     * Fingerprints (hashCode()) of stack traces that we've
665     * already logged DropBox entries for.  Guarded by itself.  If
666     * something (rogue user app) forces this over
667     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
668     */
669    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
670    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
671
672    /**
673     * Strict Mode background batched logging state.
674     *
675     * The string buffer is guarded by itself, and its lock is also
676     * used to determine if another batched write is already
677     * in-flight.
678     */
679    private final StringBuilder mStrictModeBuffer = new StringBuilder();
680
681    /**
682     * Keeps track of all IIntentReceivers that have been registered for
683     * broadcasts.  Hash keys are the receiver IBinder, hash value is
684     * a ReceiverList.
685     */
686    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
687            new HashMap<IBinder, ReceiverList>();
688
689    /**
690     * Resolver for broadcast intents to registered receivers.
691     * Holds BroadcastFilter (subclass of IntentFilter).
692     */
693    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
694            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
695        @Override
696        protected boolean allowFilterResult(
697                BroadcastFilter filter, List<BroadcastFilter> dest) {
698            IBinder target = filter.receiverList.receiver.asBinder();
699            for (int i=dest.size()-1; i>=0; i--) {
700                if (dest.get(i).receiverList.receiver.asBinder() == target) {
701                    return false;
702                }
703            }
704            return true;
705        }
706
707        @Override
708        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
709            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
710                    || userId == filter.owningUserId) {
711                return super.newResult(filter, match, userId);
712            }
713            return null;
714        }
715
716        @Override
717        protected BroadcastFilter[] newArray(int size) {
718            return new BroadcastFilter[size];
719        }
720
721        @Override
722        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
723            return packageName.equals(filter.packageName);
724        }
725    };
726
727    /**
728     * State of all active sticky broadcasts per user.  Keys are the action of the
729     * sticky Intent, values are an ArrayList of all broadcasted intents with
730     * that action (which should usually be one).  The SparseArray is keyed
731     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
732     * for stickies that are sent to all users.
733     */
734    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
735            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
736
737    final ActiveServices mServices;
738
739    /**
740     * Backup/restore process management
741     */
742    String mBackupAppName = null;
743    BackupRecord mBackupTarget = null;
744
745    final ProviderMap mProviderMap;
746
747    /**
748     * List of content providers who have clients waiting for them.  The
749     * application is currently being launched and the provider will be
750     * removed from this list once it is published.
751     */
752    final ArrayList<ContentProviderRecord> mLaunchingProviders
753            = new ArrayList<ContentProviderRecord>();
754
755    /**
756     * File storing persisted {@link #mGrantedUriPermissions}.
757     */
758    private final AtomicFile mGrantFile;
759
760    /** XML constants used in {@link #mGrantFile} */
761    private static final String TAG_URI_GRANTS = "uri-grants";
762    private static final String TAG_URI_GRANT = "uri-grant";
763    private static final String ATTR_USER_HANDLE = "userHandle";
764    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
765    private static final String ATTR_TARGET_USER_ID = "targetUserId";
766    private static final String ATTR_SOURCE_PKG = "sourcePkg";
767    private static final String ATTR_TARGET_PKG = "targetPkg";
768    private static final String ATTR_URI = "uri";
769    private static final String ATTR_MODE_FLAGS = "modeFlags";
770    private static final String ATTR_CREATED_TIME = "createdTime";
771    private static final String ATTR_PREFIX = "prefix";
772
773    /**
774     * Global set of specific {@link Uri} permissions that have been granted.
775     * This optimized lookup structure maps from {@link UriPermission#targetUid}
776     * to {@link UriPermission#uri} to {@link UriPermission}.
777     */
778    @GuardedBy("this")
779    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
780            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
781
782    public static class GrantUri {
783        public final int sourceUserId;
784        public final Uri uri;
785        public boolean prefix;
786
787        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
788            this.sourceUserId = sourceUserId;
789            this.uri = uri;
790            this.prefix = prefix;
791        }
792
793        @Override
794        public int hashCode() {
795            return toString().hashCode();
796        }
797
798        @Override
799        public boolean equals(Object o) {
800            if (o instanceof GrantUri) {
801                GrantUri other = (GrantUri) o;
802                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
803                        && prefix == other.prefix;
804            }
805            return false;
806        }
807
808        @Override
809        public String toString() {
810            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
811            if (prefix) result += " [prefix]";
812            return result;
813        }
814
815        public String toSafeString() {
816            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
817            if (prefix) result += " [prefix]";
818            return result;
819        }
820
821        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
822            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
823                    ContentProvider.getUriWithoutUserId(uri), false);
824        }
825    }
826
827    CoreSettingsObserver mCoreSettingsObserver;
828
829    /**
830     * Thread-local storage used to carry caller permissions over through
831     * indirect content-provider access.
832     */
833    private class Identity {
834        public int pid;
835        public int uid;
836
837        Identity(int _pid, int _uid) {
838            pid = _pid;
839            uid = _uid;
840        }
841    }
842
843    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
844
845    /**
846     * All information we have collected about the runtime performance of
847     * any user id that can impact battery performance.
848     */
849    final BatteryStatsService mBatteryStatsService;
850
851    /**
852     * Information about component usage
853     */
854    UsageStatsManagerInternal mUsageStatsService;
855
856    /**
857     * Information about and control over application operations
858     */
859    final AppOpsService mAppOpsService;
860
861    /**
862     * Save recent tasks information across reboots.
863     */
864    final TaskPersister mTaskPersister;
865
866    /**
867     * Current configuration information.  HistoryRecord objects are given
868     * a reference to this object to indicate which configuration they are
869     * currently running in, so this object must be kept immutable.
870     */
871    Configuration mConfiguration = new Configuration();
872
873    /**
874     * Current sequencing integer of the configuration, for skipping old
875     * configurations.
876     */
877    int mConfigurationSeq = 0;
878
879    /**
880     * Hardware-reported OpenGLES version.
881     */
882    final int GL_ES_VERSION;
883
884    /**
885     * List of initialization arguments to pass to all processes when binding applications to them.
886     * For example, references to the commonly used services.
887     */
888    HashMap<String, IBinder> mAppBindArgs;
889
890    /**
891     * Temporary to avoid allocations.  Protected by main lock.
892     */
893    final StringBuilder mStringBuilder = new StringBuilder(256);
894
895    /**
896     * Used to control how we initialize the service.
897     */
898    ComponentName mTopComponent;
899    String mTopAction = Intent.ACTION_MAIN;
900    String mTopData;
901    boolean mProcessesReady = false;
902    boolean mSystemReady = false;
903    boolean mBooting = false;
904    boolean mCallFinishBooting = false;
905    boolean mBootAnimationComplete = false;
906    boolean mWaitingUpdate = false;
907    boolean mDidUpdate = false;
908    boolean mOnBattery = false;
909    boolean mLaunchWarningShown = false;
910
911    Context mContext;
912
913    int mFactoryTest;
914
915    boolean mCheckedForSetup;
916
917    /**
918     * The time at which we will allow normal application switches again,
919     * after a call to {@link #stopAppSwitches()}.
920     */
921    long mAppSwitchesAllowedTime;
922
923    /**
924     * This is set to true after the first switch after mAppSwitchesAllowedTime
925     * is set; any switches after that will clear the time.
926     */
927    boolean mDidAppSwitch;
928
929    /**
930     * Last time (in realtime) at which we checked for power usage.
931     */
932    long mLastPowerCheckRealtime;
933
934    /**
935     * Last time (in uptime) at which we checked for power usage.
936     */
937    long mLastPowerCheckUptime;
938
939    /**
940     * Set while we are wanting to sleep, to prevent any
941     * activities from being started/resumed.
942     */
943    private boolean mSleeping = false;
944
945    /**
946     * Set while we are running a voice interaction.  This overrides
947     * sleeping while it is active.
948     */
949    private boolean mRunningVoice = false;
950
951    /**
952     * State of external calls telling us if the device is awake or asleep.
953     */
954    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
955
956    /**
957     * State of external call telling us if the lock screen is shown.
958     */
959    private boolean mLockScreenShown = false;
960
961    /**
962     * Set if we are shutting down the system, similar to sleeping.
963     */
964    boolean mShuttingDown = false;
965
966    /**
967     * Current sequence id for oom_adj computation traversal.
968     */
969    int mAdjSeq = 0;
970
971    /**
972     * Current sequence id for process LRU updating.
973     */
974    int mLruSeq = 0;
975
976    /**
977     * Keep track of the non-cached/empty process we last found, to help
978     * determine how to distribute cached/empty processes next time.
979     */
980    int mNumNonCachedProcs = 0;
981
982    /**
983     * Keep track of the number of cached hidden procs, to balance oom adj
984     * distribution between those and empty procs.
985     */
986    int mNumCachedHiddenProcs = 0;
987
988    /**
989     * Keep track of the number of service processes we last found, to
990     * determine on the next iteration which should be B services.
991     */
992    int mNumServiceProcs = 0;
993    int mNewNumAServiceProcs = 0;
994    int mNewNumServiceProcs = 0;
995
996    /**
997     * Allow the current computed overall memory level of the system to go down?
998     * This is set to false when we are killing processes for reasons other than
999     * memory management, so that the now smaller process list will not be taken as
1000     * an indication that memory is tighter.
1001     */
1002    boolean mAllowLowerMemLevel = false;
1003
1004    /**
1005     * The last computed memory level, for holding when we are in a state that
1006     * processes are going away for other reasons.
1007     */
1008    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1009
1010    /**
1011     * The last total number of process we have, to determine if changes actually look
1012     * like a shrinking number of process due to lower RAM.
1013     */
1014    int mLastNumProcesses;
1015
1016    /**
1017     * The uptime of the last time we performed idle maintenance.
1018     */
1019    long mLastIdleTime = SystemClock.uptimeMillis();
1020
1021    /**
1022     * Total time spent with RAM that has been added in the past since the last idle time.
1023     */
1024    long mLowRamTimeSinceLastIdle = 0;
1025
1026    /**
1027     * If RAM is currently low, when that horrible situation started.
1028     */
1029    long mLowRamStartTime = 0;
1030
1031    /**
1032     * For reporting to battery stats the current top application.
1033     */
1034    private String mCurResumedPackage = null;
1035    private int mCurResumedUid = -1;
1036
1037    /**
1038     * For reporting to battery stats the apps currently running foreground
1039     * service.  The ProcessMap is package/uid tuples; each of these contain
1040     * an array of the currently foreground processes.
1041     */
1042    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1043            = new ProcessMap<ArrayList<ProcessRecord>>();
1044
1045    /**
1046     * This is set if we had to do a delayed dexopt of an app before launching
1047     * it, to increase the ANR timeouts in that case.
1048     */
1049    boolean mDidDexOpt;
1050
1051    /**
1052     * Set if the systemServer made a call to enterSafeMode.
1053     */
1054    boolean mSafeMode;
1055
1056    String mDebugApp = null;
1057    boolean mWaitForDebugger = false;
1058    boolean mDebugTransient = false;
1059    String mOrigDebugApp = null;
1060    boolean mOrigWaitForDebugger = false;
1061    boolean mAlwaysFinishActivities = false;
1062    IActivityController mController = null;
1063    String mProfileApp = null;
1064    ProcessRecord mProfileProc = null;
1065    String mProfileFile;
1066    ParcelFileDescriptor mProfileFd;
1067    int mSamplingInterval = 0;
1068    boolean mAutoStopProfiler = false;
1069    int mProfileType = 0;
1070    String mOpenGlTraceApp = null;
1071
1072    static class ProcessChangeItem {
1073        static final int CHANGE_ACTIVITIES = 1<<0;
1074        static final int CHANGE_PROCESS_STATE = 1<<1;
1075        int changes;
1076        int uid;
1077        int pid;
1078        int processState;
1079        boolean foregroundActivities;
1080    }
1081
1082    final RemoteCallbackList<IProcessObserver> mProcessObservers
1083            = new RemoteCallbackList<IProcessObserver>();
1084    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1085
1086    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1087            = new ArrayList<ProcessChangeItem>();
1088    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1089            = new ArrayList<ProcessChangeItem>();
1090
1091    /**
1092     * Runtime CPU use collection thread.  This object's lock is used to
1093     * perform synchronization with the thread (notifying it to run).
1094     */
1095    final Thread mProcessCpuThread;
1096
1097    /**
1098     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1099     * Must acquire this object's lock when accessing it.
1100     * NOTE: this lock will be held while doing long operations (trawling
1101     * through all processes in /proc), so it should never be acquired by
1102     * any critical paths such as when holding the main activity manager lock.
1103     */
1104    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1105            MONITOR_THREAD_CPU_USAGE);
1106    final AtomicLong mLastCpuTime = new AtomicLong(0);
1107    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1108
1109    long mLastWriteTime = 0;
1110
1111    /**
1112     * Used to retain an update lock when the foreground activity is in
1113     * immersive mode.
1114     */
1115    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1116
1117    /**
1118     * Set to true after the system has finished booting.
1119     */
1120    boolean mBooted = false;
1121
1122    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1123    int mProcessLimitOverride = -1;
1124
1125    WindowManagerService mWindowManager;
1126
1127    final ActivityThread mSystemThread;
1128
1129    // Holds the current foreground user's id
1130    int mCurrentUserId = 0;
1131    // Holds the target user's id during a user switch
1132    int mTargetUserId = UserHandle.USER_NULL;
1133    // If there are multiple profiles for the current user, their ids are here
1134    // Currently only the primary user can have managed profiles
1135    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1136
1137    /**
1138     * Mapping from each known user ID to the profile group ID it is associated with.
1139     */
1140    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1141
1142    private UserManagerService mUserManager;
1143
1144    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1145        final ProcessRecord mApp;
1146        final int mPid;
1147        final IApplicationThread mAppThread;
1148
1149        AppDeathRecipient(ProcessRecord app, int pid,
1150                IApplicationThread thread) {
1151            if (localLOGV) Slog.v(
1152                TAG, "New death recipient " + this
1153                + " for thread " + thread.asBinder());
1154            mApp = app;
1155            mPid = pid;
1156            mAppThread = thread;
1157        }
1158
1159        @Override
1160        public void binderDied() {
1161            if (localLOGV) Slog.v(
1162                TAG, "Death received in " + this
1163                + " for thread " + mAppThread.asBinder());
1164            synchronized(ActivityManagerService.this) {
1165                appDiedLocked(mApp, mPid, mAppThread);
1166            }
1167        }
1168    }
1169
1170    static final int SHOW_ERROR_MSG = 1;
1171    static final int SHOW_NOT_RESPONDING_MSG = 2;
1172    static final int SHOW_FACTORY_ERROR_MSG = 3;
1173    static final int UPDATE_CONFIGURATION_MSG = 4;
1174    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1175    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1176    static final int SERVICE_TIMEOUT_MSG = 12;
1177    static final int UPDATE_TIME_ZONE = 13;
1178    static final int SHOW_UID_ERROR_MSG = 14;
1179    static final int IM_FEELING_LUCKY_MSG = 15;
1180    static final int PROC_START_TIMEOUT_MSG = 20;
1181    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1182    static final int KILL_APPLICATION_MSG = 22;
1183    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1184    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1185    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1186    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1187    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1188    static final int CLEAR_DNS_CACHE_MSG = 28;
1189    static final int UPDATE_HTTP_PROXY_MSG = 29;
1190    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1191    static final int DISPATCH_PROCESSES_CHANGED = 31;
1192    static final int DISPATCH_PROCESS_DIED = 32;
1193    static final int REPORT_MEM_USAGE_MSG = 33;
1194    static final int REPORT_USER_SWITCH_MSG = 34;
1195    static final int CONTINUE_USER_SWITCH_MSG = 35;
1196    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1197    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1198    static final int PERSIST_URI_GRANTS_MSG = 38;
1199    static final int REQUEST_ALL_PSS_MSG = 39;
1200    static final int START_PROFILES_MSG = 40;
1201    static final int UPDATE_TIME = 41;
1202    static final int SYSTEM_USER_START_MSG = 42;
1203    static final int SYSTEM_USER_CURRENT_MSG = 43;
1204    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1205    static final int FINISH_BOOTING_MSG = 45;
1206    static final int START_USER_SWITCH_MSG = 46;
1207    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1208
1209    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1210    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1211    static final int FIRST_COMPAT_MODE_MSG = 300;
1212    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1213
1214    AlertDialog mUidAlert;
1215    CompatModeDialog mCompatModeDialog;
1216    long mLastMemUsageReportTime = 0;
1217
1218    private LockToAppRequestDialog mLockToAppRequest;
1219
1220    /**
1221     * Flag whether the current user is a "monkey", i.e. whether
1222     * the UI is driven by a UI automation tool.
1223     */
1224    private boolean mUserIsMonkey;
1225
1226    /** Flag whether the device has a Recents UI */
1227    boolean mHasRecents;
1228
1229    /** The dimensions of the thumbnails in the Recents UI. */
1230    int mThumbnailWidth;
1231    int mThumbnailHeight;
1232
1233    final ServiceThread mHandlerThread;
1234    final MainHandler mHandler;
1235
1236    final class MainHandler extends Handler {
1237        public MainHandler(Looper looper) {
1238            super(looper, null, true);
1239        }
1240
1241        @Override
1242        public void handleMessage(Message msg) {
1243            switch (msg.what) {
1244            case SHOW_ERROR_MSG: {
1245                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1246                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1247                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1248                synchronized (ActivityManagerService.this) {
1249                    ProcessRecord proc = (ProcessRecord)data.get("app");
1250                    AppErrorResult res = (AppErrorResult) data.get("result");
1251                    if (proc != null && proc.crashDialog != null) {
1252                        Slog.e(TAG, "App already has crash dialog: " + proc);
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                        return;
1257                    }
1258                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1259                            >= Process.FIRST_APPLICATION_UID
1260                            && proc.pid != MY_PID);
1261                    for (int userId : mCurrentProfileIds) {
1262                        isBackground &= (proc.userId != userId);
1263                    }
1264                    if (isBackground && !showBackground) {
1265                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1266                        if (res != null) {
1267                            res.set(0);
1268                        }
1269                        return;
1270                    }
1271                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1272                        Dialog d = new AppErrorDialog(mContext,
1273                                ActivityManagerService.this, res, proc);
1274                        d.show();
1275                        proc.crashDialog = d;
1276                    } else {
1277                        // The device is asleep, so just pretend that the user
1278                        // saw a crash dialog and hit "force quit".
1279                        if (res != null) {
1280                            res.set(0);
1281                        }
1282                    }
1283                }
1284
1285                ensureBootCompleted();
1286            } break;
1287            case SHOW_NOT_RESPONDING_MSG: {
1288                synchronized (ActivityManagerService.this) {
1289                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1290                    ProcessRecord proc = (ProcessRecord)data.get("app");
1291                    if (proc != null && proc.anrDialog != null) {
1292                        Slog.e(TAG, "App already has anr dialog: " + proc);
1293                        return;
1294                    }
1295
1296                    Intent intent = new Intent("android.intent.action.ANR");
1297                    if (!mProcessesReady) {
1298                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1299                                | Intent.FLAG_RECEIVER_FOREGROUND);
1300                    }
1301                    broadcastIntentLocked(null, null, intent,
1302                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1303                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1304
1305                    if (mShowDialogs) {
1306                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1307                                mContext, proc, (ActivityRecord)data.get("activity"),
1308                                msg.arg1 != 0);
1309                        d.show();
1310                        proc.anrDialog = d;
1311                    } else {
1312                        // Just kill the app if there is no dialog to be shown.
1313                        killAppAtUsersRequest(proc, null);
1314                    }
1315                }
1316
1317                ensureBootCompleted();
1318            } break;
1319            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1320                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1321                synchronized (ActivityManagerService.this) {
1322                    ProcessRecord proc = (ProcessRecord) data.get("app");
1323                    if (proc == null) {
1324                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1325                        break;
1326                    }
1327                    if (proc.crashDialog != null) {
1328                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1329                        return;
1330                    }
1331                    AppErrorResult res = (AppErrorResult) data.get("result");
1332                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1333                        Dialog d = new StrictModeViolationDialog(mContext,
1334                                ActivityManagerService.this, res, proc);
1335                        d.show();
1336                        proc.crashDialog = d;
1337                    } else {
1338                        // The device is asleep, so just pretend that the user
1339                        // saw a crash dialog and hit "force quit".
1340                        res.set(0);
1341                    }
1342                }
1343                ensureBootCompleted();
1344            } break;
1345            case SHOW_FACTORY_ERROR_MSG: {
1346                Dialog d = new FactoryErrorDialog(
1347                    mContext, msg.getData().getCharSequence("msg"));
1348                d.show();
1349                ensureBootCompleted();
1350            } break;
1351            case UPDATE_CONFIGURATION_MSG: {
1352                final ContentResolver resolver = mContext.getContentResolver();
1353                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1354            } break;
1355            case GC_BACKGROUND_PROCESSES_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    performAppGcsIfAppropriateLocked();
1358                }
1359            } break;
1360            case WAIT_FOR_DEBUGGER_MSG: {
1361                synchronized (ActivityManagerService.this) {
1362                    ProcessRecord app = (ProcessRecord)msg.obj;
1363                    if (msg.arg1 != 0) {
1364                        if (!app.waitedForDebugger) {
1365                            Dialog d = new AppWaitingForDebuggerDialog(
1366                                    ActivityManagerService.this,
1367                                    mContext, app);
1368                            app.waitDialog = d;
1369                            app.waitedForDebugger = true;
1370                            d.show();
1371                        }
1372                    } else {
1373                        if (app.waitDialog != null) {
1374                            app.waitDialog.dismiss();
1375                            app.waitDialog = null;
1376                        }
1377                    }
1378                }
1379            } break;
1380            case SERVICE_TIMEOUT_MSG: {
1381                if (mDidDexOpt) {
1382                    mDidDexOpt = false;
1383                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1384                    nmsg.obj = msg.obj;
1385                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1386                    return;
1387                }
1388                mServices.serviceTimeout((ProcessRecord)msg.obj);
1389            } break;
1390            case UPDATE_TIME_ZONE: {
1391                synchronized (ActivityManagerService.this) {
1392                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1393                        ProcessRecord r = mLruProcesses.get(i);
1394                        if (r.thread != null) {
1395                            try {
1396                                r.thread.updateTimeZone();
1397                            } catch (RemoteException ex) {
1398                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1399                            }
1400                        }
1401                    }
1402                }
1403            } break;
1404            case CLEAR_DNS_CACHE_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1407                        ProcessRecord r = mLruProcesses.get(i);
1408                        if (r.thread != null) {
1409                            try {
1410                                r.thread.clearDnsCache();
1411                            } catch (RemoteException ex) {
1412                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1413                            }
1414                        }
1415                    }
1416                }
1417            } break;
1418            case UPDATE_HTTP_PROXY_MSG: {
1419                ProxyInfo proxy = (ProxyInfo)msg.obj;
1420                String host = "";
1421                String port = "";
1422                String exclList = "";
1423                Uri pacFileUrl = Uri.EMPTY;
1424                if (proxy != null) {
1425                    host = proxy.getHost();
1426                    port = Integer.toString(proxy.getPort());
1427                    exclList = proxy.getExclusionListAsString();
1428                    pacFileUrl = proxy.getPacFileUrl();
1429                }
1430                synchronized (ActivityManagerService.this) {
1431                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1432                        ProcessRecord r = mLruProcesses.get(i);
1433                        if (r.thread != null) {
1434                            try {
1435                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1436                            } catch (RemoteException ex) {
1437                                Slog.w(TAG, "Failed to update http proxy for: " +
1438                                        r.info.processName);
1439                            }
1440                        }
1441                    }
1442                }
1443            } break;
1444            case SHOW_UID_ERROR_MSG: {
1445                String title = "System UIDs Inconsistent";
1446                String text = "UIDs on the system are inconsistent, you need to wipe your"
1447                        + " data partition or your device will be unstable.";
1448                Log.e(TAG, title + ": " + text);
1449                if (mShowDialogs) {
1450                    // XXX This is a temporary dialog, no need to localize.
1451                    AlertDialog d = new BaseErrorDialog(mContext);
1452                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1453                    d.setCancelable(false);
1454                    d.setTitle(title);
1455                    d.setMessage(text);
1456                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1457                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1458                    mUidAlert = d;
1459                    d.show();
1460                }
1461            } break;
1462            case IM_FEELING_LUCKY_MSG: {
1463                if (mUidAlert != null) {
1464                    mUidAlert.dismiss();
1465                    mUidAlert = null;
1466                }
1467            } break;
1468            case PROC_START_TIMEOUT_MSG: {
1469                if (mDidDexOpt) {
1470                    mDidDexOpt = false;
1471                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1472                    nmsg.obj = msg.obj;
1473                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1474                    return;
1475                }
1476                ProcessRecord app = (ProcessRecord)msg.obj;
1477                synchronized (ActivityManagerService.this) {
1478                    processStartTimedOutLocked(app);
1479                }
1480            } break;
1481            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1482                synchronized (ActivityManagerService.this) {
1483                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1484                }
1485            } break;
1486            case KILL_APPLICATION_MSG: {
1487                synchronized (ActivityManagerService.this) {
1488                    int appid = msg.arg1;
1489                    boolean restart = (msg.arg2 == 1);
1490                    Bundle bundle = (Bundle)msg.obj;
1491                    String pkg = bundle.getString("pkg");
1492                    String reason = bundle.getString("reason");
1493                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1494                            false, UserHandle.USER_ALL, reason);
1495                }
1496            } break;
1497            case FINALIZE_PENDING_INTENT_MSG: {
1498                ((PendingIntentRecord)msg.obj).completeFinalize();
1499            } break;
1500            case POST_HEAVY_NOTIFICATION_MSG: {
1501                INotificationManager inm = NotificationManager.getService();
1502                if (inm == null) {
1503                    return;
1504                }
1505
1506                ActivityRecord root = (ActivityRecord)msg.obj;
1507                ProcessRecord process = root.app;
1508                if (process == null) {
1509                    return;
1510                }
1511
1512                try {
1513                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1514                    String text = mContext.getString(R.string.heavy_weight_notification,
1515                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1516                    Notification notification = new Notification();
1517                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1518                    notification.when = 0;
1519                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1520                    notification.tickerText = text;
1521                    notification.defaults = 0; // please be quiet
1522                    notification.sound = null;
1523                    notification.vibrate = null;
1524                    notification.color = mContext.getResources().getColor(
1525                            com.android.internal.R.color.system_notification_accent_color);
1526                    notification.setLatestEventInfo(context, text,
1527                            mContext.getText(R.string.heavy_weight_notification_detail),
1528                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1529                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1530                                    new UserHandle(root.userId)));
1531
1532                    try {
1533                        int[] outId = new int[1];
1534                        inm.enqueueNotificationWithTag("android", "android", null,
1535                                R.string.heavy_weight_notification,
1536                                notification, outId, root.userId);
1537                    } catch (RuntimeException e) {
1538                        Slog.w(ActivityManagerService.TAG,
1539                                "Error showing notification for heavy-weight app", e);
1540                    } catch (RemoteException e) {
1541                    }
1542                } catch (NameNotFoundException e) {
1543                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1544                }
1545            } break;
1546            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1547                INotificationManager inm = NotificationManager.getService();
1548                if (inm == null) {
1549                    return;
1550                }
1551                try {
1552                    inm.cancelNotificationWithTag("android", null,
1553                            R.string.heavy_weight_notification,  msg.arg1);
1554                } catch (RuntimeException e) {
1555                    Slog.w(ActivityManagerService.TAG,
1556                            "Error canceling notification for service", e);
1557                } catch (RemoteException e) {
1558                }
1559            } break;
1560            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1561                synchronized (ActivityManagerService.this) {
1562                    checkExcessivePowerUsageLocked(true);
1563                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1565                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1566                }
1567            } break;
1568            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1569                synchronized (ActivityManagerService.this) {
1570                    ActivityRecord ar = (ActivityRecord)msg.obj;
1571                    if (mCompatModeDialog != null) {
1572                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1573                                ar.info.applicationInfo.packageName)) {
1574                            return;
1575                        }
1576                        mCompatModeDialog.dismiss();
1577                        mCompatModeDialog = null;
1578                    }
1579                    if (ar != null && false) {
1580                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1581                                ar.packageName)) {
1582                            int mode = mCompatModePackages.computeCompatModeLocked(
1583                                    ar.info.applicationInfo);
1584                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1585                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1586                                mCompatModeDialog = new CompatModeDialog(
1587                                        ActivityManagerService.this, mContext,
1588                                        ar.info.applicationInfo);
1589                                mCompatModeDialog.show();
1590                            }
1591                        }
1592                    }
1593                }
1594                break;
1595            }
1596            case DISPATCH_PROCESSES_CHANGED: {
1597                dispatchProcessesChanged();
1598                break;
1599            }
1600            case DISPATCH_PROCESS_DIED: {
1601                final int pid = msg.arg1;
1602                final int uid = msg.arg2;
1603                dispatchProcessDied(pid, uid);
1604                break;
1605            }
1606            case REPORT_MEM_USAGE_MSG: {
1607                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1608                Thread thread = new Thread() {
1609                    @Override public void run() {
1610                        final SparseArray<ProcessMemInfo> infoMap
1611                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1612                        for (int i=0, N=memInfos.size(); i<N; i++) {
1613                            ProcessMemInfo mi = memInfos.get(i);
1614                            infoMap.put(mi.pid, mi);
1615                        }
1616                        updateCpuStatsNow();
1617                        synchronized (mProcessCpuTracker) {
1618                            final int N = mProcessCpuTracker.countStats();
1619                            for (int i=0; i<N; i++) {
1620                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1621                                if (st.vsize > 0) {
1622                                    long pss = Debug.getPss(st.pid, null);
1623                                    if (pss > 0) {
1624                                        if (infoMap.indexOfKey(st.pid) < 0) {
1625                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1626                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1627                                            mi.pss = pss;
1628                                            memInfos.add(mi);
1629                                        }
1630                                    }
1631                                }
1632                            }
1633                        }
1634
1635                        long totalPss = 0;
1636                        for (int i=0, N=memInfos.size(); i<N; i++) {
1637                            ProcessMemInfo mi = memInfos.get(i);
1638                            if (mi.pss == 0) {
1639                                mi.pss = Debug.getPss(mi.pid, null);
1640                            }
1641                            totalPss += mi.pss;
1642                        }
1643                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1644                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1645                                if (lhs.oomAdj != rhs.oomAdj) {
1646                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1647                                }
1648                                if (lhs.pss != rhs.pss) {
1649                                    return lhs.pss < rhs.pss ? 1 : -1;
1650                                }
1651                                return 0;
1652                            }
1653                        });
1654
1655                        StringBuilder tag = new StringBuilder(128);
1656                        StringBuilder stack = new StringBuilder(128);
1657                        tag.append("Low on memory -- ");
1658                        appendMemBucket(tag, totalPss, "total", false);
1659                        appendMemBucket(stack, totalPss, "total", true);
1660
1661                        StringBuilder logBuilder = new StringBuilder(1024);
1662                        logBuilder.append("Low on memory:\n");
1663
1664                        boolean firstLine = true;
1665                        int lastOomAdj = Integer.MIN_VALUE;
1666                        for (int i=0, N=memInfos.size(); i<N; i++) {
1667                            ProcessMemInfo mi = memInfos.get(i);
1668
1669                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1670                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1671                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1672                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1673                                if (lastOomAdj != mi.oomAdj) {
1674                                    lastOomAdj = mi.oomAdj;
1675                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1676                                        tag.append(" / ");
1677                                    }
1678                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1679                                        if (firstLine) {
1680                                            stack.append(":");
1681                                            firstLine = false;
1682                                        }
1683                                        stack.append("\n\t at ");
1684                                    } else {
1685                                        stack.append("$");
1686                                    }
1687                                } else {
1688                                    tag.append(" ");
1689                                    stack.append("$");
1690                                }
1691                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1692                                    appendMemBucket(tag, mi.pss, mi.name, false);
1693                                }
1694                                appendMemBucket(stack, mi.pss, mi.name, true);
1695                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1696                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1697                                    stack.append("(");
1698                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1699                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1700                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1701                                            stack.append(":");
1702                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1703                                        }
1704                                    }
1705                                    stack.append(")");
1706                                }
1707                            }
1708
1709                            logBuilder.append("  ");
1710                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1711                            logBuilder.append(' ');
1712                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1713                            logBuilder.append(' ');
1714                            ProcessList.appendRamKb(logBuilder, mi.pss);
1715                            logBuilder.append(" kB: ");
1716                            logBuilder.append(mi.name);
1717                            logBuilder.append(" (");
1718                            logBuilder.append(mi.pid);
1719                            logBuilder.append(") ");
1720                            logBuilder.append(mi.adjType);
1721                            logBuilder.append('\n');
1722                            if (mi.adjReason != null) {
1723                                logBuilder.append("                      ");
1724                                logBuilder.append(mi.adjReason);
1725                                logBuilder.append('\n');
1726                            }
1727                        }
1728
1729                        logBuilder.append("           ");
1730                        ProcessList.appendRamKb(logBuilder, totalPss);
1731                        logBuilder.append(" kB: TOTAL\n");
1732
1733                        long[] infos = new long[Debug.MEMINFO_COUNT];
1734                        Debug.getMemInfo(infos);
1735                        logBuilder.append("  MemInfo: ");
1736                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1737                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1738                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1739                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1740                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1741                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1742                            logBuilder.append("  ZRAM: ");
1743                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1744                            logBuilder.append(" kB RAM, ");
1745                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1746                            logBuilder.append(" kB swap total, ");
1747                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1748                            logBuilder.append(" kB swap free\n");
1749                        }
1750                        Slog.i(TAG, logBuilder.toString());
1751
1752                        StringBuilder dropBuilder = new StringBuilder(1024);
1753                        /*
1754                        StringWriter oomSw = new StringWriter();
1755                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1756                        StringWriter catSw = new StringWriter();
1757                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1758                        String[] emptyArgs = new String[] { };
1759                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1760                        oomPw.flush();
1761                        String oomString = oomSw.toString();
1762                        */
1763                        dropBuilder.append(stack);
1764                        dropBuilder.append('\n');
1765                        dropBuilder.append('\n');
1766                        dropBuilder.append(logBuilder);
1767                        dropBuilder.append('\n');
1768                        /*
1769                        dropBuilder.append(oomString);
1770                        dropBuilder.append('\n');
1771                        */
1772                        StringWriter catSw = new StringWriter();
1773                        synchronized (ActivityManagerService.this) {
1774                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1775                            String[] emptyArgs = new String[] { };
1776                            catPw.println();
1777                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1778                            catPw.println();
1779                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1780                                    false, false, null);
1781                            catPw.println();
1782                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1783                            catPw.flush();
1784                        }
1785                        dropBuilder.append(catSw.toString());
1786                        addErrorToDropBox("lowmem", null, "system_server", null,
1787                                null, tag.toString(), dropBuilder.toString(), null, null);
1788                        //Slog.i(TAG, "Sent to dropbox:");
1789                        //Slog.i(TAG, dropBuilder.toString());
1790                        synchronized (ActivityManagerService.this) {
1791                            long now = SystemClock.uptimeMillis();
1792                            if (mLastMemUsageReportTime < now) {
1793                                mLastMemUsageReportTime = now;
1794                            }
1795                        }
1796                    }
1797                };
1798                thread.start();
1799                break;
1800            }
1801            case START_USER_SWITCH_MSG: {
1802                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1803                break;
1804            }
1805            case REPORT_USER_SWITCH_MSG: {
1806                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1807                break;
1808            }
1809            case CONTINUE_USER_SWITCH_MSG: {
1810                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1811                break;
1812            }
1813            case USER_SWITCH_TIMEOUT_MSG: {
1814                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1815                break;
1816            }
1817            case IMMERSIVE_MODE_LOCK_MSG: {
1818                final boolean nextState = (msg.arg1 != 0);
1819                if (mUpdateLock.isHeld() != nextState) {
1820                    if (DEBUG_IMMERSIVE) {
1821                        final ActivityRecord r = (ActivityRecord) msg.obj;
1822                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1823                    }
1824                    if (nextState) {
1825                        mUpdateLock.acquire();
1826                    } else {
1827                        mUpdateLock.release();
1828                    }
1829                }
1830                break;
1831            }
1832            case PERSIST_URI_GRANTS_MSG: {
1833                writeGrantedUriPermissions();
1834                break;
1835            }
1836            case REQUEST_ALL_PSS_MSG: {
1837                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1838                break;
1839            }
1840            case START_PROFILES_MSG: {
1841                synchronized (ActivityManagerService.this) {
1842                    startProfilesLocked();
1843                }
1844                break;
1845            }
1846            case UPDATE_TIME: {
1847                synchronized (ActivityManagerService.this) {
1848                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1849                        ProcessRecord r = mLruProcesses.get(i);
1850                        if (r.thread != null) {
1851                            try {
1852                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1853                            } catch (RemoteException ex) {
1854                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1855                            }
1856                        }
1857                    }
1858                }
1859                break;
1860            }
1861            case SYSTEM_USER_START_MSG: {
1862                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1863                        Integer.toString(msg.arg1), msg.arg1);
1864                mSystemServiceManager.startUser(msg.arg1);
1865                break;
1866            }
1867            case SYSTEM_USER_CURRENT_MSG: {
1868                mBatteryStatsService.noteEvent(
1869                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1870                        Integer.toString(msg.arg2), msg.arg2);
1871                mBatteryStatsService.noteEvent(
1872                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1873                        Integer.toString(msg.arg1), msg.arg1);
1874                mSystemServiceManager.switchUser(msg.arg1);
1875                mLockToAppRequest.clearPrompt();
1876                break;
1877            }
1878            case ENTER_ANIMATION_COMPLETE_MSG: {
1879                synchronized (ActivityManagerService.this) {
1880                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1881                    if (r != null && r.app != null && r.app.thread != null) {
1882                        try {
1883                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1884                        } catch (RemoteException e) {
1885                        }
1886                    }
1887                }
1888                break;
1889            }
1890            case FINISH_BOOTING_MSG: {
1891                if (msg.arg1 != 0) {
1892                    finishBooting();
1893                }
1894                if (msg.arg2 != 0) {
1895                    enableScreenAfterBoot();
1896                }
1897                break;
1898            }
1899            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1900                try {
1901                    Locale l = (Locale) msg.obj;
1902                    IBinder service = ServiceManager.getService("mount");
1903                    IMountService mountService = IMountService.Stub.asInterface(service);
1904                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1905                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1906                } catch (RemoteException e) {
1907                    Log.e(TAG, "Error storing locale for decryption UI", e);
1908                }
1909                break;
1910            }
1911            }
1912        }
1913    };
1914
1915    static final int COLLECT_PSS_BG_MSG = 1;
1916
1917    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1918        @Override
1919        public void handleMessage(Message msg) {
1920            switch (msg.what) {
1921            case COLLECT_PSS_BG_MSG: {
1922                long start = SystemClock.uptimeMillis();
1923                MemInfoReader memInfo = null;
1924                synchronized (ActivityManagerService.this) {
1925                    if (mFullPssPending) {
1926                        mFullPssPending = false;
1927                        memInfo = new MemInfoReader();
1928                    }
1929                }
1930                if (memInfo != null) {
1931                    updateCpuStatsNow();
1932                    long nativeTotalPss = 0;
1933                    synchronized (mProcessCpuTracker) {
1934                        final int N = mProcessCpuTracker.countStats();
1935                        for (int j=0; j<N; j++) {
1936                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1937                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1938                                // This is definitely an application process; skip it.
1939                                continue;
1940                            }
1941                            synchronized (mPidsSelfLocked) {
1942                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1943                                    // This is one of our own processes; skip it.
1944                                    continue;
1945                                }
1946                            }
1947                            nativeTotalPss += Debug.getPss(st.pid, null);
1948                        }
1949                    }
1950                    memInfo.readMemInfo();
1951                    synchronized (ActivityManagerService.this) {
1952                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1953                                + (SystemClock.uptimeMillis()-start) + "ms");
1954                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1955                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1956                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1957                                        +memInfo.getSlabSizeKb(),
1958                                nativeTotalPss);
1959                    }
1960                }
1961
1962                int i=0, num=0;
1963                long[] tmp = new long[1];
1964                do {
1965                    ProcessRecord proc;
1966                    int procState;
1967                    int pid;
1968                    synchronized (ActivityManagerService.this) {
1969                        if (i >= mPendingPssProcesses.size()) {
1970                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1971                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1972                            mPendingPssProcesses.clear();
1973                            return;
1974                        }
1975                        proc = mPendingPssProcesses.get(i);
1976                        procState = proc.pssProcState;
1977                        if (proc.thread != null && procState == proc.setProcState) {
1978                            pid = proc.pid;
1979                        } else {
1980                            proc = null;
1981                            pid = 0;
1982                        }
1983                        i++;
1984                    }
1985                    if (proc != null) {
1986                        long pss = Debug.getPss(pid, tmp);
1987                        synchronized (ActivityManagerService.this) {
1988                            if (proc.thread != null && proc.setProcState == procState
1989                                    && proc.pid == pid) {
1990                                num++;
1991                                proc.lastPssTime = SystemClock.uptimeMillis();
1992                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1993                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1994                                        + ": " + pss + " lastPss=" + proc.lastPss
1995                                        + " state=" + ProcessList.makeProcStateString(procState));
1996                                if (proc.initialIdlePss == 0) {
1997                                    proc.initialIdlePss = pss;
1998                                }
1999                                proc.lastPss = pss;
2000                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2001                                    proc.lastCachedPss = pss;
2002                                }
2003                            }
2004                        }
2005                    }
2006                } while (true);
2007            }
2008            }
2009        }
2010    };
2011
2012    /**
2013     * Monitor for package changes and update our internal state.
2014     */
2015    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2016        @Override
2017        public void onPackageRemoved(String packageName, int uid) {
2018            // Remove all tasks with activities in the specified package from the list of recent tasks
2019            final int eventUserId = getChangingUserId();
2020            synchronized (ActivityManagerService.this) {
2021                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2022                    TaskRecord tr = mRecentTasks.get(i);
2023                    if (tr.userId != eventUserId) continue;
2024
2025                    ComponentName cn = tr.intent.getComponent();
2026                    if (cn != null && cn.getPackageName().equals(packageName)) {
2027                        // If the package name matches, remove the task and kill the process
2028                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2029                    }
2030                }
2031            }
2032        }
2033
2034        @Override
2035        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2036            onPackageModified(packageName);
2037            return true;
2038        }
2039
2040        @Override
2041        public void onPackageModified(String packageName) {
2042            final int eventUserId = getChangingUserId();
2043            final IPackageManager pm = AppGlobals.getPackageManager();
2044            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2045                    new ArrayList<Pair<Intent, Integer>>();
2046            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2047            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2048            // Copy the list of recent tasks so that we don't hold onto the lock on
2049            // ActivityManagerService for long periods while checking if components exist.
2050            synchronized (ActivityManagerService.this) {
2051                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2052                    TaskRecord tr = mRecentTasks.get(i);
2053                    if (tr.userId != eventUserId) continue;
2054
2055                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2056                }
2057            }
2058            // Check the recent tasks and filter out all tasks with components that no longer exist.
2059            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2060                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2061                ComponentName cn = p.first.getComponent();
2062                if (cn != null && cn.getPackageName().equals(packageName)) {
2063                    if (componentsKnownToExist.contains(cn)) {
2064                        // If we know that the component still exists in the package, then skip
2065                        continue;
2066                    }
2067                    try {
2068                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2069                        if (info != null) {
2070                            componentsKnownToExist.add(cn);
2071                        } else {
2072                            tasksToRemove.add(p.second);
2073                        }
2074                    } catch (RemoteException e) {
2075                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2076                    }
2077                }
2078            }
2079            // Prune all the tasks with removed components from the list of recent tasks
2080            synchronized (ActivityManagerService.this) {
2081                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2082                    // Remove the task but don't kill the process (since other components in that
2083                    // package may still be running and in the background)
2084                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2085                }
2086            }
2087        }
2088
2089        @Override
2090        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2091            // Force stop the specified packages
2092            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2093            if (packages != null) {
2094                for (String pkg : packages) {
2095                    synchronized (ActivityManagerService.this) {
2096                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2097                                userId, "finished booting")) {
2098                            return true;
2099                        }
2100                    }
2101                }
2102            }
2103            return false;
2104        }
2105    };
2106
2107    public void setSystemProcess() {
2108        try {
2109            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2110            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2111            ServiceManager.addService("meminfo", new MemBinder(this));
2112            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2113            ServiceManager.addService("dbinfo", new DbBinder(this));
2114            if (MONITOR_CPU_USAGE) {
2115                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2116            }
2117            ServiceManager.addService("permission", new PermissionController(this));
2118
2119            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2120                    "android", STOCK_PM_FLAGS);
2121            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2122
2123            synchronized (this) {
2124                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2125                app.persistent = true;
2126                app.pid = MY_PID;
2127                app.maxAdj = ProcessList.SYSTEM_ADJ;
2128                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2129                mProcessNames.put(app.processName, app.uid, app);
2130                synchronized (mPidsSelfLocked) {
2131                    mPidsSelfLocked.put(app.pid, app);
2132                }
2133                updateLruProcessLocked(app, false, null);
2134                updateOomAdjLocked();
2135            }
2136        } catch (PackageManager.NameNotFoundException e) {
2137            throw new RuntimeException(
2138                    "Unable to find android system package", e);
2139        }
2140    }
2141
2142    public void setWindowManager(WindowManagerService wm) {
2143        mWindowManager = wm;
2144        mStackSupervisor.setWindowManager(wm);
2145    }
2146
2147    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2148        mUsageStatsService = usageStatsManager;
2149    }
2150
2151    public void startObservingNativeCrashes() {
2152        final NativeCrashListener ncl = new NativeCrashListener(this);
2153        ncl.start();
2154    }
2155
2156    public IAppOpsService getAppOpsService() {
2157        return mAppOpsService;
2158    }
2159
2160    static class MemBinder extends Binder {
2161        ActivityManagerService mActivityManagerService;
2162        MemBinder(ActivityManagerService activityManagerService) {
2163            mActivityManagerService = activityManagerService;
2164        }
2165
2166        @Override
2167        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2168            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2169                    != PackageManager.PERMISSION_GRANTED) {
2170                pw.println("Permission Denial: can't dump meminfo from from pid="
2171                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2172                        + " without permission " + android.Manifest.permission.DUMP);
2173                return;
2174            }
2175
2176            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2177        }
2178    }
2179
2180    static class GraphicsBinder extends Binder {
2181        ActivityManagerService mActivityManagerService;
2182        GraphicsBinder(ActivityManagerService activityManagerService) {
2183            mActivityManagerService = activityManagerService;
2184        }
2185
2186        @Override
2187        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2188            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2189                    != PackageManager.PERMISSION_GRANTED) {
2190                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2191                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2192                        + " without permission " + android.Manifest.permission.DUMP);
2193                return;
2194            }
2195
2196            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2197        }
2198    }
2199
2200    static class DbBinder extends Binder {
2201        ActivityManagerService mActivityManagerService;
2202        DbBinder(ActivityManagerService activityManagerService) {
2203            mActivityManagerService = activityManagerService;
2204        }
2205
2206        @Override
2207        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2208            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2209                    != PackageManager.PERMISSION_GRANTED) {
2210                pw.println("Permission Denial: can't dump dbinfo from from pid="
2211                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2212                        + " without permission " + android.Manifest.permission.DUMP);
2213                return;
2214            }
2215
2216            mActivityManagerService.dumpDbInfo(fd, pw, args);
2217        }
2218    }
2219
2220    static class CpuBinder extends Binder {
2221        ActivityManagerService mActivityManagerService;
2222        CpuBinder(ActivityManagerService activityManagerService) {
2223            mActivityManagerService = activityManagerService;
2224        }
2225
2226        @Override
2227        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2228            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2229                    != PackageManager.PERMISSION_GRANTED) {
2230                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2231                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2232                        + " without permission " + android.Manifest.permission.DUMP);
2233                return;
2234            }
2235
2236            synchronized (mActivityManagerService.mProcessCpuTracker) {
2237                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2238                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2239                        SystemClock.uptimeMillis()));
2240            }
2241        }
2242    }
2243
2244    public static final class Lifecycle extends SystemService {
2245        private final ActivityManagerService mService;
2246
2247        public Lifecycle(Context context) {
2248            super(context);
2249            mService = new ActivityManagerService(context);
2250        }
2251
2252        @Override
2253        public void onStart() {
2254            mService.start();
2255        }
2256
2257        public ActivityManagerService getService() {
2258            return mService;
2259        }
2260    }
2261
2262    // Note: This method is invoked on the main thread but may need to attach various
2263    // handlers to other threads.  So take care to be explicit about the looper.
2264    public ActivityManagerService(Context systemContext) {
2265        mContext = systemContext;
2266        mFactoryTest = FactoryTest.getMode();
2267        mSystemThread = ActivityThread.currentActivityThread();
2268
2269        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2270
2271        mHandlerThread = new ServiceThread(TAG,
2272                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2273        mHandlerThread.start();
2274        mHandler = new MainHandler(mHandlerThread.getLooper());
2275
2276        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2277                "foreground", BROADCAST_FG_TIMEOUT, false);
2278        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2279                "background", BROADCAST_BG_TIMEOUT, true);
2280        mBroadcastQueues[0] = mFgBroadcastQueue;
2281        mBroadcastQueues[1] = mBgBroadcastQueue;
2282
2283        mServices = new ActiveServices(this);
2284        mProviderMap = new ProviderMap(this);
2285
2286        // TODO: Move creation of battery stats service outside of activity manager service.
2287        File dataDir = Environment.getDataDirectory();
2288        File systemDir = new File(dataDir, "system");
2289        systemDir.mkdirs();
2290        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2291        mBatteryStatsService.getActiveStatistics().readLocked();
2292        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2293        mOnBattery = DEBUG_POWER ? true
2294                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2295        mBatteryStatsService.getActiveStatistics().setCallback(this);
2296
2297        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2298
2299        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2300
2301        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2302
2303        // User 0 is the first and only user that runs at boot.
2304        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2305        mUserLru.add(Integer.valueOf(0));
2306        updateStartedUserArrayLocked();
2307
2308        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2309            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2310
2311        mConfiguration.setToDefaults();
2312        mConfiguration.setLocale(Locale.getDefault());
2313
2314        mConfigurationSeq = mConfiguration.seq = 1;
2315        mProcessCpuTracker.init();
2316
2317        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2318        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2319        mStackSupervisor = new ActivityStackSupervisor(this);
2320        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2321
2322        mProcessCpuThread = new Thread("CpuTracker") {
2323            @Override
2324            public void run() {
2325                while (true) {
2326                    try {
2327                        try {
2328                            synchronized(this) {
2329                                final long now = SystemClock.uptimeMillis();
2330                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2331                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2332                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2333                                //        + ", write delay=" + nextWriteDelay);
2334                                if (nextWriteDelay < nextCpuDelay) {
2335                                    nextCpuDelay = nextWriteDelay;
2336                                }
2337                                if (nextCpuDelay > 0) {
2338                                    mProcessCpuMutexFree.set(true);
2339                                    this.wait(nextCpuDelay);
2340                                }
2341                            }
2342                        } catch (InterruptedException e) {
2343                        }
2344                        updateCpuStatsNow();
2345                    } catch (Exception e) {
2346                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2347                    }
2348                }
2349            }
2350        };
2351
2352        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2353
2354        Watchdog.getInstance().addMonitor(this);
2355        Watchdog.getInstance().addThread(mHandler);
2356    }
2357
2358    public void setSystemServiceManager(SystemServiceManager mgr) {
2359        mSystemServiceManager = mgr;
2360    }
2361
2362    private void start() {
2363        Process.removeAllProcessGroups();
2364        mProcessCpuThread.start();
2365
2366        mBatteryStatsService.publish(mContext);
2367        mAppOpsService.publish(mContext);
2368        Slog.d("AppOps", "AppOpsService published");
2369        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2370    }
2371
2372    public void initPowerManagement() {
2373        mStackSupervisor.initPowerManagement();
2374        mBatteryStatsService.initPowerManagement();
2375    }
2376
2377    @Override
2378    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2379            throws RemoteException {
2380        if (code == SYSPROPS_TRANSACTION) {
2381            // We need to tell all apps about the system property change.
2382            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2383            synchronized(this) {
2384                final int NP = mProcessNames.getMap().size();
2385                for (int ip=0; ip<NP; ip++) {
2386                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2387                    final int NA = apps.size();
2388                    for (int ia=0; ia<NA; ia++) {
2389                        ProcessRecord app = apps.valueAt(ia);
2390                        if (app.thread != null) {
2391                            procs.add(app.thread.asBinder());
2392                        }
2393                    }
2394                }
2395            }
2396
2397            int N = procs.size();
2398            for (int i=0; i<N; i++) {
2399                Parcel data2 = Parcel.obtain();
2400                try {
2401                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2402                } catch (RemoteException e) {
2403                }
2404                data2.recycle();
2405            }
2406        }
2407        try {
2408            return super.onTransact(code, data, reply, flags);
2409        } catch (RuntimeException e) {
2410            // The activity manager only throws security exceptions, so let's
2411            // log all others.
2412            if (!(e instanceof SecurityException)) {
2413                Slog.wtf(TAG, "Activity Manager Crash", e);
2414            }
2415            throw e;
2416        }
2417    }
2418
2419    void updateCpuStats() {
2420        final long now = SystemClock.uptimeMillis();
2421        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2422            return;
2423        }
2424        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2425            synchronized (mProcessCpuThread) {
2426                mProcessCpuThread.notify();
2427            }
2428        }
2429    }
2430
2431    void updateCpuStatsNow() {
2432        synchronized (mProcessCpuTracker) {
2433            mProcessCpuMutexFree.set(false);
2434            final long now = SystemClock.uptimeMillis();
2435            boolean haveNewCpuStats = false;
2436
2437            if (MONITOR_CPU_USAGE &&
2438                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2439                mLastCpuTime.set(now);
2440                haveNewCpuStats = true;
2441                mProcessCpuTracker.update();
2442                //Slog.i(TAG, mProcessCpu.printCurrentState());
2443                //Slog.i(TAG, "Total CPU usage: "
2444                //        + mProcessCpu.getTotalCpuPercent() + "%");
2445
2446                // Slog the cpu usage if the property is set.
2447                if ("true".equals(SystemProperties.get("events.cpu"))) {
2448                    int user = mProcessCpuTracker.getLastUserTime();
2449                    int system = mProcessCpuTracker.getLastSystemTime();
2450                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2451                    int irq = mProcessCpuTracker.getLastIrqTime();
2452                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2453                    int idle = mProcessCpuTracker.getLastIdleTime();
2454
2455                    int total = user + system + iowait + irq + softIrq + idle;
2456                    if (total == 0) total = 1;
2457
2458                    EventLog.writeEvent(EventLogTags.CPU,
2459                            ((user+system+iowait+irq+softIrq) * 100) / total,
2460                            (user * 100) / total,
2461                            (system * 100) / total,
2462                            (iowait * 100) / total,
2463                            (irq * 100) / total,
2464                            (softIrq * 100) / total);
2465                }
2466            }
2467
2468            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2469            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2470            synchronized(bstats) {
2471                synchronized(mPidsSelfLocked) {
2472                    if (haveNewCpuStats) {
2473                        if (mOnBattery) {
2474                            int perc = bstats.startAddingCpuLocked();
2475                            int totalUTime = 0;
2476                            int totalSTime = 0;
2477                            final int N = mProcessCpuTracker.countStats();
2478                            for (int i=0; i<N; i++) {
2479                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2480                                if (!st.working) {
2481                                    continue;
2482                                }
2483                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2484                                int otherUTime = (st.rel_utime*perc)/100;
2485                                int otherSTime = (st.rel_stime*perc)/100;
2486                                totalUTime += otherUTime;
2487                                totalSTime += otherSTime;
2488                                if (pr != null) {
2489                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2490                                    if (ps == null || !ps.isActive()) {
2491                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2492                                                pr.info.uid, pr.processName);
2493                                    }
2494                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2495                                            st.rel_stime-otherSTime);
2496                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2497                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2498                                } else {
2499                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2500                                    if (ps == null || !ps.isActive()) {
2501                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2502                                                bstats.mapUid(st.uid), st.name);
2503                                    }
2504                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2505                                            st.rel_stime-otherSTime);
2506                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2507                                }
2508                            }
2509                            bstats.finishAddingCpuLocked(perc, totalUTime,
2510                                    totalSTime, cpuSpeedTimes);
2511                        }
2512                    }
2513                }
2514
2515                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2516                    mLastWriteTime = now;
2517                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2518                }
2519            }
2520        }
2521    }
2522
2523    @Override
2524    public void batteryNeedsCpuUpdate() {
2525        updateCpuStatsNow();
2526    }
2527
2528    @Override
2529    public void batteryPowerChanged(boolean onBattery) {
2530        // When plugging in, update the CPU stats first before changing
2531        // the plug state.
2532        updateCpuStatsNow();
2533        synchronized (this) {
2534            synchronized(mPidsSelfLocked) {
2535                mOnBattery = DEBUG_POWER ? true : onBattery;
2536            }
2537        }
2538    }
2539
2540    /**
2541     * Initialize the application bind args. These are passed to each
2542     * process when the bindApplication() IPC is sent to the process. They're
2543     * lazily setup to make sure the services are running when they're asked for.
2544     */
2545    private HashMap<String, IBinder> getCommonServicesLocked() {
2546        if (mAppBindArgs == null) {
2547            mAppBindArgs = new HashMap<String, IBinder>();
2548
2549            // Setup the application init args
2550            mAppBindArgs.put("package", ServiceManager.getService("package"));
2551            mAppBindArgs.put("window", ServiceManager.getService("window"));
2552            mAppBindArgs.put(Context.ALARM_SERVICE,
2553                    ServiceManager.getService(Context.ALARM_SERVICE));
2554        }
2555        return mAppBindArgs;
2556    }
2557
2558    final void setFocusedActivityLocked(ActivityRecord r) {
2559        if (mFocusedActivity != r) {
2560            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2561            mFocusedActivity = r;
2562            if (r.task != null && r.task.voiceInteractor != null) {
2563                startRunningVoiceLocked();
2564            } else {
2565                finishRunningVoiceLocked();
2566            }
2567            mStackSupervisor.setFocusedStack(r);
2568            if (r != null) {
2569                mWindowManager.setFocusedApp(r.appToken, true);
2570            }
2571            applyUpdateLockStateLocked(r);
2572        }
2573    }
2574
2575    final void clearFocusedActivity(ActivityRecord r) {
2576        if (mFocusedActivity == r) {
2577            mFocusedActivity = null;
2578        }
2579    }
2580
2581    @Override
2582    public void setFocusedStack(int stackId) {
2583        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2584        synchronized (ActivityManagerService.this) {
2585            ActivityStack stack = mStackSupervisor.getStack(stackId);
2586            if (stack != null) {
2587                ActivityRecord r = stack.topRunningActivityLocked(null);
2588                if (r != null) {
2589                    setFocusedActivityLocked(r);
2590                }
2591            }
2592        }
2593    }
2594
2595    @Override
2596    public void notifyActivityDrawn(IBinder token) {
2597        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2598        synchronized (this) {
2599            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2600            if (r != null) {
2601                r.task.stack.notifyActivityDrawnLocked(r);
2602            }
2603        }
2604    }
2605
2606    final void applyUpdateLockStateLocked(ActivityRecord r) {
2607        // Modifications to the UpdateLock state are done on our handler, outside
2608        // the activity manager's locks.  The new state is determined based on the
2609        // state *now* of the relevant activity record.  The object is passed to
2610        // the handler solely for logging detail, not to be consulted/modified.
2611        final boolean nextState = r != null && r.immersive;
2612        mHandler.sendMessage(
2613                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2614    }
2615
2616    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2617        Message msg = Message.obtain();
2618        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2619        msg.obj = r.task.askedCompatMode ? null : r;
2620        mHandler.sendMessage(msg);
2621    }
2622
2623    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2624            String what, Object obj, ProcessRecord srcApp) {
2625        app.lastActivityTime = now;
2626
2627        if (app.activities.size() > 0) {
2628            // Don't want to touch dependent processes that are hosting activities.
2629            return index;
2630        }
2631
2632        int lrui = mLruProcesses.lastIndexOf(app);
2633        if (lrui < 0) {
2634            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2635                    + what + " " + obj + " from " + srcApp);
2636            return index;
2637        }
2638
2639        if (lrui >= index) {
2640            // Don't want to cause this to move dependent processes *back* in the
2641            // list as if they were less frequently used.
2642            return index;
2643        }
2644
2645        if (lrui >= mLruProcessActivityStart) {
2646            // Don't want to touch dependent processes that are hosting activities.
2647            return index;
2648        }
2649
2650        mLruProcesses.remove(lrui);
2651        if (index > 0) {
2652            index--;
2653        }
2654        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2655                + " in LRU list: " + app);
2656        mLruProcesses.add(index, app);
2657        return index;
2658    }
2659
2660    final void removeLruProcessLocked(ProcessRecord app) {
2661        int lrui = mLruProcesses.lastIndexOf(app);
2662        if (lrui >= 0) {
2663            if (!app.killed) {
2664                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2665                Process.killProcessQuiet(app.pid);
2666                Process.killProcessGroup(app.info.uid, app.pid);
2667            }
2668            if (lrui <= mLruProcessActivityStart) {
2669                mLruProcessActivityStart--;
2670            }
2671            if (lrui <= mLruProcessServiceStart) {
2672                mLruProcessServiceStart--;
2673            }
2674            mLruProcesses.remove(lrui);
2675        }
2676    }
2677
2678    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2679            ProcessRecord client) {
2680        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2681                || app.treatLikeActivity;
2682        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2683        if (!activityChange && hasActivity) {
2684            // The process has activities, so we are only allowing activity-based adjustments
2685            // to move it.  It should be kept in the front of the list with other
2686            // processes that have activities, and we don't want those to change their
2687            // order except due to activity operations.
2688            return;
2689        }
2690
2691        mLruSeq++;
2692        final long now = SystemClock.uptimeMillis();
2693        app.lastActivityTime = now;
2694
2695        // First a quick reject: if the app is already at the position we will
2696        // put it, then there is nothing to do.
2697        if (hasActivity) {
2698            final int N = mLruProcesses.size();
2699            if (N > 0 && mLruProcesses.get(N-1) == app) {
2700                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2701                return;
2702            }
2703        } else {
2704            if (mLruProcessServiceStart > 0
2705                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2706                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2707                return;
2708            }
2709        }
2710
2711        int lrui = mLruProcesses.lastIndexOf(app);
2712
2713        if (app.persistent && lrui >= 0) {
2714            // We don't care about the position of persistent processes, as long as
2715            // they are in the list.
2716            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2717            return;
2718        }
2719
2720        /* In progress: compute new position first, so we can avoid doing work
2721           if the process is not actually going to move.  Not yet working.
2722        int addIndex;
2723        int nextIndex;
2724        boolean inActivity = false, inService = false;
2725        if (hasActivity) {
2726            // Process has activities, put it at the very tipsy-top.
2727            addIndex = mLruProcesses.size();
2728            nextIndex = mLruProcessServiceStart;
2729            inActivity = true;
2730        } else if (hasService) {
2731            // Process has services, put it at the top of the service list.
2732            addIndex = mLruProcessActivityStart;
2733            nextIndex = mLruProcessServiceStart;
2734            inActivity = true;
2735            inService = true;
2736        } else  {
2737            // Process not otherwise of interest, it goes to the top of the non-service area.
2738            addIndex = mLruProcessServiceStart;
2739            if (client != null) {
2740                int clientIndex = mLruProcesses.lastIndexOf(client);
2741                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2742                        + app);
2743                if (clientIndex >= 0 && addIndex > clientIndex) {
2744                    addIndex = clientIndex;
2745                }
2746            }
2747            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2748        }
2749
2750        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2751                + mLruProcessActivityStart + "): " + app);
2752        */
2753
2754        if (lrui >= 0) {
2755            if (lrui < mLruProcessActivityStart) {
2756                mLruProcessActivityStart--;
2757            }
2758            if (lrui < mLruProcessServiceStart) {
2759                mLruProcessServiceStart--;
2760            }
2761            /*
2762            if (addIndex > lrui) {
2763                addIndex--;
2764            }
2765            if (nextIndex > lrui) {
2766                nextIndex--;
2767            }
2768            */
2769            mLruProcesses.remove(lrui);
2770        }
2771
2772        /*
2773        mLruProcesses.add(addIndex, app);
2774        if (inActivity) {
2775            mLruProcessActivityStart++;
2776        }
2777        if (inService) {
2778            mLruProcessActivityStart++;
2779        }
2780        */
2781
2782        int nextIndex;
2783        if (hasActivity) {
2784            final int N = mLruProcesses.size();
2785            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2786                // Process doesn't have activities, but has clients with
2787                // activities...  move it up, but one below the top (the top
2788                // should always have a real activity).
2789                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2790                mLruProcesses.add(N-1, app);
2791                // To keep it from spamming the LRU list (by making a bunch of clients),
2792                // we will push down any other entries owned by the app.
2793                final int uid = app.info.uid;
2794                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2795                    ProcessRecord subProc = mLruProcesses.get(i);
2796                    if (subProc.info.uid == uid) {
2797                        // We want to push this one down the list.  If the process after
2798                        // it is for the same uid, however, don't do so, because we don't
2799                        // want them internally to be re-ordered.
2800                        if (mLruProcesses.get(i-1).info.uid != uid) {
2801                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2802                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2803                            ProcessRecord tmp = mLruProcesses.get(i);
2804                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2805                            mLruProcesses.set(i-1, tmp);
2806                            i--;
2807                        }
2808                    } else {
2809                        // A gap, we can stop here.
2810                        break;
2811                    }
2812                }
2813            } else {
2814                // Process has activities, put it at the very tipsy-top.
2815                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2816                mLruProcesses.add(app);
2817            }
2818            nextIndex = mLruProcessServiceStart;
2819        } else if (hasService) {
2820            // Process has services, put it at the top of the service list.
2821            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2822            mLruProcesses.add(mLruProcessActivityStart, app);
2823            nextIndex = mLruProcessServiceStart;
2824            mLruProcessActivityStart++;
2825        } else  {
2826            // Process not otherwise of interest, it goes to the top of the non-service area.
2827            int index = mLruProcessServiceStart;
2828            if (client != null) {
2829                // If there is a client, don't allow the process to be moved up higher
2830                // in the list than that client.
2831                int clientIndex = mLruProcesses.lastIndexOf(client);
2832                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2833                        + " when updating " + app);
2834                if (clientIndex <= lrui) {
2835                    // Don't allow the client index restriction to push it down farther in the
2836                    // list than it already is.
2837                    clientIndex = lrui;
2838                }
2839                if (clientIndex >= 0 && index > clientIndex) {
2840                    index = clientIndex;
2841                }
2842            }
2843            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2844            mLruProcesses.add(index, app);
2845            nextIndex = index-1;
2846            mLruProcessActivityStart++;
2847            mLruProcessServiceStart++;
2848        }
2849
2850        // If the app is currently using a content provider or service,
2851        // bump those processes as well.
2852        for (int j=app.connections.size()-1; j>=0; j--) {
2853            ConnectionRecord cr = app.connections.valueAt(j);
2854            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2855                    && cr.binding.service.app != null
2856                    && cr.binding.service.app.lruSeq != mLruSeq
2857                    && !cr.binding.service.app.persistent) {
2858                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2859                        "service connection", cr, app);
2860            }
2861        }
2862        for (int j=app.conProviders.size()-1; j>=0; j--) {
2863            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2864            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2865                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2866                        "provider reference", cpr, app);
2867            }
2868        }
2869    }
2870
2871    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2872        if (uid == Process.SYSTEM_UID) {
2873            // The system gets to run in any process.  If there are multiple
2874            // processes with the same uid, just pick the first (this
2875            // should never happen).
2876            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2877            if (procs == null) return null;
2878            final int N = procs.size();
2879            for (int i = 0; i < N; i++) {
2880                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2881            }
2882        }
2883        ProcessRecord proc = mProcessNames.get(processName, uid);
2884        if (false && proc != null && !keepIfLarge
2885                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2886                && proc.lastCachedPss >= 4000) {
2887            // Turn this condition on to cause killing to happen regularly, for testing.
2888            if (proc.baseProcessTracker != null) {
2889                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2890            }
2891            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2892        } else if (proc != null && !keepIfLarge
2893                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2894                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2895            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2896            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2897                if (proc.baseProcessTracker != null) {
2898                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2899                }
2900                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2901            }
2902        }
2903        return proc;
2904    }
2905
2906    void ensurePackageDexOpt(String packageName) {
2907        IPackageManager pm = AppGlobals.getPackageManager();
2908        try {
2909            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2910                mDidDexOpt = true;
2911            }
2912        } catch (RemoteException e) {
2913        }
2914    }
2915
2916    boolean isNextTransitionForward() {
2917        int transit = mWindowManager.getPendingAppTransition();
2918        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2919                || transit == AppTransition.TRANSIT_TASK_OPEN
2920                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2921    }
2922
2923    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2924            String processName, String abiOverride, int uid, Runnable crashHandler) {
2925        synchronized(this) {
2926            ApplicationInfo info = new ApplicationInfo();
2927            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2928            // For isolated processes, the former contains the parent's uid and the latter the
2929            // actual uid of the isolated process.
2930            // In the special case introduced by this method (which is, starting an isolated
2931            // process directly from the SystemServer without an actual parent app process) the
2932            // closest thing to a parent's uid is SYSTEM_UID.
2933            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2934            // the |isolated| logic in the ProcessRecord constructor.
2935            info.uid = Process.SYSTEM_UID;
2936            info.processName = processName;
2937            info.className = entryPoint;
2938            info.packageName = "android";
2939            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2940                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2941                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2942                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2943                    crashHandler);
2944            return proc != null ? proc.pid : 0;
2945        }
2946    }
2947
2948    final ProcessRecord startProcessLocked(String processName,
2949            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2950            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2951            boolean isolated, boolean keepIfLarge) {
2952        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2953                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2954                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2955                null /* crashHandler */);
2956    }
2957
2958    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2959            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2960            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2961            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2962        long startTime = SystemClock.elapsedRealtime();
2963        ProcessRecord app;
2964        if (!isolated) {
2965            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2966            checkTime(startTime, "startProcess: after getProcessRecord");
2967        } else {
2968            // If this is an isolated process, it can't re-use an existing process.
2969            app = null;
2970        }
2971        // We don't have to do anything more if:
2972        // (1) There is an existing application record; and
2973        // (2) The caller doesn't think it is dead, OR there is no thread
2974        //     object attached to it so we know it couldn't have crashed; and
2975        // (3) There is a pid assigned to it, so it is either starting or
2976        //     already running.
2977        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2978                + " app=" + app + " knownToBeDead=" + knownToBeDead
2979                + " thread=" + (app != null ? app.thread : null)
2980                + " pid=" + (app != null ? app.pid : -1));
2981        if (app != null && app.pid > 0) {
2982            if (!knownToBeDead || app.thread == null) {
2983                // We already have the app running, or are waiting for it to
2984                // come up (we have a pid but not yet its thread), so keep it.
2985                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2986                // If this is a new package in the process, add the package to the list
2987                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2988                checkTime(startTime, "startProcess: done, added package to proc");
2989                return app;
2990            }
2991
2992            // An application record is attached to a previous process,
2993            // clean it up now.
2994            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2995            checkTime(startTime, "startProcess: bad proc running, killing");
2996            Process.killProcessGroup(app.info.uid, app.pid);
2997            handleAppDiedLocked(app, true, true);
2998            checkTime(startTime, "startProcess: done killing old proc");
2999        }
3000
3001        String hostingNameStr = hostingName != null
3002                ? hostingName.flattenToShortString() : null;
3003
3004        if (!isolated) {
3005            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3006                // If we are in the background, then check to see if this process
3007                // is bad.  If so, we will just silently fail.
3008                if (mBadProcesses.get(info.processName, info.uid) != null) {
3009                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3010                            + "/" + info.processName);
3011                    return null;
3012                }
3013            } else {
3014                // When the user is explicitly starting a process, then clear its
3015                // crash count so that we won't make it bad until they see at
3016                // least one crash dialog again, and make the process good again
3017                // if it had been bad.
3018                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3019                        + "/" + info.processName);
3020                mProcessCrashTimes.remove(info.processName, info.uid);
3021                if (mBadProcesses.get(info.processName, info.uid) != null) {
3022                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3023                            UserHandle.getUserId(info.uid), info.uid,
3024                            info.processName);
3025                    mBadProcesses.remove(info.processName, info.uid);
3026                    if (app != null) {
3027                        app.bad = false;
3028                    }
3029                }
3030            }
3031        }
3032
3033        if (app == null) {
3034            checkTime(startTime, "startProcess: creating new process record");
3035            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3036            app.crashHandler = crashHandler;
3037            if (app == null) {
3038                Slog.w(TAG, "Failed making new process record for "
3039                        + processName + "/" + info.uid + " isolated=" + isolated);
3040                return null;
3041            }
3042            mProcessNames.put(processName, app.uid, app);
3043            if (isolated) {
3044                mIsolatedProcesses.put(app.uid, app);
3045            }
3046            checkTime(startTime, "startProcess: done creating new process record");
3047        } else {
3048            // If this is a new package in the process, add the package to the list
3049            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3050            checkTime(startTime, "startProcess: added package to existing proc");
3051        }
3052
3053        // If the system is not ready yet, then hold off on starting this
3054        // process until it is.
3055        if (!mProcessesReady
3056                && !isAllowedWhileBooting(info)
3057                && !allowWhileBooting) {
3058            if (!mProcessesOnHold.contains(app)) {
3059                mProcessesOnHold.add(app);
3060            }
3061            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3062            checkTime(startTime, "startProcess: returning with proc on hold");
3063            return app;
3064        }
3065
3066        checkTime(startTime, "startProcess: stepping in to startProcess");
3067        startProcessLocked(
3068                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3069        checkTime(startTime, "startProcess: done starting proc!");
3070        return (app.pid != 0) ? app : null;
3071    }
3072
3073    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3074        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3075    }
3076
3077    private final void startProcessLocked(ProcessRecord app,
3078            String hostingType, String hostingNameStr) {
3079        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3080                null /* entryPoint */, null /* entryPointArgs */);
3081    }
3082
3083    private final void startProcessLocked(ProcessRecord app, String hostingType,
3084            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3085        long startTime = SystemClock.elapsedRealtime();
3086        if (app.pid > 0 && app.pid != MY_PID) {
3087            checkTime(startTime, "startProcess: removing from pids map");
3088            synchronized (mPidsSelfLocked) {
3089                mPidsSelfLocked.remove(app.pid);
3090                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3091            }
3092            checkTime(startTime, "startProcess: done removing from pids map");
3093            app.setPid(0);
3094        }
3095
3096        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3097                "startProcessLocked removing on hold: " + app);
3098        mProcessesOnHold.remove(app);
3099
3100        checkTime(startTime, "startProcess: starting to update cpu stats");
3101        updateCpuStats();
3102        checkTime(startTime, "startProcess: done updating cpu stats");
3103
3104        try {
3105            int uid = app.uid;
3106
3107            int[] gids = null;
3108            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3109            if (!app.isolated) {
3110                int[] permGids = null;
3111                try {
3112                    checkTime(startTime, "startProcess: getting gids from package manager");
3113                    final PackageManager pm = mContext.getPackageManager();
3114                    permGids = pm.getPackageGids(app.info.packageName);
3115
3116                    if (Environment.isExternalStorageEmulated()) {
3117                        checkTime(startTime, "startProcess: checking external storage perm");
3118                        if (pm.checkPermission(
3119                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3120                                app.info.packageName) == PERMISSION_GRANTED) {
3121                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3122                        } else {
3123                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3124                        }
3125                    }
3126                } catch (PackageManager.NameNotFoundException e) {
3127                    Slog.w(TAG, "Unable to retrieve gids", e);
3128                }
3129
3130                /*
3131                 * Add shared application and profile GIDs so applications can share some
3132                 * resources like shared libraries and access user-wide resources
3133                 */
3134                if (permGids == null) {
3135                    gids = new int[2];
3136                } else {
3137                    gids = new int[permGids.length + 2];
3138                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3139                }
3140                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3141                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3142            }
3143            checkTime(startTime, "startProcess: building args");
3144            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3145                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3146                        && mTopComponent != null
3147                        && app.processName.equals(mTopComponent.getPackageName())) {
3148                    uid = 0;
3149                }
3150                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3151                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3152                    uid = 0;
3153                }
3154            }
3155            int debugFlags = 0;
3156            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3157                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3158                // Also turn on CheckJNI for debuggable apps. It's quite
3159                // awkward to turn on otherwise.
3160                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3161            }
3162            // Run the app in safe mode if its manifest requests so or the
3163            // system is booted in safe mode.
3164            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3165                mSafeMode == true) {
3166                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3167            }
3168            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3169                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3170            }
3171            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3172                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3173            }
3174            if ("1".equals(SystemProperties.get("debug.assert"))) {
3175                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3176            }
3177
3178            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3179            if (requiredAbi == null) {
3180                requiredAbi = Build.SUPPORTED_ABIS[0];
3181            }
3182
3183            String instructionSet = null;
3184            if (app.info.primaryCpuAbi != null) {
3185                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3186            }
3187
3188            // Start the process.  It will either succeed and return a result containing
3189            // the PID of the new process, or else throw a RuntimeException.
3190            boolean isActivityProcess = (entryPoint == null);
3191            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3192            checkTime(startTime, "startProcess: asking zygote to start proc");
3193            Process.ProcessStartResult startResult = Process.start(entryPoint,
3194                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3195                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3196                    app.info.dataDir, entryPointArgs);
3197            checkTime(startTime, "startProcess: returned from zygote!");
3198
3199            if (app.isolated) {
3200                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3201            }
3202            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3203            checkTime(startTime, "startProcess: done updating battery stats");
3204
3205            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3206                    UserHandle.getUserId(uid), startResult.pid, uid,
3207                    app.processName, hostingType,
3208                    hostingNameStr != null ? hostingNameStr : "");
3209
3210            if (app.persistent) {
3211                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3212            }
3213
3214            checkTime(startTime, "startProcess: building log message");
3215            StringBuilder buf = mStringBuilder;
3216            buf.setLength(0);
3217            buf.append("Start proc ");
3218            buf.append(app.processName);
3219            if (!isActivityProcess) {
3220                buf.append(" [");
3221                buf.append(entryPoint);
3222                buf.append("]");
3223            }
3224            buf.append(" for ");
3225            buf.append(hostingType);
3226            if (hostingNameStr != null) {
3227                buf.append(" ");
3228                buf.append(hostingNameStr);
3229            }
3230            buf.append(": pid=");
3231            buf.append(startResult.pid);
3232            buf.append(" uid=");
3233            buf.append(uid);
3234            buf.append(" gids={");
3235            if (gids != null) {
3236                for (int gi=0; gi<gids.length; gi++) {
3237                    if (gi != 0) buf.append(", ");
3238                    buf.append(gids[gi]);
3239
3240                }
3241            }
3242            buf.append("}");
3243            if (requiredAbi != null) {
3244                buf.append(" abi=");
3245                buf.append(requiredAbi);
3246            }
3247            Slog.i(TAG, buf.toString());
3248            app.setPid(startResult.pid);
3249            app.usingWrapper = startResult.usingWrapper;
3250            app.removed = false;
3251            app.killed = false;
3252            app.killedByAm = false;
3253            checkTime(startTime, "startProcess: starting to update pids map");
3254            synchronized (mPidsSelfLocked) {
3255                this.mPidsSelfLocked.put(startResult.pid, app);
3256                if (isActivityProcess) {
3257                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3258                    msg.obj = app;
3259                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3260                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3261                }
3262            }
3263            checkTime(startTime, "startProcess: done updating pids map");
3264        } catch (RuntimeException e) {
3265            // XXX do better error recovery.
3266            app.setPid(0);
3267            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3268            if (app.isolated) {
3269                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3270            }
3271            Slog.e(TAG, "Failure starting process " + app.processName, e);
3272        }
3273    }
3274
3275    void updateUsageStats(ActivityRecord component, boolean resumed) {
3276        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3277        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3278        if (resumed) {
3279            if (mUsageStatsService != null) {
3280                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3281                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3282            }
3283            synchronized (stats) {
3284                stats.noteActivityResumedLocked(component.app.uid);
3285            }
3286        } else {
3287            if (mUsageStatsService != null) {
3288                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3289                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3290            }
3291            synchronized (stats) {
3292                stats.noteActivityPausedLocked(component.app.uid);
3293            }
3294        }
3295    }
3296
3297    Intent getHomeIntent() {
3298        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3299        intent.setComponent(mTopComponent);
3300        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3301            intent.addCategory(Intent.CATEGORY_HOME);
3302        }
3303        return intent;
3304    }
3305
3306    boolean startHomeActivityLocked(int userId) {
3307        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3308                && mTopAction == null) {
3309            // We are running in factory test mode, but unable to find
3310            // the factory test app, so just sit around displaying the
3311            // error message and don't try to start anything.
3312            return false;
3313        }
3314        Intent intent = getHomeIntent();
3315        ActivityInfo aInfo =
3316            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3317        if (aInfo != null) {
3318            intent.setComponent(new ComponentName(
3319                    aInfo.applicationInfo.packageName, aInfo.name));
3320            // Don't do this if the home app is currently being
3321            // instrumented.
3322            aInfo = new ActivityInfo(aInfo);
3323            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3324            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3325                    aInfo.applicationInfo.uid, true);
3326            if (app == null || app.instrumentationClass == null) {
3327                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3328                mStackSupervisor.startHomeActivity(intent, aInfo);
3329            }
3330        }
3331
3332        return true;
3333    }
3334
3335    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3336        ActivityInfo ai = null;
3337        ComponentName comp = intent.getComponent();
3338        try {
3339            if (comp != null) {
3340                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3341            } else {
3342                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3343                        intent,
3344                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3345                            flags, userId);
3346
3347                if (info != null) {
3348                    ai = info.activityInfo;
3349                }
3350            }
3351        } catch (RemoteException e) {
3352            // ignore
3353        }
3354
3355        return ai;
3356    }
3357
3358    /**
3359     * Starts the "new version setup screen" if appropriate.
3360     */
3361    void startSetupActivityLocked() {
3362        // Only do this once per boot.
3363        if (mCheckedForSetup) {
3364            return;
3365        }
3366
3367        // We will show this screen if the current one is a different
3368        // version than the last one shown, and we are not running in
3369        // low-level factory test mode.
3370        final ContentResolver resolver = mContext.getContentResolver();
3371        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3372                Settings.Global.getInt(resolver,
3373                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3374            mCheckedForSetup = true;
3375
3376            // See if we should be showing the platform update setup UI.
3377            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3378            List<ResolveInfo> ris = mContext.getPackageManager()
3379                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3380
3381            // We don't allow third party apps to replace this.
3382            ResolveInfo ri = null;
3383            for (int i=0; ris != null && i<ris.size(); i++) {
3384                if ((ris.get(i).activityInfo.applicationInfo.flags
3385                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3386                    ri = ris.get(i);
3387                    break;
3388                }
3389            }
3390
3391            if (ri != null) {
3392                String vers = ri.activityInfo.metaData != null
3393                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3394                        : null;
3395                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3396                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3397                            Intent.METADATA_SETUP_VERSION);
3398                }
3399                String lastVers = Settings.Secure.getString(
3400                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3401                if (vers != null && !vers.equals(lastVers)) {
3402                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3403                    intent.setComponent(new ComponentName(
3404                            ri.activityInfo.packageName, ri.activityInfo.name));
3405                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3406                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3407                            null);
3408                }
3409            }
3410        }
3411    }
3412
3413    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3414        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3415    }
3416
3417    void enforceNotIsolatedCaller(String caller) {
3418        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3419            throw new SecurityException("Isolated process not allowed to call " + caller);
3420        }
3421    }
3422
3423    void enforceShellRestriction(String restriction, int userHandle) {
3424        if (Binder.getCallingUid() == Process.SHELL_UID) {
3425            if (userHandle < 0
3426                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3427                throw new SecurityException("Shell does not have permission to access user "
3428                        + userHandle);
3429            }
3430        }
3431    }
3432
3433    @Override
3434    public int getFrontActivityScreenCompatMode() {
3435        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3436        synchronized (this) {
3437            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3438        }
3439    }
3440
3441    @Override
3442    public void setFrontActivityScreenCompatMode(int mode) {
3443        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3444                "setFrontActivityScreenCompatMode");
3445        synchronized (this) {
3446            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3447        }
3448    }
3449
3450    @Override
3451    public int getPackageScreenCompatMode(String packageName) {
3452        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3453        synchronized (this) {
3454            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3455        }
3456    }
3457
3458    @Override
3459    public void setPackageScreenCompatMode(String packageName, int mode) {
3460        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3461                "setPackageScreenCompatMode");
3462        synchronized (this) {
3463            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3464        }
3465    }
3466
3467    @Override
3468    public boolean getPackageAskScreenCompat(String packageName) {
3469        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3470        synchronized (this) {
3471            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3472        }
3473    }
3474
3475    @Override
3476    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3477        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3478                "setPackageAskScreenCompat");
3479        synchronized (this) {
3480            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3481        }
3482    }
3483
3484    private void dispatchProcessesChanged() {
3485        int N;
3486        synchronized (this) {
3487            N = mPendingProcessChanges.size();
3488            if (mActiveProcessChanges.length < N) {
3489                mActiveProcessChanges = new ProcessChangeItem[N];
3490            }
3491            mPendingProcessChanges.toArray(mActiveProcessChanges);
3492            mAvailProcessChanges.addAll(mPendingProcessChanges);
3493            mPendingProcessChanges.clear();
3494            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3495        }
3496
3497        int i = mProcessObservers.beginBroadcast();
3498        while (i > 0) {
3499            i--;
3500            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3501            if (observer != null) {
3502                try {
3503                    for (int j=0; j<N; j++) {
3504                        ProcessChangeItem item = mActiveProcessChanges[j];
3505                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3506                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3507                                    + item.pid + " uid=" + item.uid + ": "
3508                                    + item.foregroundActivities);
3509                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3510                                    item.foregroundActivities);
3511                        }
3512                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3513                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3514                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3515                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3516                        }
3517                    }
3518                } catch (RemoteException e) {
3519                }
3520            }
3521        }
3522        mProcessObservers.finishBroadcast();
3523    }
3524
3525    private void dispatchProcessDied(int pid, int uid) {
3526        int i = mProcessObservers.beginBroadcast();
3527        while (i > 0) {
3528            i--;
3529            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3530            if (observer != null) {
3531                try {
3532                    observer.onProcessDied(pid, uid);
3533                } catch (RemoteException e) {
3534                }
3535            }
3536        }
3537        mProcessObservers.finishBroadcast();
3538    }
3539
3540    @Override
3541    public final int startActivity(IApplicationThread caller, String callingPackage,
3542            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3543            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3544        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3545            resultWho, requestCode, startFlags, profilerInfo, options,
3546            UserHandle.getCallingUserId());
3547    }
3548
3549    @Override
3550    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3551            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3552            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3553        enforceNotIsolatedCaller("startActivity");
3554        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3555                false, ALLOW_FULL_ONLY, "startActivity", null);
3556        // TODO: Switch to user app stacks here.
3557        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3558                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3559                profilerInfo, null, null, options, userId, null, null);
3560    }
3561
3562    @Override
3563    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3564            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3565            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3566
3567        // This is very dangerous -- it allows you to perform a start activity (including
3568        // permission grants) as any app that may launch one of your own activities.  So
3569        // we will only allow this to be done from activities that are part of the core framework,
3570        // and then only when they are running as the system.
3571        final ActivityRecord sourceRecord;
3572        final int targetUid;
3573        final String targetPackage;
3574        synchronized (this) {
3575            if (resultTo == null) {
3576                throw new SecurityException("Must be called from an activity");
3577            }
3578            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3579            if (sourceRecord == null) {
3580                throw new SecurityException("Called with bad activity token: " + resultTo);
3581            }
3582            if (!sourceRecord.info.packageName.equals("android")) {
3583                throw new SecurityException(
3584                        "Must be called from an activity that is declared in the android package");
3585            }
3586            if (sourceRecord.app == null) {
3587                throw new SecurityException("Called without a process attached to activity");
3588            }
3589            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3590                // This is still okay, as long as this activity is running under the
3591                // uid of the original calling activity.
3592                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3593                    throw new SecurityException(
3594                            "Calling activity in uid " + sourceRecord.app.uid
3595                                    + " must be system uid or original calling uid "
3596                                    + sourceRecord.launchedFromUid);
3597                }
3598            }
3599            targetUid = sourceRecord.launchedFromUid;
3600            targetPackage = sourceRecord.launchedFromPackage;
3601        }
3602
3603        if (userId == UserHandle.USER_NULL) {
3604            userId = UserHandle.getUserId(sourceRecord.app.uid);
3605        }
3606
3607        // TODO: Switch to user app stacks here.
3608        try {
3609            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3610                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3611                    null, null, options, userId, null, null);
3612            return ret;
3613        } catch (SecurityException e) {
3614            // XXX need to figure out how to propagate to original app.
3615            // A SecurityException here is generally actually a fault of the original
3616            // calling activity (such as a fairly granting permissions), so propagate it
3617            // back to them.
3618            /*
3619            StringBuilder msg = new StringBuilder();
3620            msg.append("While launching");
3621            msg.append(intent.toString());
3622            msg.append(": ");
3623            msg.append(e.getMessage());
3624            */
3625            throw e;
3626        }
3627    }
3628
3629    @Override
3630    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3632            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3633        enforceNotIsolatedCaller("startActivityAndWait");
3634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3635                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3636        WaitResult res = new WaitResult();
3637        // TODO: Switch to user app stacks here.
3638        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3639                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3640                options, userId, null, null);
3641        return res;
3642    }
3643
3644    @Override
3645    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3646            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3647            int startFlags, Configuration config, Bundle options, int userId) {
3648        enforceNotIsolatedCaller("startActivityWithConfig");
3649        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3650                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3651        // TODO: Switch to user app stacks here.
3652        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3653                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3654                null, null, config, options, userId, null, null);
3655        return ret;
3656    }
3657
3658    @Override
3659    public int startActivityIntentSender(IApplicationThread caller,
3660            IntentSender intent, Intent fillInIntent, String resolvedType,
3661            IBinder resultTo, String resultWho, int requestCode,
3662            int flagsMask, int flagsValues, Bundle options) {
3663        enforceNotIsolatedCaller("startActivityIntentSender");
3664        // Refuse possible leaked file descriptors
3665        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3666            throw new IllegalArgumentException("File descriptors passed in Intent");
3667        }
3668
3669        IIntentSender sender = intent.getTarget();
3670        if (!(sender instanceof PendingIntentRecord)) {
3671            throw new IllegalArgumentException("Bad PendingIntent object");
3672        }
3673
3674        PendingIntentRecord pir = (PendingIntentRecord)sender;
3675
3676        synchronized (this) {
3677            // If this is coming from the currently resumed activity, it is
3678            // effectively saying that app switches are allowed at this point.
3679            final ActivityStack stack = getFocusedStack();
3680            if (stack.mResumedActivity != null &&
3681                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3682                mAppSwitchesAllowedTime = 0;
3683            }
3684        }
3685        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3686                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3687        return ret;
3688    }
3689
3690    @Override
3691    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3692            Intent intent, String resolvedType, IVoiceInteractionSession session,
3693            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3694            Bundle options, int userId) {
3695        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3696                != PackageManager.PERMISSION_GRANTED) {
3697            String msg = "Permission Denial: startVoiceActivity() from pid="
3698                    + Binder.getCallingPid()
3699                    + ", uid=" + Binder.getCallingUid()
3700                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3701            Slog.w(TAG, msg);
3702            throw new SecurityException(msg);
3703        }
3704        if (session == null || interactor == null) {
3705            throw new NullPointerException("null session or interactor");
3706        }
3707        userId = handleIncomingUser(callingPid, callingUid, userId,
3708                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3709        // TODO: Switch to user app stacks here.
3710        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3711                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3712                null, options, userId, null, null);
3713    }
3714
3715    @Override
3716    public boolean startNextMatchingActivity(IBinder callingActivity,
3717            Intent intent, Bundle options) {
3718        // Refuse possible leaked file descriptors
3719        if (intent != null && intent.hasFileDescriptors() == true) {
3720            throw new IllegalArgumentException("File descriptors passed in Intent");
3721        }
3722
3723        synchronized (this) {
3724            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3725            if (r == null) {
3726                ActivityOptions.abort(options);
3727                return false;
3728            }
3729            if (r.app == null || r.app.thread == null) {
3730                // The caller is not running...  d'oh!
3731                ActivityOptions.abort(options);
3732                return false;
3733            }
3734            intent = new Intent(intent);
3735            // The caller is not allowed to change the data.
3736            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3737            // And we are resetting to find the next component...
3738            intent.setComponent(null);
3739
3740            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3741
3742            ActivityInfo aInfo = null;
3743            try {
3744                List<ResolveInfo> resolves =
3745                    AppGlobals.getPackageManager().queryIntentActivities(
3746                            intent, r.resolvedType,
3747                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3748                            UserHandle.getCallingUserId());
3749
3750                // Look for the original activity in the list...
3751                final int N = resolves != null ? resolves.size() : 0;
3752                for (int i=0; i<N; i++) {
3753                    ResolveInfo rInfo = resolves.get(i);
3754                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3755                            && rInfo.activityInfo.name.equals(r.info.name)) {
3756                        // We found the current one...  the next matching is
3757                        // after it.
3758                        i++;
3759                        if (i<N) {
3760                            aInfo = resolves.get(i).activityInfo;
3761                        }
3762                        if (debug) {
3763                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3764                                    + "/" + r.info.name);
3765                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3766                                    + "/" + aInfo.name);
3767                        }
3768                        break;
3769                    }
3770                }
3771            } catch (RemoteException e) {
3772            }
3773
3774            if (aInfo == null) {
3775                // Nobody who is next!
3776                ActivityOptions.abort(options);
3777                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3778                return false;
3779            }
3780
3781            intent.setComponent(new ComponentName(
3782                    aInfo.applicationInfo.packageName, aInfo.name));
3783            intent.setFlags(intent.getFlags()&~(
3784                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3785                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3786                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3787                    Intent.FLAG_ACTIVITY_NEW_TASK));
3788
3789            // Okay now we need to start the new activity, replacing the
3790            // currently running activity.  This is a little tricky because
3791            // we want to start the new one as if the current one is finished,
3792            // but not finish the current one first so that there is no flicker.
3793            // And thus...
3794            final boolean wasFinishing = r.finishing;
3795            r.finishing = true;
3796
3797            // Propagate reply information over to the new activity.
3798            final ActivityRecord resultTo = r.resultTo;
3799            final String resultWho = r.resultWho;
3800            final int requestCode = r.requestCode;
3801            r.resultTo = null;
3802            if (resultTo != null) {
3803                resultTo.removeResultsLocked(r, resultWho, requestCode);
3804            }
3805
3806            final long origId = Binder.clearCallingIdentity();
3807            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3808                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3809                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3810                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3811            Binder.restoreCallingIdentity(origId);
3812
3813            r.finishing = wasFinishing;
3814            if (res != ActivityManager.START_SUCCESS) {
3815                return false;
3816            }
3817            return true;
3818        }
3819    }
3820
3821    @Override
3822    public final int startActivityFromRecents(int taskId, Bundle options) {
3823        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3824            String msg = "Permission Denial: startActivityFromRecents called without " +
3825                    START_TASKS_FROM_RECENTS;
3826            Slog.w(TAG, msg);
3827            throw new SecurityException(msg);
3828        }
3829        return startActivityFromRecentsInner(taskId, options);
3830    }
3831
3832    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3833        final TaskRecord task;
3834        final int callingUid;
3835        final String callingPackage;
3836        final Intent intent;
3837        final int userId;
3838        synchronized (this) {
3839            task = recentTaskForIdLocked(taskId);
3840            if (task == null) {
3841                throw new IllegalArgumentException("Task " + taskId + " not found.");
3842            }
3843            callingUid = task.mCallingUid;
3844            callingPackage = task.mCallingPackage;
3845            intent = task.intent;
3846            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3847            userId = task.userId;
3848        }
3849        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3850                options, userId, null, task);
3851    }
3852
3853    final int startActivityInPackage(int uid, String callingPackage,
3854            Intent intent, String resolvedType, IBinder resultTo,
3855            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3856            IActivityContainer container, TaskRecord inTask) {
3857
3858        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3859                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3860
3861        // TODO: Switch to user app stacks here.
3862        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3863                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3864                null, null, null, options, userId, container, inTask);
3865        return ret;
3866    }
3867
3868    @Override
3869    public final int startActivities(IApplicationThread caller, String callingPackage,
3870            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3871            int userId) {
3872        enforceNotIsolatedCaller("startActivities");
3873        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3874                false, ALLOW_FULL_ONLY, "startActivity", null);
3875        // TODO: Switch to user app stacks here.
3876        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3877                resolvedTypes, resultTo, options, userId);
3878        return ret;
3879    }
3880
3881    final int startActivitiesInPackage(int uid, String callingPackage,
3882            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3883            Bundle options, int userId) {
3884
3885        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3886                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3887        // TODO: Switch to user app stacks here.
3888        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3889                resultTo, options, userId);
3890        return ret;
3891    }
3892
3893    //explicitly remove thd old information in mRecentTasks when removing existing user.
3894    private void removeRecentTasksForUserLocked(int userId) {
3895        if(userId <= 0) {
3896            Slog.i(TAG, "Can't remove recent task on user " + userId);
3897            return;
3898        }
3899
3900        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3901            TaskRecord tr = mRecentTasks.get(i);
3902            if (tr.userId == userId) {
3903                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3904                        + " when finishing user" + userId);
3905                mRecentTasks.remove(i);
3906                tr.removedFromRecents(mTaskPersister);
3907            }
3908        }
3909
3910        // Remove tasks from persistent storage.
3911        mTaskPersister.wakeup(null, true);
3912    }
3913
3914    // Sort by taskId
3915    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3916        @Override
3917        public int compare(TaskRecord lhs, TaskRecord rhs) {
3918            return rhs.taskId - lhs.taskId;
3919        }
3920    };
3921
3922    // Extract the affiliates of the chain containing mRecentTasks[start].
3923    private int processNextAffiliateChain(int start) {
3924        final TaskRecord startTask = mRecentTasks.get(start);
3925        final int affiliateId = startTask.mAffiliatedTaskId;
3926
3927        // Quick identification of isolated tasks. I.e. those not launched behind.
3928        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3929                startTask.mNextAffiliate == null) {
3930            // There is still a slim chance that there are other tasks that point to this task
3931            // and that the chain is so messed up that this task no longer points to them but
3932            // the gain of this optimization outweighs the risk.
3933            startTask.inRecents = true;
3934            return start + 1;
3935        }
3936
3937        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3938        mTmpRecents.clear();
3939        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3940            final TaskRecord task = mRecentTasks.get(i);
3941            if (task.mAffiliatedTaskId == affiliateId) {
3942                mRecentTasks.remove(i);
3943                mTmpRecents.add(task);
3944            }
3945        }
3946
3947        // Sort them all by taskId. That is the order they were create in and that order will
3948        // always be correct.
3949        Collections.sort(mTmpRecents, mTaskRecordComparator);
3950
3951        // Go through and fix up the linked list.
3952        // The first one is the end of the chain and has no next.
3953        final TaskRecord first = mTmpRecents.get(0);
3954        first.inRecents = true;
3955        if (first.mNextAffiliate != null) {
3956            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3957            first.setNextAffiliate(null);
3958            mTaskPersister.wakeup(first, false);
3959        }
3960        // Everything in the middle is doubly linked from next to prev.
3961        final int tmpSize = mTmpRecents.size();
3962        for (int i = 0; i < tmpSize - 1; ++i) {
3963            final TaskRecord next = mTmpRecents.get(i);
3964            final TaskRecord prev = mTmpRecents.get(i + 1);
3965            if (next.mPrevAffiliate != prev) {
3966                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3967                        " setting prev=" + prev);
3968                next.setPrevAffiliate(prev);
3969                mTaskPersister.wakeup(next, false);
3970            }
3971            if (prev.mNextAffiliate != next) {
3972                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3973                        " setting next=" + next);
3974                prev.setNextAffiliate(next);
3975                mTaskPersister.wakeup(prev, false);
3976            }
3977            prev.inRecents = true;
3978        }
3979        // The last one is the beginning of the list and has no prev.
3980        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3981        if (last.mPrevAffiliate != null) {
3982            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3983            last.setPrevAffiliate(null);
3984            mTaskPersister.wakeup(last, false);
3985        }
3986
3987        // Insert the group back into mRecentTasks at start.
3988        mRecentTasks.addAll(start, mTmpRecents);
3989
3990        // Let the caller know where we left off.
3991        return start + tmpSize;
3992    }
3993
3994    /**
3995     * Update the recent tasks lists: make sure tasks should still be here (their
3996     * applications / activities still exist), update their availability, fixup ordering
3997     * of affiliations.
3998     */
3999    void cleanupRecentTasksLocked(int userId) {
4000        if (mRecentTasks == null) {
4001            // Happens when called from the packagemanager broadcast before boot.
4002            return;
4003        }
4004
4005        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4006        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4007        final IPackageManager pm = AppGlobals.getPackageManager();
4008        final ActivityInfo dummyAct = new ActivityInfo();
4009        final ApplicationInfo dummyApp = new ApplicationInfo();
4010
4011        int N = mRecentTasks.size();
4012
4013        int[] users = userId == UserHandle.USER_ALL
4014                ? getUsersLocked() : new int[] { userId };
4015        for (int user : users) {
4016            for (int i = 0; i < N; i++) {
4017                TaskRecord task = mRecentTasks.get(i);
4018                if (task.userId != user) {
4019                    // Only look at tasks for the user ID of interest.
4020                    continue;
4021                }
4022                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4023                    // This situation is broken, and we should just get rid of it now.
4024                    mRecentTasks.remove(i);
4025                    task.removedFromRecents(mTaskPersister);
4026                    i--;
4027                    N--;
4028                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4029                    continue;
4030                }
4031                // Check whether this activity is currently available.
4032                if (task.realActivity != null) {
4033                    ActivityInfo ai = availActCache.get(task.realActivity);
4034                    if (ai == null) {
4035                        try {
4036                            ai = pm.getActivityInfo(task.realActivity,
4037                                    PackageManager.GET_UNINSTALLED_PACKAGES
4038                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4039                        } catch (RemoteException e) {
4040                            // Will never happen.
4041                            continue;
4042                        }
4043                        if (ai == null) {
4044                            ai = dummyAct;
4045                        }
4046                        availActCache.put(task.realActivity, ai);
4047                    }
4048                    if (ai == dummyAct) {
4049                        // This could be either because the activity no longer exists, or the
4050                        // app is temporarily gone.  For the former we want to remove the recents
4051                        // entry; for the latter we want to mark it as unavailable.
4052                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4053                        if (app == null) {
4054                            try {
4055                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4056                                        PackageManager.GET_UNINSTALLED_PACKAGES
4057                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4058                            } catch (RemoteException e) {
4059                                // Will never happen.
4060                                continue;
4061                            }
4062                            if (app == null) {
4063                                app = dummyApp;
4064                            }
4065                            availAppCache.put(task.realActivity.getPackageName(), app);
4066                        }
4067                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4068                            // Doesn't exist any more!  Good-bye.
4069                            mRecentTasks.remove(i);
4070                            task.removedFromRecents(mTaskPersister);
4071                            i--;
4072                            N--;
4073                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4074                            continue;
4075                        } else {
4076                            // Otherwise just not available for now.
4077                            if (task.isAvailable) {
4078                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4079                                        + task);
4080                            }
4081                            task.isAvailable = false;
4082                        }
4083                    } else {
4084                        if (!ai.enabled || !ai.applicationInfo.enabled
4085                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4086                            if (task.isAvailable) {
4087                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4088                                        + task + " (enabled=" + ai.enabled + "/"
4089                                        + ai.applicationInfo.enabled +  " flags="
4090                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4091                            }
4092                            task.isAvailable = false;
4093                        } else {
4094                            if (!task.isAvailable) {
4095                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4096                                        + task);
4097                            }
4098                            task.isAvailable = true;
4099                        }
4100                    }
4101                }
4102            }
4103        }
4104
4105        // Verify the affiliate chain for each task.
4106        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4107        }
4108
4109        mTmpRecents.clear();
4110        // mRecentTasks is now in sorted, affiliated order.
4111    }
4112
4113    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4114        int N = mRecentTasks.size();
4115        TaskRecord top = task;
4116        int topIndex = taskIndex;
4117        while (top.mNextAffiliate != null && topIndex > 0) {
4118            top = top.mNextAffiliate;
4119            topIndex--;
4120        }
4121        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4122                + topIndex + " from intial " + taskIndex);
4123        // Find the end of the chain, doing a sanity check along the way.
4124        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4125        int endIndex = topIndex;
4126        TaskRecord prev = top;
4127        while (endIndex < N) {
4128            TaskRecord cur = mRecentTasks.get(endIndex);
4129            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4130                    + endIndex + " " + cur);
4131            if (cur == top) {
4132                // Verify start of the chain.
4133                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4134                    Slog.wtf(TAG, "Bad chain @" + endIndex
4135                            + ": first task has next affiliate: " + prev);
4136                    sane = false;
4137                    break;
4138                }
4139            } else {
4140                // Verify middle of the chain's next points back to the one before.
4141                if (cur.mNextAffiliate != prev
4142                        || cur.mNextAffiliateTaskId != prev.taskId) {
4143                    Slog.wtf(TAG, "Bad chain @" + endIndex
4144                            + ": middle task " + cur + " @" + endIndex
4145                            + " has bad next affiliate "
4146                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4147                            + ", expected " + prev);
4148                    sane = false;
4149                    break;
4150                }
4151            }
4152            if (cur.mPrevAffiliateTaskId == -1) {
4153                // Chain ends here.
4154                if (cur.mPrevAffiliate != null) {
4155                    Slog.wtf(TAG, "Bad chain @" + endIndex
4156                            + ": last task " + cur + " has previous affiliate "
4157                            + cur.mPrevAffiliate);
4158                    sane = false;
4159                }
4160                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4161                break;
4162            } else {
4163                // Verify middle of the chain's prev points to a valid item.
4164                if (cur.mPrevAffiliate == null) {
4165                    Slog.wtf(TAG, "Bad chain @" + endIndex
4166                            + ": task " + cur + " has previous affiliate "
4167                            + cur.mPrevAffiliate + " but should be id "
4168                            + cur.mPrevAffiliate);
4169                    sane = false;
4170                    break;
4171                }
4172            }
4173            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4174                Slog.wtf(TAG, "Bad chain @" + endIndex
4175                        + ": task " + cur + " has affiliated id "
4176                        + cur.mAffiliatedTaskId + " but should be "
4177                        + task.mAffiliatedTaskId);
4178                sane = false;
4179                break;
4180            }
4181            prev = cur;
4182            endIndex++;
4183            if (endIndex >= N) {
4184                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4185                        + ": last task " + prev);
4186                sane = false;
4187                break;
4188            }
4189        }
4190        if (sane) {
4191            if (endIndex < taskIndex) {
4192                Slog.wtf(TAG, "Bad chain @" + endIndex
4193                        + ": did not extend to task " + task + " @" + taskIndex);
4194                sane = false;
4195            }
4196        }
4197        if (sane) {
4198            // All looks good, we can just move all of the affiliated tasks
4199            // to the top.
4200            for (int i=topIndex; i<=endIndex; i++) {
4201                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4202                        + " from " + i + " to " + (i-topIndex));
4203                TaskRecord cur = mRecentTasks.remove(i);
4204                mRecentTasks.add(i-topIndex, cur);
4205            }
4206            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4207                    + " to " + endIndex);
4208            return true;
4209        }
4210
4211        // Whoops, couldn't do it.
4212        return false;
4213    }
4214
4215    final void addRecentTaskLocked(TaskRecord task) {
4216        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4217                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4218
4219        int N = mRecentTasks.size();
4220        // Quick case: check if the top-most recent task is the same.
4221        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4222            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4223            return;
4224        }
4225        // Another quick case: check if this is part of a set of affiliated
4226        // tasks that are at the top.
4227        if (isAffiliated && N > 0 && task.inRecents
4228                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4229            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4230                    + " at top when adding " + task);
4231            return;
4232        }
4233        // Another quick case: never add voice sessions.
4234        if (task.voiceSession != null) {
4235            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4236            return;
4237        }
4238
4239        boolean needAffiliationFix = false;
4240
4241        // Slightly less quick case: the task is already in recents, so all we need
4242        // to do is move it.
4243        if (task.inRecents) {
4244            int taskIndex = mRecentTasks.indexOf(task);
4245            if (taskIndex >= 0) {
4246                if (!isAffiliated) {
4247                    // Simple case: this is not an affiliated task, so we just move it to the front.
4248                    mRecentTasks.remove(taskIndex);
4249                    mRecentTasks.add(0, task);
4250                    notifyTaskPersisterLocked(task, false);
4251                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4252                            + " from " + taskIndex);
4253                    return;
4254                } else {
4255                    // More complicated: need to keep all affiliated tasks together.
4256                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4257                        // All went well.
4258                        return;
4259                    }
4260
4261                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4262                    // everything and then go through our general path of adding a new task.
4263                    needAffiliationFix = true;
4264                }
4265            } else {
4266                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4267                needAffiliationFix = true;
4268            }
4269        }
4270
4271        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4272        trimRecentsForTask(task, true);
4273
4274        N = mRecentTasks.size();
4275        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4276            final TaskRecord tr = mRecentTasks.remove(N - 1);
4277            tr.removedFromRecents(mTaskPersister);
4278            N--;
4279        }
4280        task.inRecents = true;
4281        if (!isAffiliated || needAffiliationFix) {
4282            // If this is a simple non-affiliated task, or we had some failure trying to
4283            // handle it as part of an affilated task, then just place it at the top.
4284            mRecentTasks.add(0, task);
4285        } else if (isAffiliated) {
4286            // If this is a new affiliated task, then move all of the affiliated tasks
4287            // to the front and insert this new one.
4288            TaskRecord other = task.mNextAffiliate;
4289            if (other == null) {
4290                other = task.mPrevAffiliate;
4291            }
4292            if (other != null) {
4293                int otherIndex = mRecentTasks.indexOf(other);
4294                if (otherIndex >= 0) {
4295                    // Insert new task at appropriate location.
4296                    int taskIndex;
4297                    if (other == task.mNextAffiliate) {
4298                        // We found the index of our next affiliation, which is who is
4299                        // before us in the list, so add after that point.
4300                        taskIndex = otherIndex+1;
4301                    } else {
4302                        // We found the index of our previous affiliation, which is who is
4303                        // after us in the list, so add at their position.
4304                        taskIndex = otherIndex;
4305                    }
4306                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4307                            + taskIndex + ": " + task);
4308                    mRecentTasks.add(taskIndex, task);
4309
4310                    // Now move everything to the front.
4311                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4312                        // All went well.
4313                        return;
4314                    }
4315
4316                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4317                    // everything and then go through our general path of adding a new task.
4318                    needAffiliationFix = true;
4319                } else {
4320                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4321                            + other);
4322                    needAffiliationFix = true;
4323                }
4324            } else {
4325                if (DEBUG_RECENTS) Slog.d(TAG,
4326                        "addRecent: adding affiliated task without next/prev:" + task);
4327                needAffiliationFix = true;
4328            }
4329        }
4330        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4331
4332        if (needAffiliationFix) {
4333            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4334            cleanupRecentTasksLocked(task.userId);
4335        }
4336    }
4337
4338    /**
4339     * If needed, remove oldest existing entries in recents that are for the same kind
4340     * of task as the given one.
4341     */
4342    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4343        int N = mRecentTasks.size();
4344        final Intent intent = task.intent;
4345        final boolean document = intent != null && intent.isDocument();
4346
4347        int maxRecents = task.maxRecents - 1;
4348        for (int i=0; i<N; i++) {
4349            final TaskRecord tr = mRecentTasks.get(i);
4350            if (task != tr) {
4351                if (task.userId != tr.userId) {
4352                    continue;
4353                }
4354                if (i > MAX_RECENT_BITMAPS) {
4355                    tr.freeLastThumbnail();
4356                }
4357                final Intent trIntent = tr.intent;
4358                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4359                    (intent == null || !intent.filterEquals(trIntent))) {
4360                    continue;
4361                }
4362                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4363                if (document && trIsDocument) {
4364                    // These are the same document activity (not necessarily the same doc).
4365                    if (maxRecents > 0) {
4366                        --maxRecents;
4367                        continue;
4368                    }
4369                    // Hit the maximum number of documents for this task. Fall through
4370                    // and remove this document from recents.
4371                } else if (document || trIsDocument) {
4372                    // Only one of these is a document. Not the droid we're looking for.
4373                    continue;
4374                }
4375            }
4376
4377            if (!doTrim) {
4378                // If the caller is not actually asking for a trim, just tell them we reached
4379                // a point where the trim would happen.
4380                return i;
4381            }
4382
4383            // Either task and tr are the same or, their affinities match or their intents match
4384            // and neither of them is a document, or they are documents using the same activity
4385            // and their maxRecents has been reached.
4386            tr.disposeThumbnail();
4387            mRecentTasks.remove(i);
4388            if (task != tr) {
4389                tr.removedFromRecents(mTaskPersister);
4390            }
4391            i--;
4392            N--;
4393            if (task.intent == null) {
4394                // If the new recent task we are adding is not fully
4395                // specified, then replace it with the existing recent task.
4396                task = tr;
4397            }
4398            notifyTaskPersisterLocked(tr, false);
4399        }
4400
4401        return -1;
4402    }
4403
4404    @Override
4405    public void reportActivityFullyDrawn(IBinder token) {
4406        synchronized (this) {
4407            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4408            if (r == null) {
4409                return;
4410            }
4411            r.reportFullyDrawnLocked();
4412        }
4413    }
4414
4415    @Override
4416    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4417        synchronized (this) {
4418            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4419            if (r == null) {
4420                return;
4421            }
4422            final long origId = Binder.clearCallingIdentity();
4423            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4424            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4425                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4426            if (config != null) {
4427                r.frozenBeforeDestroy = true;
4428                if (!updateConfigurationLocked(config, r, false, false)) {
4429                    mStackSupervisor.resumeTopActivitiesLocked();
4430                }
4431            }
4432            Binder.restoreCallingIdentity(origId);
4433        }
4434    }
4435
4436    @Override
4437    public int getRequestedOrientation(IBinder token) {
4438        synchronized (this) {
4439            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4440            if (r == null) {
4441                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4442            }
4443            return mWindowManager.getAppOrientation(r.appToken);
4444        }
4445    }
4446
4447    /**
4448     * This is the internal entry point for handling Activity.finish().
4449     *
4450     * @param token The Binder token referencing the Activity we want to finish.
4451     * @param resultCode Result code, if any, from this Activity.
4452     * @param resultData Result data (Intent), if any, from this Activity.
4453     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4454     *            the root Activity in the task.
4455     *
4456     * @return Returns true if the activity successfully finished, or false if it is still running.
4457     */
4458    @Override
4459    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4460            boolean finishTask) {
4461        // Refuse possible leaked file descriptors
4462        if (resultData != null && resultData.hasFileDescriptors() == true) {
4463            throw new IllegalArgumentException("File descriptors passed in Intent");
4464        }
4465
4466        synchronized(this) {
4467            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4468            if (r == null) {
4469                return true;
4470            }
4471            // Keep track of the root activity of the task before we finish it
4472            TaskRecord tr = r.task;
4473            ActivityRecord rootR = tr.getRootActivity();
4474            // Do not allow task to finish in Lock Task mode.
4475            if (tr == mStackSupervisor.mLockTaskModeTask) {
4476                if (rootR == r) {
4477                    mStackSupervisor.showLockTaskToast();
4478                    return false;
4479                }
4480            }
4481            if (mController != null) {
4482                // Find the first activity that is not finishing.
4483                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4484                if (next != null) {
4485                    // ask watcher if this is allowed
4486                    boolean resumeOK = true;
4487                    try {
4488                        resumeOK = mController.activityResuming(next.packageName);
4489                    } catch (RemoteException e) {
4490                        mController = null;
4491                        Watchdog.getInstance().setActivityController(null);
4492                    }
4493
4494                    if (!resumeOK) {
4495                        return false;
4496                    }
4497                }
4498            }
4499            final long origId = Binder.clearCallingIdentity();
4500            try {
4501                boolean res;
4502                if (finishTask && r == rootR) {
4503                    // If requested, remove the task that is associated to this activity only if it
4504                    // was the root activity in the task.  The result code and data is ignored because
4505                    // we don't support returning them across task boundaries.
4506                    res = removeTaskByIdLocked(tr.taskId, 0);
4507                } else {
4508                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4509                            resultData, "app-request", true);
4510                }
4511                return res;
4512            } finally {
4513                Binder.restoreCallingIdentity(origId);
4514            }
4515        }
4516    }
4517
4518    @Override
4519    public final void finishHeavyWeightApp() {
4520        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4521                != PackageManager.PERMISSION_GRANTED) {
4522            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4523                    + Binder.getCallingPid()
4524                    + ", uid=" + Binder.getCallingUid()
4525                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4526            Slog.w(TAG, msg);
4527            throw new SecurityException(msg);
4528        }
4529
4530        synchronized(this) {
4531            if (mHeavyWeightProcess == null) {
4532                return;
4533            }
4534
4535            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4536                    mHeavyWeightProcess.activities);
4537            for (int i=0; i<activities.size(); i++) {
4538                ActivityRecord r = activities.get(i);
4539                if (!r.finishing) {
4540                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4541                            null, "finish-heavy", true);
4542                }
4543            }
4544
4545            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4546                    mHeavyWeightProcess.userId, 0));
4547            mHeavyWeightProcess = null;
4548        }
4549    }
4550
4551    @Override
4552    public void crashApplication(int uid, int initialPid, String packageName,
4553            String message) {
4554        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4555                != PackageManager.PERMISSION_GRANTED) {
4556            String msg = "Permission Denial: crashApplication() from pid="
4557                    + Binder.getCallingPid()
4558                    + ", uid=" + Binder.getCallingUid()
4559                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4560            Slog.w(TAG, msg);
4561            throw new SecurityException(msg);
4562        }
4563
4564        synchronized(this) {
4565            ProcessRecord proc = null;
4566
4567            // Figure out which process to kill.  We don't trust that initialPid
4568            // still has any relation to current pids, so must scan through the
4569            // list.
4570            synchronized (mPidsSelfLocked) {
4571                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4572                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4573                    if (p.uid != uid) {
4574                        continue;
4575                    }
4576                    if (p.pid == initialPid) {
4577                        proc = p;
4578                        break;
4579                    }
4580                    if (p.pkgList.containsKey(packageName)) {
4581                        proc = p;
4582                    }
4583                }
4584            }
4585
4586            if (proc == null) {
4587                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4588                        + " initialPid=" + initialPid
4589                        + " packageName=" + packageName);
4590                return;
4591            }
4592
4593            if (proc.thread != null) {
4594                if (proc.pid == Process.myPid()) {
4595                    Log.w(TAG, "crashApplication: trying to crash self!");
4596                    return;
4597                }
4598                long ident = Binder.clearCallingIdentity();
4599                try {
4600                    proc.thread.scheduleCrash(message);
4601                } catch (RemoteException e) {
4602                }
4603                Binder.restoreCallingIdentity(ident);
4604            }
4605        }
4606    }
4607
4608    @Override
4609    public final void finishSubActivity(IBinder token, String resultWho,
4610            int requestCode) {
4611        synchronized(this) {
4612            final long origId = Binder.clearCallingIdentity();
4613            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4614            if (r != null) {
4615                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4616            }
4617            Binder.restoreCallingIdentity(origId);
4618        }
4619    }
4620
4621    @Override
4622    public boolean finishActivityAffinity(IBinder token) {
4623        synchronized(this) {
4624            final long origId = Binder.clearCallingIdentity();
4625            try {
4626                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4627
4628                ActivityRecord rootR = r.task.getRootActivity();
4629                // Do not allow task to finish in Lock Task mode.
4630                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4631                    if (rootR == r) {
4632                        mStackSupervisor.showLockTaskToast();
4633                        return false;
4634                    }
4635                }
4636                boolean res = false;
4637                if (r != null) {
4638                    res = r.task.stack.finishActivityAffinityLocked(r);
4639                }
4640                return res;
4641            } finally {
4642                Binder.restoreCallingIdentity(origId);
4643            }
4644        }
4645    }
4646
4647    @Override
4648    public void finishVoiceTask(IVoiceInteractionSession session) {
4649        synchronized(this) {
4650            final long origId = Binder.clearCallingIdentity();
4651            try {
4652                mStackSupervisor.finishVoiceTask(session);
4653            } finally {
4654                Binder.restoreCallingIdentity(origId);
4655            }
4656        }
4657
4658    }
4659
4660    @Override
4661    public boolean releaseActivityInstance(IBinder token) {
4662        synchronized(this) {
4663            final long origId = Binder.clearCallingIdentity();
4664            try {
4665                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4666                if (r.task == null || r.task.stack == null) {
4667                    return false;
4668                }
4669                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4670            } finally {
4671                Binder.restoreCallingIdentity(origId);
4672            }
4673        }
4674    }
4675
4676    @Override
4677    public void releaseSomeActivities(IApplicationThread appInt) {
4678        synchronized(this) {
4679            final long origId = Binder.clearCallingIdentity();
4680            try {
4681                ProcessRecord app = getRecordForAppLocked(appInt);
4682                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4683            } finally {
4684                Binder.restoreCallingIdentity(origId);
4685            }
4686        }
4687    }
4688
4689    @Override
4690    public boolean willActivityBeVisible(IBinder token) {
4691        synchronized(this) {
4692            ActivityStack stack = ActivityRecord.getStackLocked(token);
4693            if (stack != null) {
4694                return stack.willActivityBeVisibleLocked(token);
4695            }
4696            return false;
4697        }
4698    }
4699
4700    @Override
4701    public void overridePendingTransition(IBinder token, String packageName,
4702            int enterAnim, int exitAnim) {
4703        synchronized(this) {
4704            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4705            if (self == null) {
4706                return;
4707            }
4708
4709            final long origId = Binder.clearCallingIdentity();
4710
4711            if (self.state == ActivityState.RESUMED
4712                    || self.state == ActivityState.PAUSING) {
4713                mWindowManager.overridePendingAppTransition(packageName,
4714                        enterAnim, exitAnim, null);
4715            }
4716
4717            Binder.restoreCallingIdentity(origId);
4718        }
4719    }
4720
4721    /**
4722     * Main function for removing an existing process from the activity manager
4723     * as a result of that process going away.  Clears out all connections
4724     * to the process.
4725     */
4726    private final void handleAppDiedLocked(ProcessRecord app,
4727            boolean restarting, boolean allowRestart) {
4728        int pid = app.pid;
4729        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4730        if (!kept && !restarting) {
4731            removeLruProcessLocked(app);
4732            if (pid > 0) {
4733                ProcessList.remove(pid);
4734            }
4735        }
4736
4737        if (mProfileProc == app) {
4738            clearProfilerLocked();
4739        }
4740
4741        // Remove this application's activities from active lists.
4742        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4743
4744        app.activities.clear();
4745
4746        if (app.instrumentationClass != null) {
4747            Slog.w(TAG, "Crash of app " + app.processName
4748                  + " running instrumentation " + app.instrumentationClass);
4749            Bundle info = new Bundle();
4750            info.putString("shortMsg", "Process crashed.");
4751            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4752        }
4753
4754        if (!restarting) {
4755            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4756                // If there was nothing to resume, and we are not already
4757                // restarting this process, but there is a visible activity that
4758                // is hosted by the process...  then make sure all visible
4759                // activities are running, taking care of restarting this
4760                // process.
4761                if (hasVisibleActivities) {
4762                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4763                }
4764            }
4765        }
4766    }
4767
4768    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4769        IBinder threadBinder = thread.asBinder();
4770        // Find the application record.
4771        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4772            ProcessRecord rec = mLruProcesses.get(i);
4773            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4774                return i;
4775            }
4776        }
4777        return -1;
4778    }
4779
4780    final ProcessRecord getRecordForAppLocked(
4781            IApplicationThread thread) {
4782        if (thread == null) {
4783            return null;
4784        }
4785
4786        int appIndex = getLRURecordIndexForAppLocked(thread);
4787        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4788    }
4789
4790    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4791        // If there are no longer any background processes running,
4792        // and the app that died was not running instrumentation,
4793        // then tell everyone we are now low on memory.
4794        boolean haveBg = false;
4795        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4796            ProcessRecord rec = mLruProcesses.get(i);
4797            if (rec.thread != null
4798                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4799                haveBg = true;
4800                break;
4801            }
4802        }
4803
4804        if (!haveBg) {
4805            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4806            if (doReport) {
4807                long now = SystemClock.uptimeMillis();
4808                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4809                    doReport = false;
4810                } else {
4811                    mLastMemUsageReportTime = now;
4812                }
4813            }
4814            final ArrayList<ProcessMemInfo> memInfos
4815                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4816            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4817            long now = SystemClock.uptimeMillis();
4818            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4819                ProcessRecord rec = mLruProcesses.get(i);
4820                if (rec == dyingProc || rec.thread == null) {
4821                    continue;
4822                }
4823                if (doReport) {
4824                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4825                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4826                }
4827                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4828                    // The low memory report is overriding any current
4829                    // state for a GC request.  Make sure to do
4830                    // heavy/important/visible/foreground processes first.
4831                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4832                        rec.lastRequestedGc = 0;
4833                    } else {
4834                        rec.lastRequestedGc = rec.lastLowMemory;
4835                    }
4836                    rec.reportLowMemory = true;
4837                    rec.lastLowMemory = now;
4838                    mProcessesToGc.remove(rec);
4839                    addProcessToGcListLocked(rec);
4840                }
4841            }
4842            if (doReport) {
4843                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4844                mHandler.sendMessage(msg);
4845            }
4846            scheduleAppGcsLocked();
4847        }
4848    }
4849
4850    final void appDiedLocked(ProcessRecord app) {
4851       appDiedLocked(app, app.pid, app.thread);
4852    }
4853
4854    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4855        // First check if this ProcessRecord is actually active for the pid.
4856        synchronized (mPidsSelfLocked) {
4857            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4858            if (curProc != app) {
4859                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4860                return;
4861            }
4862        }
4863
4864        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4865        synchronized (stats) {
4866            stats.noteProcessDiedLocked(app.info.uid, pid);
4867        }
4868
4869        Process.killProcessQuiet(pid);
4870        Process.killProcessGroup(app.info.uid, pid);
4871        app.killed = true;
4872
4873        // Clean up already done if the process has been re-started.
4874        if (app.pid == pid && app.thread != null &&
4875                app.thread.asBinder() == thread.asBinder()) {
4876            boolean doLowMem = app.instrumentationClass == null;
4877            boolean doOomAdj = doLowMem;
4878            if (!app.killedByAm) {
4879                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4880                        + ") has died");
4881                mAllowLowerMemLevel = true;
4882            } else {
4883                // Note that we always want to do oom adj to update our state with the
4884                // new number of procs.
4885                mAllowLowerMemLevel = false;
4886                doLowMem = false;
4887            }
4888            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4889            if (DEBUG_CLEANUP) Slog.v(
4890                TAG, "Dying app: " + app + ", pid: " + pid
4891                + ", thread: " + thread.asBinder());
4892            handleAppDiedLocked(app, false, true);
4893
4894            if (doOomAdj) {
4895                updateOomAdjLocked();
4896            }
4897            if (doLowMem) {
4898                doLowMemReportIfNeededLocked(app);
4899            }
4900        } else if (app.pid != pid) {
4901            // A new process has already been started.
4902            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4903                    + ") has died and restarted (pid " + app.pid + ").");
4904            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4905        } else if (DEBUG_PROCESSES) {
4906            Slog.d(TAG, "Received spurious death notification for thread "
4907                    + thread.asBinder());
4908        }
4909    }
4910
4911    /**
4912     * If a stack trace dump file is configured, dump process stack traces.
4913     * @param clearTraces causes the dump file to be erased prior to the new
4914     *    traces being written, if true; when false, the new traces will be
4915     *    appended to any existing file content.
4916     * @param firstPids of dalvik VM processes to dump stack traces for first
4917     * @param lastPids of dalvik VM processes to dump stack traces for last
4918     * @param nativeProcs optional list of native process names to dump stack crawls
4919     * @return file containing stack traces, or null if no dump file is configured
4920     */
4921    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4922            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4923        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4924        if (tracesPath == null || tracesPath.length() == 0) {
4925            return null;
4926        }
4927
4928        File tracesFile = new File(tracesPath);
4929        try {
4930            File tracesDir = tracesFile.getParentFile();
4931            if (!tracesDir.exists()) {
4932                tracesDir.mkdirs();
4933                if (!SELinux.restorecon(tracesDir)) {
4934                    return null;
4935                }
4936            }
4937            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4938
4939            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4940            tracesFile.createNewFile();
4941            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4942        } catch (IOException e) {
4943            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4944            return null;
4945        }
4946
4947        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4948        return tracesFile;
4949    }
4950
4951    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4952            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4953        // Use a FileObserver to detect when traces finish writing.
4954        // The order of traces is considered important to maintain for legibility.
4955        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4956            @Override
4957            public synchronized void onEvent(int event, String path) { notify(); }
4958        };
4959
4960        try {
4961            observer.startWatching();
4962
4963            // First collect all of the stacks of the most important pids.
4964            if (firstPids != null) {
4965                try {
4966                    int num = firstPids.size();
4967                    for (int i = 0; i < num; i++) {
4968                        synchronized (observer) {
4969                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4970                            observer.wait(200);  // Wait for write-close, give up after 200msec
4971                        }
4972                    }
4973                } catch (InterruptedException e) {
4974                    Slog.wtf(TAG, e);
4975                }
4976            }
4977
4978            // Next collect the stacks of the native pids
4979            if (nativeProcs != null) {
4980                int[] pids = Process.getPidsForCommands(nativeProcs);
4981                if (pids != null) {
4982                    for (int pid : pids) {
4983                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4984                    }
4985                }
4986            }
4987
4988            // Lastly, measure CPU usage.
4989            if (processCpuTracker != null) {
4990                processCpuTracker.init();
4991                System.gc();
4992                processCpuTracker.update();
4993                try {
4994                    synchronized (processCpuTracker) {
4995                        processCpuTracker.wait(500); // measure over 1/2 second.
4996                    }
4997                } catch (InterruptedException e) {
4998                }
4999                processCpuTracker.update();
5000
5001                // We'll take the stack crawls of just the top apps using CPU.
5002                final int N = processCpuTracker.countWorkingStats();
5003                int numProcs = 0;
5004                for (int i=0; i<N && numProcs<5; i++) {
5005                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5006                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5007                        numProcs++;
5008                        try {
5009                            synchronized (observer) {
5010                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5011                                observer.wait(200);  // Wait for write-close, give up after 200msec
5012                            }
5013                        } catch (InterruptedException e) {
5014                            Slog.wtf(TAG, e);
5015                        }
5016
5017                    }
5018                }
5019            }
5020        } finally {
5021            observer.stopWatching();
5022        }
5023    }
5024
5025    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5026        if (true || IS_USER_BUILD) {
5027            return;
5028        }
5029        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5030        if (tracesPath == null || tracesPath.length() == 0) {
5031            return;
5032        }
5033
5034        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5035        StrictMode.allowThreadDiskWrites();
5036        try {
5037            final File tracesFile = new File(tracesPath);
5038            final File tracesDir = tracesFile.getParentFile();
5039            final File tracesTmp = new File(tracesDir, "__tmp__");
5040            try {
5041                if (!tracesDir.exists()) {
5042                    tracesDir.mkdirs();
5043                    if (!SELinux.restorecon(tracesDir.getPath())) {
5044                        return;
5045                    }
5046                }
5047                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5048
5049                if (tracesFile.exists()) {
5050                    tracesTmp.delete();
5051                    tracesFile.renameTo(tracesTmp);
5052                }
5053                StringBuilder sb = new StringBuilder();
5054                Time tobj = new Time();
5055                tobj.set(System.currentTimeMillis());
5056                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5057                sb.append(": ");
5058                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5059                sb.append(" since ");
5060                sb.append(msg);
5061                FileOutputStream fos = new FileOutputStream(tracesFile);
5062                fos.write(sb.toString().getBytes());
5063                if (app == null) {
5064                    fos.write("\n*** No application process!".getBytes());
5065                }
5066                fos.close();
5067                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5068            } catch (IOException e) {
5069                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5070                return;
5071            }
5072
5073            if (app != null) {
5074                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5075                firstPids.add(app.pid);
5076                dumpStackTraces(tracesPath, firstPids, null, null, null);
5077            }
5078
5079            File lastTracesFile = null;
5080            File curTracesFile = null;
5081            for (int i=9; i>=0; i--) {
5082                String name = String.format(Locale.US, "slow%02d.txt", i);
5083                curTracesFile = new File(tracesDir, name);
5084                if (curTracesFile.exists()) {
5085                    if (lastTracesFile != null) {
5086                        curTracesFile.renameTo(lastTracesFile);
5087                    } else {
5088                        curTracesFile.delete();
5089                    }
5090                }
5091                lastTracesFile = curTracesFile;
5092            }
5093            tracesFile.renameTo(curTracesFile);
5094            if (tracesTmp.exists()) {
5095                tracesTmp.renameTo(tracesFile);
5096            }
5097        } finally {
5098            StrictMode.setThreadPolicy(oldPolicy);
5099        }
5100    }
5101
5102    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5103            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5104        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5105        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5106
5107        if (mController != null) {
5108            try {
5109                // 0 == continue, -1 = kill process immediately
5110                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5111                if (res < 0 && app.pid != MY_PID) {
5112                    app.kill("anr", true);
5113                }
5114            } catch (RemoteException e) {
5115                mController = null;
5116                Watchdog.getInstance().setActivityController(null);
5117            }
5118        }
5119
5120        long anrTime = SystemClock.uptimeMillis();
5121        if (MONITOR_CPU_USAGE) {
5122            updateCpuStatsNow();
5123        }
5124
5125        synchronized (this) {
5126            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5127            if (mShuttingDown) {
5128                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5129                return;
5130            } else if (app.notResponding) {
5131                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5132                return;
5133            } else if (app.crashing) {
5134                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5135                return;
5136            }
5137
5138            // In case we come through here for the same app before completing
5139            // this one, mark as anring now so we will bail out.
5140            app.notResponding = true;
5141
5142            // Log the ANR to the event log.
5143            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5144                    app.processName, app.info.flags, annotation);
5145
5146            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5147            firstPids.add(app.pid);
5148
5149            int parentPid = app.pid;
5150            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5151            if (parentPid != app.pid) firstPids.add(parentPid);
5152
5153            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5154
5155            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5156                ProcessRecord r = mLruProcesses.get(i);
5157                if (r != null && r.thread != null) {
5158                    int pid = r.pid;
5159                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5160                        if (r.persistent) {
5161                            firstPids.add(pid);
5162                        } else {
5163                            lastPids.put(pid, Boolean.TRUE);
5164                        }
5165                    }
5166                }
5167            }
5168        }
5169
5170        // Log the ANR to the main log.
5171        StringBuilder info = new StringBuilder();
5172        info.setLength(0);
5173        info.append("ANR in ").append(app.processName);
5174        if (activity != null && activity.shortComponentName != null) {
5175            info.append(" (").append(activity.shortComponentName).append(")");
5176        }
5177        info.append("\n");
5178        info.append("PID: ").append(app.pid).append("\n");
5179        if (annotation != null) {
5180            info.append("Reason: ").append(annotation).append("\n");
5181        }
5182        if (parent != null && parent != activity) {
5183            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5184        }
5185
5186        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5187
5188        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5189                NATIVE_STACKS_OF_INTEREST);
5190
5191        String cpuInfo = null;
5192        if (MONITOR_CPU_USAGE) {
5193            updateCpuStatsNow();
5194            synchronized (mProcessCpuTracker) {
5195                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5196            }
5197            info.append(processCpuTracker.printCurrentLoad());
5198            info.append(cpuInfo);
5199        }
5200
5201        info.append(processCpuTracker.printCurrentState(anrTime));
5202
5203        Slog.e(TAG, info.toString());
5204        if (tracesFile == null) {
5205            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5206            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5207        }
5208
5209        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5210                cpuInfo, tracesFile, null);
5211
5212        if (mController != null) {
5213            try {
5214                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5215                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5216                if (res != 0) {
5217                    if (res < 0 && app.pid != MY_PID) {
5218                        app.kill("anr", true);
5219                    } else {
5220                        synchronized (this) {
5221                            mServices.scheduleServiceTimeoutLocked(app);
5222                        }
5223                    }
5224                    return;
5225                }
5226            } catch (RemoteException e) {
5227                mController = null;
5228                Watchdog.getInstance().setActivityController(null);
5229            }
5230        }
5231
5232        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5233        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5234                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5235
5236        synchronized (this) {
5237            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5238                app.kill("bg anr", true);
5239                return;
5240            }
5241
5242            // Set the app's notResponding state, and look up the errorReportReceiver
5243            makeAppNotRespondingLocked(app,
5244                    activity != null ? activity.shortComponentName : null,
5245                    annotation != null ? "ANR " + annotation : "ANR",
5246                    info.toString());
5247
5248            // Bring up the infamous App Not Responding dialog
5249            Message msg = Message.obtain();
5250            HashMap<String, Object> map = new HashMap<String, Object>();
5251            msg.what = SHOW_NOT_RESPONDING_MSG;
5252            msg.obj = map;
5253            msg.arg1 = aboveSystem ? 1 : 0;
5254            map.put("app", app);
5255            if (activity != null) {
5256                map.put("activity", activity);
5257            }
5258
5259            mHandler.sendMessage(msg);
5260        }
5261    }
5262
5263    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5264        if (!mLaunchWarningShown) {
5265            mLaunchWarningShown = true;
5266            mHandler.post(new Runnable() {
5267                @Override
5268                public void run() {
5269                    synchronized (ActivityManagerService.this) {
5270                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5271                        d.show();
5272                        mHandler.postDelayed(new Runnable() {
5273                            @Override
5274                            public void run() {
5275                                synchronized (ActivityManagerService.this) {
5276                                    d.dismiss();
5277                                    mLaunchWarningShown = false;
5278                                }
5279                            }
5280                        }, 4000);
5281                    }
5282                }
5283            });
5284        }
5285    }
5286
5287    @Override
5288    public boolean clearApplicationUserData(final String packageName,
5289            final IPackageDataObserver observer, int userId) {
5290        enforceNotIsolatedCaller("clearApplicationUserData");
5291        int uid = Binder.getCallingUid();
5292        int pid = Binder.getCallingPid();
5293        userId = handleIncomingUser(pid, uid,
5294                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5295        long callingId = Binder.clearCallingIdentity();
5296        try {
5297            IPackageManager pm = AppGlobals.getPackageManager();
5298            int pkgUid = -1;
5299            synchronized(this) {
5300                try {
5301                    pkgUid = pm.getPackageUid(packageName, userId);
5302                } catch (RemoteException e) {
5303                }
5304                if (pkgUid == -1) {
5305                    Slog.w(TAG, "Invalid packageName: " + packageName);
5306                    if (observer != null) {
5307                        try {
5308                            observer.onRemoveCompleted(packageName, false);
5309                        } catch (RemoteException e) {
5310                            Slog.i(TAG, "Observer no longer exists.");
5311                        }
5312                    }
5313                    return false;
5314                }
5315                if (uid == pkgUid || checkComponentPermission(
5316                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5317                        pid, uid, -1, true)
5318                        == PackageManager.PERMISSION_GRANTED) {
5319                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5320                } else {
5321                    throw new SecurityException("PID " + pid + " does not have permission "
5322                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5323                                    + " of package " + packageName);
5324                }
5325
5326                // Remove all tasks match the cleared application package and user
5327                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5328                    final TaskRecord tr = mRecentTasks.get(i);
5329                    final String taskPackageName =
5330                            tr.getBaseIntent().getComponent().getPackageName();
5331                    if (tr.userId != userId) continue;
5332                    if (!taskPackageName.equals(packageName)) continue;
5333                    removeTaskByIdLocked(tr.taskId, 0);
5334                }
5335            }
5336
5337            try {
5338                // Clear application user data
5339                pm.clearApplicationUserData(packageName, observer, userId);
5340
5341                synchronized(this) {
5342                    // Remove all permissions granted from/to this package
5343                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5344                }
5345
5346                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5347                        Uri.fromParts("package", packageName, null));
5348                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5349                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5350                        null, null, 0, null, null, null, false, false, userId);
5351            } catch (RemoteException e) {
5352            }
5353        } finally {
5354            Binder.restoreCallingIdentity(callingId);
5355        }
5356        return true;
5357    }
5358
5359    @Override
5360    public void killBackgroundProcesses(final String packageName, int userId) {
5361        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5362                != PackageManager.PERMISSION_GRANTED &&
5363                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5364                        != PackageManager.PERMISSION_GRANTED) {
5365            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5366                    + Binder.getCallingPid()
5367                    + ", uid=" + Binder.getCallingUid()
5368                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5369            Slog.w(TAG, msg);
5370            throw new SecurityException(msg);
5371        }
5372
5373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5374                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5375        long callingId = Binder.clearCallingIdentity();
5376        try {
5377            IPackageManager pm = AppGlobals.getPackageManager();
5378            synchronized(this) {
5379                int appId = -1;
5380                try {
5381                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5382                } catch (RemoteException e) {
5383                }
5384                if (appId == -1) {
5385                    Slog.w(TAG, "Invalid packageName: " + packageName);
5386                    return;
5387                }
5388                killPackageProcessesLocked(packageName, appId, userId,
5389                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5390            }
5391        } finally {
5392            Binder.restoreCallingIdentity(callingId);
5393        }
5394    }
5395
5396    @Override
5397    public void killAllBackgroundProcesses() {
5398        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5399                != PackageManager.PERMISSION_GRANTED) {
5400            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5401                    + Binder.getCallingPid()
5402                    + ", uid=" + Binder.getCallingUid()
5403                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5404            Slog.w(TAG, msg);
5405            throw new SecurityException(msg);
5406        }
5407
5408        long callingId = Binder.clearCallingIdentity();
5409        try {
5410            synchronized(this) {
5411                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5412                final int NP = mProcessNames.getMap().size();
5413                for (int ip=0; ip<NP; ip++) {
5414                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5415                    final int NA = apps.size();
5416                    for (int ia=0; ia<NA; ia++) {
5417                        ProcessRecord app = apps.valueAt(ia);
5418                        if (app.persistent) {
5419                            // we don't kill persistent processes
5420                            continue;
5421                        }
5422                        if (app.removed) {
5423                            procs.add(app);
5424                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5425                            app.removed = true;
5426                            procs.add(app);
5427                        }
5428                    }
5429                }
5430
5431                int N = procs.size();
5432                for (int i=0; i<N; i++) {
5433                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5434                }
5435                mAllowLowerMemLevel = true;
5436                updateOomAdjLocked();
5437                doLowMemReportIfNeededLocked(null);
5438            }
5439        } finally {
5440            Binder.restoreCallingIdentity(callingId);
5441        }
5442    }
5443
5444    @Override
5445    public void forceStopPackage(final String packageName, int userId) {
5446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5447                != PackageManager.PERMISSION_GRANTED) {
5448            String msg = "Permission Denial: forceStopPackage() from pid="
5449                    + Binder.getCallingPid()
5450                    + ", uid=" + Binder.getCallingUid()
5451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5452            Slog.w(TAG, msg);
5453            throw new SecurityException(msg);
5454        }
5455        final int callingPid = Binder.getCallingPid();
5456        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5457                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5458        long callingId = Binder.clearCallingIdentity();
5459        try {
5460            IPackageManager pm = AppGlobals.getPackageManager();
5461            synchronized(this) {
5462                int[] users = userId == UserHandle.USER_ALL
5463                        ? getUsersLocked() : new int[] { userId };
5464                for (int user : users) {
5465                    int pkgUid = -1;
5466                    try {
5467                        pkgUid = pm.getPackageUid(packageName, user);
5468                    } catch (RemoteException e) {
5469                    }
5470                    if (pkgUid == -1) {
5471                        Slog.w(TAG, "Invalid packageName: " + packageName);
5472                        continue;
5473                    }
5474                    try {
5475                        pm.setPackageStoppedState(packageName, true, user);
5476                    } catch (RemoteException e) {
5477                    } catch (IllegalArgumentException e) {
5478                        Slog.w(TAG, "Failed trying to unstop package "
5479                                + packageName + ": " + e);
5480                    }
5481                    if (isUserRunningLocked(user, false)) {
5482                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5483                    }
5484                }
5485            }
5486        } finally {
5487            Binder.restoreCallingIdentity(callingId);
5488        }
5489    }
5490
5491    @Override
5492    public void addPackageDependency(String packageName) {
5493        synchronized (this) {
5494            int callingPid = Binder.getCallingPid();
5495            if (callingPid == Process.myPid()) {
5496                //  Yeah, um, no.
5497                Slog.w(TAG, "Can't addPackageDependency on system process");
5498                return;
5499            }
5500            ProcessRecord proc;
5501            synchronized (mPidsSelfLocked) {
5502                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5503            }
5504            if (proc != null) {
5505                if (proc.pkgDeps == null) {
5506                    proc.pkgDeps = new ArraySet<String>(1);
5507                }
5508                proc.pkgDeps.add(packageName);
5509            }
5510        }
5511    }
5512
5513    /*
5514     * The pkg name and app id have to be specified.
5515     */
5516    @Override
5517    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5518        if (pkg == null) {
5519            return;
5520        }
5521        // Make sure the uid is valid.
5522        if (appid < 0) {
5523            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5524            return;
5525        }
5526        int callerUid = Binder.getCallingUid();
5527        // Only the system server can kill an application
5528        if (callerUid == Process.SYSTEM_UID) {
5529            // Post an aysnc message to kill the application
5530            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5531            msg.arg1 = appid;
5532            msg.arg2 = 0;
5533            Bundle bundle = new Bundle();
5534            bundle.putString("pkg", pkg);
5535            bundle.putString("reason", reason);
5536            msg.obj = bundle;
5537            mHandler.sendMessage(msg);
5538        } else {
5539            throw new SecurityException(callerUid + " cannot kill pkg: " +
5540                    pkg);
5541        }
5542    }
5543
5544    @Override
5545    public void closeSystemDialogs(String reason) {
5546        enforceNotIsolatedCaller("closeSystemDialogs");
5547
5548        final int pid = Binder.getCallingPid();
5549        final int uid = Binder.getCallingUid();
5550        final long origId = Binder.clearCallingIdentity();
5551        try {
5552            synchronized (this) {
5553                // Only allow this from foreground processes, so that background
5554                // applications can't abuse it to prevent system UI from being shown.
5555                if (uid >= Process.FIRST_APPLICATION_UID) {
5556                    ProcessRecord proc;
5557                    synchronized (mPidsSelfLocked) {
5558                        proc = mPidsSelfLocked.get(pid);
5559                    }
5560                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5561                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5562                                + " from background process " + proc);
5563                        return;
5564                    }
5565                }
5566                closeSystemDialogsLocked(reason);
5567            }
5568        } finally {
5569            Binder.restoreCallingIdentity(origId);
5570        }
5571    }
5572
5573    void closeSystemDialogsLocked(String reason) {
5574        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5575        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5576                | Intent.FLAG_RECEIVER_FOREGROUND);
5577        if (reason != null) {
5578            intent.putExtra("reason", reason);
5579        }
5580        mWindowManager.closeSystemDialogs(reason);
5581
5582        mStackSupervisor.closeSystemDialogsLocked();
5583
5584        broadcastIntentLocked(null, null, intent, null,
5585                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5586                Process.SYSTEM_UID, UserHandle.USER_ALL);
5587    }
5588
5589    @Override
5590    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5591        enforceNotIsolatedCaller("getProcessMemoryInfo");
5592        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5593        for (int i=pids.length-1; i>=0; i--) {
5594            ProcessRecord proc;
5595            int oomAdj;
5596            synchronized (this) {
5597                synchronized (mPidsSelfLocked) {
5598                    proc = mPidsSelfLocked.get(pids[i]);
5599                    oomAdj = proc != null ? proc.setAdj : 0;
5600                }
5601            }
5602            infos[i] = new Debug.MemoryInfo();
5603            Debug.getMemoryInfo(pids[i], infos[i]);
5604            if (proc != null) {
5605                synchronized (this) {
5606                    if (proc.thread != null && proc.setAdj == oomAdj) {
5607                        // Record this for posterity if the process has been stable.
5608                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5609                                infos[i].getTotalUss(), false, proc.pkgList);
5610                    }
5611                }
5612            }
5613        }
5614        return infos;
5615    }
5616
5617    @Override
5618    public long[] getProcessPss(int[] pids) {
5619        enforceNotIsolatedCaller("getProcessPss");
5620        long[] pss = new long[pids.length];
5621        for (int i=pids.length-1; i>=0; i--) {
5622            ProcessRecord proc;
5623            int oomAdj;
5624            synchronized (this) {
5625                synchronized (mPidsSelfLocked) {
5626                    proc = mPidsSelfLocked.get(pids[i]);
5627                    oomAdj = proc != null ? proc.setAdj : 0;
5628                }
5629            }
5630            long[] tmpUss = new long[1];
5631            pss[i] = Debug.getPss(pids[i], tmpUss);
5632            if (proc != null) {
5633                synchronized (this) {
5634                    if (proc.thread != null && proc.setAdj == oomAdj) {
5635                        // Record this for posterity if the process has been stable.
5636                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5637                    }
5638                }
5639            }
5640        }
5641        return pss;
5642    }
5643
5644    @Override
5645    public void killApplicationProcess(String processName, int uid) {
5646        if (processName == null) {
5647            return;
5648        }
5649
5650        int callerUid = Binder.getCallingUid();
5651        // Only the system server can kill an application
5652        if (callerUid == Process.SYSTEM_UID) {
5653            synchronized (this) {
5654                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5655                if (app != null && app.thread != null) {
5656                    try {
5657                        app.thread.scheduleSuicide();
5658                    } catch (RemoteException e) {
5659                        // If the other end already died, then our work here is done.
5660                    }
5661                } else {
5662                    Slog.w(TAG, "Process/uid not found attempting kill of "
5663                            + processName + " / " + uid);
5664                }
5665            }
5666        } else {
5667            throw new SecurityException(callerUid + " cannot kill app process: " +
5668                    processName);
5669        }
5670    }
5671
5672    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5673        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5674                false, true, false, false, UserHandle.getUserId(uid), reason);
5675        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5676                Uri.fromParts("package", packageName, null));
5677        if (!mProcessesReady) {
5678            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5679                    | Intent.FLAG_RECEIVER_FOREGROUND);
5680        }
5681        intent.putExtra(Intent.EXTRA_UID, uid);
5682        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5683        broadcastIntentLocked(null, null, intent,
5684                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5685                false, false,
5686                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5687    }
5688
5689    private void forceStopUserLocked(int userId, String reason) {
5690        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5691        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5692        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5693                | Intent.FLAG_RECEIVER_FOREGROUND);
5694        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5695        broadcastIntentLocked(null, null, intent,
5696                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5697                false, false,
5698                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5699    }
5700
5701    private final boolean killPackageProcessesLocked(String packageName, int appId,
5702            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5703            boolean doit, boolean evenPersistent, String reason) {
5704        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5705
5706        // Remove all processes this package may have touched: all with the
5707        // same UID (except for the system or root user), and all whose name
5708        // matches the package name.
5709        final int NP = mProcessNames.getMap().size();
5710        for (int ip=0; ip<NP; ip++) {
5711            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5712            final int NA = apps.size();
5713            for (int ia=0; ia<NA; ia++) {
5714                ProcessRecord app = apps.valueAt(ia);
5715                if (app.persistent && !evenPersistent) {
5716                    // we don't kill persistent processes
5717                    continue;
5718                }
5719                if (app.removed) {
5720                    if (doit) {
5721                        procs.add(app);
5722                    }
5723                    continue;
5724                }
5725
5726                // Skip process if it doesn't meet our oom adj requirement.
5727                if (app.setAdj < minOomAdj) {
5728                    continue;
5729                }
5730
5731                // If no package is specified, we call all processes under the
5732                // give user id.
5733                if (packageName == null) {
5734                    if (app.userId != userId) {
5735                        continue;
5736                    }
5737                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5738                        continue;
5739                    }
5740                // Package has been specified, we want to hit all processes
5741                // that match it.  We need to qualify this by the processes
5742                // that are running under the specified app and user ID.
5743                } else {
5744                    final boolean isDep = app.pkgDeps != null
5745                            && app.pkgDeps.contains(packageName);
5746                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5747                        continue;
5748                    }
5749                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5750                        continue;
5751                    }
5752                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5753                        continue;
5754                    }
5755                }
5756
5757                // Process has passed all conditions, kill it!
5758                if (!doit) {
5759                    return true;
5760                }
5761                app.removed = true;
5762                procs.add(app);
5763            }
5764        }
5765
5766        int N = procs.size();
5767        for (int i=0; i<N; i++) {
5768            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5769        }
5770        updateOomAdjLocked();
5771        return N > 0;
5772    }
5773
5774    private final boolean forceStopPackageLocked(String name, int appId,
5775            boolean callerWillRestart, boolean purgeCache, boolean doit,
5776            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5777        int i;
5778        int N;
5779
5780        if (userId == UserHandle.USER_ALL && name == null) {
5781            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5782        }
5783
5784        if (appId < 0 && name != null) {
5785            try {
5786                appId = UserHandle.getAppId(
5787                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5788            } catch (RemoteException e) {
5789            }
5790        }
5791
5792        if (doit) {
5793            if (name != null) {
5794                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5795                        + " user=" + userId + ": " + reason);
5796            } else {
5797                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5798            }
5799
5800            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5801            for (int ip=pmap.size()-1; ip>=0; ip--) {
5802                SparseArray<Long> ba = pmap.valueAt(ip);
5803                for (i=ba.size()-1; i>=0; i--) {
5804                    boolean remove = false;
5805                    final int entUid = ba.keyAt(i);
5806                    if (name != null) {
5807                        if (userId == UserHandle.USER_ALL) {
5808                            if (UserHandle.getAppId(entUid) == appId) {
5809                                remove = true;
5810                            }
5811                        } else {
5812                            if (entUid == UserHandle.getUid(userId, appId)) {
5813                                remove = true;
5814                            }
5815                        }
5816                    } else if (UserHandle.getUserId(entUid) == userId) {
5817                        remove = true;
5818                    }
5819                    if (remove) {
5820                        ba.removeAt(i);
5821                    }
5822                }
5823                if (ba.size() == 0) {
5824                    pmap.removeAt(ip);
5825                }
5826            }
5827        }
5828
5829        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5830                -100, callerWillRestart, true, doit, evenPersistent,
5831                name == null ? ("stop user " + userId) : ("stop " + name));
5832
5833        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5834            if (!doit) {
5835                return true;
5836            }
5837            didSomething = true;
5838        }
5839
5840        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5841            if (!doit) {
5842                return true;
5843            }
5844            didSomething = true;
5845        }
5846
5847        if (name == null) {
5848            // Remove all sticky broadcasts from this user.
5849            mStickyBroadcasts.remove(userId);
5850        }
5851
5852        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5853        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5854                userId, providers)) {
5855            if (!doit) {
5856                return true;
5857            }
5858            didSomething = true;
5859        }
5860        N = providers.size();
5861        for (i=0; i<N; i++) {
5862            removeDyingProviderLocked(null, providers.get(i), true);
5863        }
5864
5865        // Remove transient permissions granted from/to this package/user
5866        removeUriPermissionsForPackageLocked(name, userId, false);
5867
5868        if (name == null || uninstalling) {
5869            // Remove pending intents.  For now we only do this when force
5870            // stopping users, because we have some problems when doing this
5871            // for packages -- app widgets are not currently cleaned up for
5872            // such packages, so they can be left with bad pending intents.
5873            if (mIntentSenderRecords.size() > 0) {
5874                Iterator<WeakReference<PendingIntentRecord>> it
5875                        = mIntentSenderRecords.values().iterator();
5876                while (it.hasNext()) {
5877                    WeakReference<PendingIntentRecord> wpir = it.next();
5878                    if (wpir == null) {
5879                        it.remove();
5880                        continue;
5881                    }
5882                    PendingIntentRecord pir = wpir.get();
5883                    if (pir == null) {
5884                        it.remove();
5885                        continue;
5886                    }
5887                    if (name == null) {
5888                        // Stopping user, remove all objects for the user.
5889                        if (pir.key.userId != userId) {
5890                            // Not the same user, skip it.
5891                            continue;
5892                        }
5893                    } else {
5894                        if (UserHandle.getAppId(pir.uid) != appId) {
5895                            // Different app id, skip it.
5896                            continue;
5897                        }
5898                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5899                            // Different user, skip it.
5900                            continue;
5901                        }
5902                        if (!pir.key.packageName.equals(name)) {
5903                            // Different package, skip it.
5904                            continue;
5905                        }
5906                    }
5907                    if (!doit) {
5908                        return true;
5909                    }
5910                    didSomething = true;
5911                    it.remove();
5912                    pir.canceled = true;
5913                    if (pir.key.activity != null) {
5914                        pir.key.activity.pendingResults.remove(pir.ref);
5915                    }
5916                }
5917            }
5918        }
5919
5920        if (doit) {
5921            if (purgeCache && name != null) {
5922                AttributeCache ac = AttributeCache.instance();
5923                if (ac != null) {
5924                    ac.removePackage(name);
5925                }
5926            }
5927            if (mBooted) {
5928                mStackSupervisor.resumeTopActivitiesLocked();
5929                mStackSupervisor.scheduleIdleLocked();
5930            }
5931        }
5932
5933        return didSomething;
5934    }
5935
5936    private final boolean removeProcessLocked(ProcessRecord app,
5937            boolean callerWillRestart, boolean allowRestart, String reason) {
5938        final String name = app.processName;
5939        final int uid = app.uid;
5940        if (DEBUG_PROCESSES) Slog.d(
5941            TAG, "Force removing proc " + app.toShortString() + " (" + name
5942            + "/" + uid + ")");
5943
5944        mProcessNames.remove(name, uid);
5945        mIsolatedProcesses.remove(app.uid);
5946        if (mHeavyWeightProcess == app) {
5947            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5948                    mHeavyWeightProcess.userId, 0));
5949            mHeavyWeightProcess = null;
5950        }
5951        boolean needRestart = false;
5952        if (app.pid > 0 && app.pid != MY_PID) {
5953            int pid = app.pid;
5954            synchronized (mPidsSelfLocked) {
5955                mPidsSelfLocked.remove(pid);
5956                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5957            }
5958            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5959            if (app.isolated) {
5960                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5961            }
5962            app.kill(reason, true);
5963            handleAppDiedLocked(app, true, allowRestart);
5964            removeLruProcessLocked(app);
5965
5966            if (app.persistent && !app.isolated) {
5967                if (!callerWillRestart) {
5968                    addAppLocked(app.info, false, null /* ABI override */);
5969                } else {
5970                    needRestart = true;
5971                }
5972            }
5973        } else {
5974            mRemovedProcesses.add(app);
5975        }
5976
5977        return needRestart;
5978    }
5979
5980    private final void processStartTimedOutLocked(ProcessRecord app) {
5981        final int pid = app.pid;
5982        boolean gone = false;
5983        synchronized (mPidsSelfLocked) {
5984            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5985            if (knownApp != null && knownApp.thread == null) {
5986                mPidsSelfLocked.remove(pid);
5987                gone = true;
5988            }
5989        }
5990
5991        if (gone) {
5992            Slog.w(TAG, "Process " + app + " failed to attach");
5993            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5994                    pid, app.uid, app.processName);
5995            mProcessNames.remove(app.processName, app.uid);
5996            mIsolatedProcesses.remove(app.uid);
5997            if (mHeavyWeightProcess == app) {
5998                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5999                        mHeavyWeightProcess.userId, 0));
6000                mHeavyWeightProcess = null;
6001            }
6002            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6003            if (app.isolated) {
6004                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6005            }
6006            // Take care of any launching providers waiting for this process.
6007            checkAppInLaunchingProvidersLocked(app, true);
6008            // Take care of any services that are waiting for the process.
6009            mServices.processStartTimedOutLocked(app);
6010            app.kill("start timeout", true);
6011            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6012                Slog.w(TAG, "Unattached app died before backup, skipping");
6013                try {
6014                    IBackupManager bm = IBackupManager.Stub.asInterface(
6015                            ServiceManager.getService(Context.BACKUP_SERVICE));
6016                    bm.agentDisconnected(app.info.packageName);
6017                } catch (RemoteException e) {
6018                    // Can't happen; the backup manager is local
6019                }
6020            }
6021            if (isPendingBroadcastProcessLocked(pid)) {
6022                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6023                skipPendingBroadcastLocked(pid);
6024            }
6025        } else {
6026            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6027        }
6028    }
6029
6030    private final boolean attachApplicationLocked(IApplicationThread thread,
6031            int pid) {
6032
6033        // Find the application record that is being attached...  either via
6034        // the pid if we are running in multiple processes, or just pull the
6035        // next app record if we are emulating process with anonymous threads.
6036        ProcessRecord app;
6037        if (pid != MY_PID && pid >= 0) {
6038            synchronized (mPidsSelfLocked) {
6039                app = mPidsSelfLocked.get(pid);
6040            }
6041        } else {
6042            app = null;
6043        }
6044
6045        if (app == null) {
6046            Slog.w(TAG, "No pending application record for pid " + pid
6047                    + " (IApplicationThread " + thread + "); dropping process");
6048            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6049            if (pid > 0 && pid != MY_PID) {
6050                Process.killProcessQuiet(pid);
6051                //TODO: Process.killProcessGroup(app.info.uid, pid);
6052            } else {
6053                try {
6054                    thread.scheduleExit();
6055                } catch (Exception e) {
6056                    // Ignore exceptions.
6057                }
6058            }
6059            return false;
6060        }
6061
6062        // If this application record is still attached to a previous
6063        // process, clean it up now.
6064        if (app.thread != null) {
6065            handleAppDiedLocked(app, true, true);
6066        }
6067
6068        // Tell the process all about itself.
6069
6070        if (localLOGV) Slog.v(
6071                TAG, "Binding process pid " + pid + " to record " + app);
6072
6073        final String processName = app.processName;
6074        try {
6075            AppDeathRecipient adr = new AppDeathRecipient(
6076                    app, pid, thread);
6077            thread.asBinder().linkToDeath(adr, 0);
6078            app.deathRecipient = adr;
6079        } catch (RemoteException e) {
6080            app.resetPackageList(mProcessStats);
6081            startProcessLocked(app, "link fail", processName);
6082            return false;
6083        }
6084
6085        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6086
6087        app.makeActive(thread, mProcessStats);
6088        app.curAdj = app.setAdj = -100;
6089        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6090        app.forcingToForeground = null;
6091        updateProcessForegroundLocked(app, false, false);
6092        app.hasShownUi = false;
6093        app.debugging = false;
6094        app.cached = false;
6095
6096        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6097
6098        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6099        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6100
6101        if (!normalMode) {
6102            Slog.i(TAG, "Launching preboot mode app: " + app);
6103        }
6104
6105        if (localLOGV) Slog.v(
6106            TAG, "New app record " + app
6107            + " thread=" + thread.asBinder() + " pid=" + pid);
6108        try {
6109            int testMode = IApplicationThread.DEBUG_OFF;
6110            if (mDebugApp != null && mDebugApp.equals(processName)) {
6111                testMode = mWaitForDebugger
6112                    ? IApplicationThread.DEBUG_WAIT
6113                    : IApplicationThread.DEBUG_ON;
6114                app.debugging = true;
6115                if (mDebugTransient) {
6116                    mDebugApp = mOrigDebugApp;
6117                    mWaitForDebugger = mOrigWaitForDebugger;
6118                }
6119            }
6120            String profileFile = app.instrumentationProfileFile;
6121            ParcelFileDescriptor profileFd = null;
6122            int samplingInterval = 0;
6123            boolean profileAutoStop = false;
6124            if (mProfileApp != null && mProfileApp.equals(processName)) {
6125                mProfileProc = app;
6126                profileFile = mProfileFile;
6127                profileFd = mProfileFd;
6128                samplingInterval = mSamplingInterval;
6129                profileAutoStop = mAutoStopProfiler;
6130            }
6131            boolean enableOpenGlTrace = false;
6132            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6133                enableOpenGlTrace = true;
6134                mOpenGlTraceApp = null;
6135            }
6136
6137            // If the app is being launched for restore or full backup, set it up specially
6138            boolean isRestrictedBackupMode = false;
6139            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6140                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6141                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6142                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6143            }
6144
6145            ensurePackageDexOpt(app.instrumentationInfo != null
6146                    ? app.instrumentationInfo.packageName
6147                    : app.info.packageName);
6148            if (app.instrumentationClass != null) {
6149                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6150            }
6151            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6152                    + processName + " with config " + mConfiguration);
6153            ApplicationInfo appInfo = app.instrumentationInfo != null
6154                    ? app.instrumentationInfo : app.info;
6155            app.compat = compatibilityInfoForPackageLocked(appInfo);
6156            if (profileFd != null) {
6157                profileFd = profileFd.dup();
6158            }
6159            ProfilerInfo profilerInfo = profileFile == null ? null
6160                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6161            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6162                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6163                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6164                    isRestrictedBackupMode || !normalMode, app.persistent,
6165                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6166                    mCoreSettingsObserver.getCoreSettingsLocked());
6167            updateLruProcessLocked(app, false, null);
6168            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6169        } catch (Exception e) {
6170            // todo: Yikes!  What should we do?  For now we will try to
6171            // start another process, but that could easily get us in
6172            // an infinite loop of restarting processes...
6173            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6174
6175            app.resetPackageList(mProcessStats);
6176            app.unlinkDeathRecipient();
6177            startProcessLocked(app, "bind fail", processName);
6178            return false;
6179        }
6180
6181        // Remove this record from the list of starting applications.
6182        mPersistentStartingProcesses.remove(app);
6183        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6184                "Attach application locked removing on hold: " + app);
6185        mProcessesOnHold.remove(app);
6186
6187        boolean badApp = false;
6188        boolean didSomething = false;
6189
6190        // See if the top visible activity is waiting to run in this process...
6191        if (normalMode) {
6192            try {
6193                if (mStackSupervisor.attachApplicationLocked(app)) {
6194                    didSomething = true;
6195                }
6196            } catch (Exception e) {
6197                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6198                badApp = true;
6199            }
6200        }
6201
6202        // Find any services that should be running in this process...
6203        if (!badApp) {
6204            try {
6205                didSomething |= mServices.attachApplicationLocked(app, processName);
6206            } catch (Exception e) {
6207                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6208                badApp = true;
6209            }
6210        }
6211
6212        // Check if a next-broadcast receiver is in this process...
6213        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6214            try {
6215                didSomething |= sendPendingBroadcastsLocked(app);
6216            } catch (Exception e) {
6217                // If the app died trying to launch the receiver we declare it 'bad'
6218                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6219                badApp = true;
6220            }
6221        }
6222
6223        // Check whether the next backup agent is in this process...
6224        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6225            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6226            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6227            try {
6228                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6229                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6230                        mBackupTarget.backupMode);
6231            } catch (Exception e) {
6232                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6233                badApp = true;
6234            }
6235        }
6236
6237        if (badApp) {
6238            app.kill("error during init", true);
6239            handleAppDiedLocked(app, false, true);
6240            return false;
6241        }
6242
6243        if (!didSomething) {
6244            updateOomAdjLocked();
6245        }
6246
6247        return true;
6248    }
6249
6250    @Override
6251    public final void attachApplication(IApplicationThread thread) {
6252        synchronized (this) {
6253            int callingPid = Binder.getCallingPid();
6254            final long origId = Binder.clearCallingIdentity();
6255            attachApplicationLocked(thread, callingPid);
6256            Binder.restoreCallingIdentity(origId);
6257        }
6258    }
6259
6260    @Override
6261    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6262        final long origId = Binder.clearCallingIdentity();
6263        synchronized (this) {
6264            ActivityStack stack = ActivityRecord.getStackLocked(token);
6265            if (stack != null) {
6266                ActivityRecord r =
6267                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6268                if (stopProfiling) {
6269                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6270                        try {
6271                            mProfileFd.close();
6272                        } catch (IOException e) {
6273                        }
6274                        clearProfilerLocked();
6275                    }
6276                }
6277            }
6278        }
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6283        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6284                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6285    }
6286
6287    void enableScreenAfterBoot() {
6288        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6289                SystemClock.uptimeMillis());
6290        mWindowManager.enableScreenAfterBoot();
6291
6292        synchronized (this) {
6293            updateEventDispatchingLocked();
6294        }
6295    }
6296
6297    @Override
6298    public void showBootMessage(final CharSequence msg, final boolean always) {
6299        enforceNotIsolatedCaller("showBootMessage");
6300        mWindowManager.showBootMessage(msg, always);
6301    }
6302
6303    @Override
6304    public void keyguardWaitingForActivityDrawn() {
6305        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6306        final long token = Binder.clearCallingIdentity();
6307        try {
6308            synchronized (this) {
6309                if (DEBUG_LOCKSCREEN) logLockScreen("");
6310                mWindowManager.keyguardWaitingForActivityDrawn();
6311                if (mLockScreenShown) {
6312                    mLockScreenShown = false;
6313                    updateSleepIfNeededLocked();
6314                }
6315            }
6316        } finally {
6317            Binder.restoreCallingIdentity(token);
6318        }
6319    }
6320
6321    final void finishBooting() {
6322        synchronized (this) {
6323            if (!mBootAnimationComplete) {
6324                mCallFinishBooting = true;
6325                return;
6326            }
6327            mCallFinishBooting = false;
6328        }
6329
6330        // Register receivers to handle package update events
6331        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6332
6333        // Let system services know.
6334        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6335
6336        synchronized (this) {
6337            // Ensure that any processes we had put on hold are now started
6338            // up.
6339            final int NP = mProcessesOnHold.size();
6340            if (NP > 0) {
6341                ArrayList<ProcessRecord> procs =
6342                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6343                for (int ip=0; ip<NP; ip++) {
6344                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6345                            + procs.get(ip));
6346                    startProcessLocked(procs.get(ip), "on-hold", null);
6347                }
6348            }
6349
6350            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6351                // Start looking for apps that are abusing wake locks.
6352                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6353                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6354                // Tell anyone interested that we are done booting!
6355                SystemProperties.set("sys.boot_completed", "1");
6356
6357                // And trigger dev.bootcomplete if we are not showing encryption progress
6358                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6359                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6360                    SystemProperties.set("dev.bootcomplete", "1");
6361                }
6362                for (int i=0; i<mStartedUsers.size(); i++) {
6363                    UserStartedState uss = mStartedUsers.valueAt(i);
6364                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6365                        uss.mState = UserStartedState.STATE_RUNNING;
6366                        final int userId = mStartedUsers.keyAt(i);
6367                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6368                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6369                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6370                        broadcastIntentLocked(null, null, intent, null,
6371                                new IIntentReceiver.Stub() {
6372                                    @Override
6373                                    public void performReceive(Intent intent, int resultCode,
6374                                            String data, Bundle extras, boolean ordered,
6375                                            boolean sticky, int sendingUser) {
6376                                        synchronized (ActivityManagerService.this) {
6377                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6378                                                    true, false);
6379                                        }
6380                                    }
6381                                },
6382                                0, null, null,
6383                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6384                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6385                                userId);
6386                    }
6387                }
6388                scheduleStartProfilesLocked();
6389            }
6390        }
6391    }
6392
6393    @Override
6394    public void bootAnimationComplete() {
6395        final boolean callFinishBooting;
6396        synchronized (this) {
6397            callFinishBooting = mCallFinishBooting;
6398            mBootAnimationComplete = true;
6399        }
6400        if (callFinishBooting) {
6401            finishBooting();
6402        }
6403    }
6404
6405    final void ensureBootCompleted() {
6406        boolean booting;
6407        boolean enableScreen;
6408        synchronized (this) {
6409            booting = mBooting;
6410            mBooting = false;
6411            enableScreen = !mBooted;
6412            mBooted = true;
6413        }
6414
6415        if (booting) {
6416            finishBooting();
6417        }
6418
6419        if (enableScreen) {
6420            enableScreenAfterBoot();
6421        }
6422    }
6423
6424    @Override
6425    public final void activityResumed(IBinder token) {
6426        final long origId = Binder.clearCallingIdentity();
6427        synchronized(this) {
6428            ActivityStack stack = ActivityRecord.getStackLocked(token);
6429            if (stack != null) {
6430                ActivityRecord.activityResumedLocked(token);
6431            }
6432        }
6433        Binder.restoreCallingIdentity(origId);
6434    }
6435
6436    @Override
6437    public final void activityPaused(IBinder token) {
6438        final long origId = Binder.clearCallingIdentity();
6439        synchronized(this) {
6440            ActivityStack stack = ActivityRecord.getStackLocked(token);
6441            if (stack != null) {
6442                stack.activityPausedLocked(token, false);
6443            }
6444        }
6445        Binder.restoreCallingIdentity(origId);
6446    }
6447
6448    @Override
6449    public final void activityStopped(IBinder token, Bundle icicle,
6450            PersistableBundle persistentState, CharSequence description) {
6451        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6452
6453        // Refuse possible leaked file descriptors
6454        if (icicle != null && icicle.hasFileDescriptors()) {
6455            throw new IllegalArgumentException("File descriptors passed in Bundle");
6456        }
6457
6458        final long origId = Binder.clearCallingIdentity();
6459
6460        synchronized (this) {
6461            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6462            if (r != null) {
6463                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6464            }
6465        }
6466
6467        trimApplications();
6468
6469        Binder.restoreCallingIdentity(origId);
6470    }
6471
6472    @Override
6473    public final void activityDestroyed(IBinder token) {
6474        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6475        synchronized (this) {
6476            ActivityStack stack = ActivityRecord.getStackLocked(token);
6477            if (stack != null) {
6478                stack.activityDestroyedLocked(token);
6479            }
6480        }
6481    }
6482
6483    @Override
6484    public final void backgroundResourcesReleased(IBinder token) {
6485        final long origId = Binder.clearCallingIdentity();
6486        try {
6487            synchronized (this) {
6488                ActivityStack stack = ActivityRecord.getStackLocked(token);
6489                if (stack != null) {
6490                    stack.backgroundResourcesReleased(token);
6491                }
6492            }
6493        } finally {
6494            Binder.restoreCallingIdentity(origId);
6495        }
6496    }
6497
6498    @Override
6499    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6500        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6501    }
6502
6503    @Override
6504    public final void notifyEnterAnimationComplete(IBinder token) {
6505        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6506    }
6507
6508    @Override
6509    public String getCallingPackage(IBinder token) {
6510        synchronized (this) {
6511            ActivityRecord r = getCallingRecordLocked(token);
6512            return r != null ? r.info.packageName : null;
6513        }
6514    }
6515
6516    @Override
6517    public ComponentName getCallingActivity(IBinder token) {
6518        synchronized (this) {
6519            ActivityRecord r = getCallingRecordLocked(token);
6520            return r != null ? r.intent.getComponent() : null;
6521        }
6522    }
6523
6524    private ActivityRecord getCallingRecordLocked(IBinder token) {
6525        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6526        if (r == null) {
6527            return null;
6528        }
6529        return r.resultTo;
6530    }
6531
6532    @Override
6533    public ComponentName getActivityClassForToken(IBinder token) {
6534        synchronized(this) {
6535            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6536            if (r == null) {
6537                return null;
6538            }
6539            return r.intent.getComponent();
6540        }
6541    }
6542
6543    @Override
6544    public String getPackageForToken(IBinder token) {
6545        synchronized(this) {
6546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6547            if (r == null) {
6548                return null;
6549            }
6550            return r.packageName;
6551        }
6552    }
6553
6554    @Override
6555    public IIntentSender getIntentSender(int type,
6556            String packageName, IBinder token, String resultWho,
6557            int requestCode, Intent[] intents, String[] resolvedTypes,
6558            int flags, Bundle options, int userId) {
6559        enforceNotIsolatedCaller("getIntentSender");
6560        // Refuse possible leaked file descriptors
6561        if (intents != null) {
6562            if (intents.length < 1) {
6563                throw new IllegalArgumentException("Intents array length must be >= 1");
6564            }
6565            for (int i=0; i<intents.length; i++) {
6566                Intent intent = intents[i];
6567                if (intent != null) {
6568                    if (intent.hasFileDescriptors()) {
6569                        throw new IllegalArgumentException("File descriptors passed in Intent");
6570                    }
6571                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6572                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6573                        throw new IllegalArgumentException(
6574                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6575                    }
6576                    intents[i] = new Intent(intent);
6577                }
6578            }
6579            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6580                throw new IllegalArgumentException(
6581                        "Intent array length does not match resolvedTypes length");
6582            }
6583        }
6584        if (options != null) {
6585            if (options.hasFileDescriptors()) {
6586                throw new IllegalArgumentException("File descriptors passed in options");
6587            }
6588        }
6589
6590        synchronized(this) {
6591            int callingUid = Binder.getCallingUid();
6592            int origUserId = userId;
6593            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6594                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6595                    ALLOW_NON_FULL, "getIntentSender", null);
6596            if (origUserId == UserHandle.USER_CURRENT) {
6597                // We don't want to evaluate this until the pending intent is
6598                // actually executed.  However, we do want to always do the
6599                // security checking for it above.
6600                userId = UserHandle.USER_CURRENT;
6601            }
6602            try {
6603                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6604                    int uid = AppGlobals.getPackageManager()
6605                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6606                    if (!UserHandle.isSameApp(callingUid, uid)) {
6607                        String msg = "Permission Denial: getIntentSender() from pid="
6608                            + Binder.getCallingPid()
6609                            + ", uid=" + Binder.getCallingUid()
6610                            + ", (need uid=" + uid + ")"
6611                            + " is not allowed to send as package " + packageName;
6612                        Slog.w(TAG, msg);
6613                        throw new SecurityException(msg);
6614                    }
6615                }
6616
6617                return getIntentSenderLocked(type, packageName, callingUid, userId,
6618                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6619
6620            } catch (RemoteException e) {
6621                throw new SecurityException(e);
6622            }
6623        }
6624    }
6625
6626    IIntentSender getIntentSenderLocked(int type, String packageName,
6627            int callingUid, int userId, IBinder token, String resultWho,
6628            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6629            Bundle options) {
6630        if (DEBUG_MU)
6631            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6632        ActivityRecord activity = null;
6633        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6634            activity = ActivityRecord.isInStackLocked(token);
6635            if (activity == null) {
6636                return null;
6637            }
6638            if (activity.finishing) {
6639                return null;
6640            }
6641        }
6642
6643        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6644        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6645        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6646        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6647                |PendingIntent.FLAG_UPDATE_CURRENT);
6648
6649        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6650                type, packageName, activity, resultWho,
6651                requestCode, intents, resolvedTypes, flags, options, userId);
6652        WeakReference<PendingIntentRecord> ref;
6653        ref = mIntentSenderRecords.get(key);
6654        PendingIntentRecord rec = ref != null ? ref.get() : null;
6655        if (rec != null) {
6656            if (!cancelCurrent) {
6657                if (updateCurrent) {
6658                    if (rec.key.requestIntent != null) {
6659                        rec.key.requestIntent.replaceExtras(intents != null ?
6660                                intents[intents.length - 1] : null);
6661                    }
6662                    if (intents != null) {
6663                        intents[intents.length-1] = rec.key.requestIntent;
6664                        rec.key.allIntents = intents;
6665                        rec.key.allResolvedTypes = resolvedTypes;
6666                    } else {
6667                        rec.key.allIntents = null;
6668                        rec.key.allResolvedTypes = null;
6669                    }
6670                }
6671                return rec;
6672            }
6673            rec.canceled = true;
6674            mIntentSenderRecords.remove(key);
6675        }
6676        if (noCreate) {
6677            return rec;
6678        }
6679        rec = new PendingIntentRecord(this, key, callingUid);
6680        mIntentSenderRecords.put(key, rec.ref);
6681        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6682            if (activity.pendingResults == null) {
6683                activity.pendingResults
6684                        = new HashSet<WeakReference<PendingIntentRecord>>();
6685            }
6686            activity.pendingResults.add(rec.ref);
6687        }
6688        return rec;
6689    }
6690
6691    @Override
6692    public void cancelIntentSender(IIntentSender sender) {
6693        if (!(sender instanceof PendingIntentRecord)) {
6694            return;
6695        }
6696        synchronized(this) {
6697            PendingIntentRecord rec = (PendingIntentRecord)sender;
6698            try {
6699                int uid = AppGlobals.getPackageManager()
6700                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6701                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6702                    String msg = "Permission Denial: cancelIntentSender() from pid="
6703                        + Binder.getCallingPid()
6704                        + ", uid=" + Binder.getCallingUid()
6705                        + " is not allowed to cancel packges "
6706                        + rec.key.packageName;
6707                    Slog.w(TAG, msg);
6708                    throw new SecurityException(msg);
6709                }
6710            } catch (RemoteException e) {
6711                throw new SecurityException(e);
6712            }
6713            cancelIntentSenderLocked(rec, true);
6714        }
6715    }
6716
6717    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6718        rec.canceled = true;
6719        mIntentSenderRecords.remove(rec.key);
6720        if (cleanActivity && rec.key.activity != null) {
6721            rec.key.activity.pendingResults.remove(rec.ref);
6722        }
6723    }
6724
6725    @Override
6726    public String getPackageForIntentSender(IIntentSender pendingResult) {
6727        if (!(pendingResult instanceof PendingIntentRecord)) {
6728            return null;
6729        }
6730        try {
6731            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6732            return res.key.packageName;
6733        } catch (ClassCastException e) {
6734        }
6735        return null;
6736    }
6737
6738    @Override
6739    public int getUidForIntentSender(IIntentSender sender) {
6740        if (sender instanceof PendingIntentRecord) {
6741            try {
6742                PendingIntentRecord res = (PendingIntentRecord)sender;
6743                return res.uid;
6744            } catch (ClassCastException e) {
6745            }
6746        }
6747        return -1;
6748    }
6749
6750    @Override
6751    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6752        if (!(pendingResult instanceof PendingIntentRecord)) {
6753            return false;
6754        }
6755        try {
6756            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6757            if (res.key.allIntents == null) {
6758                return false;
6759            }
6760            for (int i=0; i<res.key.allIntents.length; i++) {
6761                Intent intent = res.key.allIntents[i];
6762                if (intent.getPackage() != null && intent.getComponent() != null) {
6763                    return false;
6764                }
6765            }
6766            return true;
6767        } catch (ClassCastException e) {
6768        }
6769        return false;
6770    }
6771
6772    @Override
6773    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6774        if (!(pendingResult instanceof PendingIntentRecord)) {
6775            return false;
6776        }
6777        try {
6778            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6779            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6780                return true;
6781            }
6782            return false;
6783        } catch (ClassCastException e) {
6784        }
6785        return false;
6786    }
6787
6788    @Override
6789    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6790        if (!(pendingResult instanceof PendingIntentRecord)) {
6791            return null;
6792        }
6793        try {
6794            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6795            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6796        } catch (ClassCastException e) {
6797        }
6798        return null;
6799    }
6800
6801    @Override
6802    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6803        if (!(pendingResult instanceof PendingIntentRecord)) {
6804            return null;
6805        }
6806        try {
6807            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6808            Intent intent = res.key.requestIntent;
6809            if (intent != null) {
6810                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6811                        || res.lastTagPrefix.equals(prefix))) {
6812                    return res.lastTag;
6813                }
6814                res.lastTagPrefix = prefix;
6815                StringBuilder sb = new StringBuilder(128);
6816                if (prefix != null) {
6817                    sb.append(prefix);
6818                }
6819                if (intent.getAction() != null) {
6820                    sb.append(intent.getAction());
6821                } else if (intent.getComponent() != null) {
6822                    intent.getComponent().appendShortString(sb);
6823                } else {
6824                    sb.append("?");
6825                }
6826                return res.lastTag = sb.toString();
6827            }
6828        } catch (ClassCastException e) {
6829        }
6830        return null;
6831    }
6832
6833    @Override
6834    public void setProcessLimit(int max) {
6835        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6836                "setProcessLimit()");
6837        synchronized (this) {
6838            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6839            mProcessLimitOverride = max;
6840        }
6841        trimApplications();
6842    }
6843
6844    @Override
6845    public int getProcessLimit() {
6846        synchronized (this) {
6847            return mProcessLimitOverride;
6848        }
6849    }
6850
6851    void foregroundTokenDied(ForegroundToken token) {
6852        synchronized (ActivityManagerService.this) {
6853            synchronized (mPidsSelfLocked) {
6854                ForegroundToken cur
6855                    = mForegroundProcesses.get(token.pid);
6856                if (cur != token) {
6857                    return;
6858                }
6859                mForegroundProcesses.remove(token.pid);
6860                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6861                if (pr == null) {
6862                    return;
6863                }
6864                pr.forcingToForeground = null;
6865                updateProcessForegroundLocked(pr, false, false);
6866            }
6867            updateOomAdjLocked();
6868        }
6869    }
6870
6871    @Override
6872    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6873        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6874                "setProcessForeground()");
6875        synchronized(this) {
6876            boolean changed = false;
6877
6878            synchronized (mPidsSelfLocked) {
6879                ProcessRecord pr = mPidsSelfLocked.get(pid);
6880                if (pr == null && isForeground) {
6881                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6882                    return;
6883                }
6884                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6885                if (oldToken != null) {
6886                    oldToken.token.unlinkToDeath(oldToken, 0);
6887                    mForegroundProcesses.remove(pid);
6888                    if (pr != null) {
6889                        pr.forcingToForeground = null;
6890                    }
6891                    changed = true;
6892                }
6893                if (isForeground && token != null) {
6894                    ForegroundToken newToken = new ForegroundToken() {
6895                        @Override
6896                        public void binderDied() {
6897                            foregroundTokenDied(this);
6898                        }
6899                    };
6900                    newToken.pid = pid;
6901                    newToken.token = token;
6902                    try {
6903                        token.linkToDeath(newToken, 0);
6904                        mForegroundProcesses.put(pid, newToken);
6905                        pr.forcingToForeground = token;
6906                        changed = true;
6907                    } catch (RemoteException e) {
6908                        // If the process died while doing this, we will later
6909                        // do the cleanup with the process death link.
6910                    }
6911                }
6912            }
6913
6914            if (changed) {
6915                updateOomAdjLocked();
6916            }
6917        }
6918    }
6919
6920    // =========================================================
6921    // PERMISSIONS
6922    // =========================================================
6923
6924    static class PermissionController extends IPermissionController.Stub {
6925        ActivityManagerService mActivityManagerService;
6926        PermissionController(ActivityManagerService activityManagerService) {
6927            mActivityManagerService = activityManagerService;
6928        }
6929
6930        @Override
6931        public boolean checkPermission(String permission, int pid, int uid) {
6932            return mActivityManagerService.checkPermission(permission, pid,
6933                    uid) == PackageManager.PERMISSION_GRANTED;
6934        }
6935    }
6936
6937    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6938        @Override
6939        public int checkComponentPermission(String permission, int pid, int uid,
6940                int owningUid, boolean exported) {
6941            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6942                    owningUid, exported);
6943        }
6944
6945        @Override
6946        public Object getAMSLock() {
6947            return ActivityManagerService.this;
6948        }
6949    }
6950
6951    /**
6952     * This can be called with or without the global lock held.
6953     */
6954    int checkComponentPermission(String permission, int pid, int uid,
6955            int owningUid, boolean exported) {
6956        // We might be performing an operation on behalf of an indirect binder
6957        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6958        // client identity accordingly before proceeding.
6959        Identity tlsIdentity = sCallerIdentity.get();
6960        if (tlsIdentity != null) {
6961            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6962                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6963            uid = tlsIdentity.uid;
6964            pid = tlsIdentity.pid;
6965        }
6966
6967        if (pid == MY_PID) {
6968            return PackageManager.PERMISSION_GRANTED;
6969        }
6970
6971        return ActivityManager.checkComponentPermission(permission, uid,
6972                owningUid, exported);
6973    }
6974
6975    /**
6976     * As the only public entry point for permissions checking, this method
6977     * can enforce the semantic that requesting a check on a null global
6978     * permission is automatically denied.  (Internally a null permission
6979     * string is used when calling {@link #checkComponentPermission} in cases
6980     * when only uid-based security is needed.)
6981     *
6982     * This can be called with or without the global lock held.
6983     */
6984    @Override
6985    public int checkPermission(String permission, int pid, int uid) {
6986        if (permission == null) {
6987            return PackageManager.PERMISSION_DENIED;
6988        }
6989        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6990    }
6991
6992    /**
6993     * Binder IPC calls go through the public entry point.
6994     * This can be called with or without the global lock held.
6995     */
6996    int checkCallingPermission(String permission) {
6997        return checkPermission(permission,
6998                Binder.getCallingPid(),
6999                UserHandle.getAppId(Binder.getCallingUid()));
7000    }
7001
7002    /**
7003     * This can be called with or without the global lock held.
7004     */
7005    void enforceCallingPermission(String permission, String func) {
7006        if (checkCallingPermission(permission)
7007                == PackageManager.PERMISSION_GRANTED) {
7008            return;
7009        }
7010
7011        String msg = "Permission Denial: " + func + " from pid="
7012                + Binder.getCallingPid()
7013                + ", uid=" + Binder.getCallingUid()
7014                + " requires " + permission;
7015        Slog.w(TAG, msg);
7016        throw new SecurityException(msg);
7017    }
7018
7019    /**
7020     * Determine if UID is holding permissions required to access {@link Uri} in
7021     * the given {@link ProviderInfo}. Final permission checking is always done
7022     * in {@link ContentProvider}.
7023     */
7024    private final boolean checkHoldingPermissionsLocked(
7025            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7026        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7027                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7028        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7029            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7030                    != PERMISSION_GRANTED) {
7031                return false;
7032            }
7033        }
7034        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7035    }
7036
7037    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7038            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7039        if (pi.applicationInfo.uid == uid) {
7040            return true;
7041        } else if (!pi.exported) {
7042            return false;
7043        }
7044
7045        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7046        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7047        try {
7048            // check if target holds top-level <provider> permissions
7049            if (!readMet && pi.readPermission != null && considerUidPermissions
7050                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7051                readMet = true;
7052            }
7053            if (!writeMet && pi.writePermission != null && considerUidPermissions
7054                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7055                writeMet = true;
7056            }
7057
7058            // track if unprotected read/write is allowed; any denied
7059            // <path-permission> below removes this ability
7060            boolean allowDefaultRead = pi.readPermission == null;
7061            boolean allowDefaultWrite = pi.writePermission == null;
7062
7063            // check if target holds any <path-permission> that match uri
7064            final PathPermission[] pps = pi.pathPermissions;
7065            if (pps != null) {
7066                final String path = grantUri.uri.getPath();
7067                int i = pps.length;
7068                while (i > 0 && (!readMet || !writeMet)) {
7069                    i--;
7070                    PathPermission pp = pps[i];
7071                    if (pp.match(path)) {
7072                        if (!readMet) {
7073                            final String pprperm = pp.getReadPermission();
7074                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7075                                    + pprperm + " for " + pp.getPath()
7076                                    + ": match=" + pp.match(path)
7077                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7078                            if (pprperm != null) {
7079                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7080                                        == PERMISSION_GRANTED) {
7081                                    readMet = true;
7082                                } else {
7083                                    allowDefaultRead = false;
7084                                }
7085                            }
7086                        }
7087                        if (!writeMet) {
7088                            final String ppwperm = pp.getWritePermission();
7089                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7090                                    + ppwperm + " for " + pp.getPath()
7091                                    + ": match=" + pp.match(path)
7092                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7093                            if (ppwperm != null) {
7094                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7095                                        == PERMISSION_GRANTED) {
7096                                    writeMet = true;
7097                                } else {
7098                                    allowDefaultWrite = false;
7099                                }
7100                            }
7101                        }
7102                    }
7103                }
7104            }
7105
7106            // grant unprotected <provider> read/write, if not blocked by
7107            // <path-permission> above
7108            if (allowDefaultRead) readMet = true;
7109            if (allowDefaultWrite) writeMet = true;
7110
7111        } catch (RemoteException e) {
7112            return false;
7113        }
7114
7115        return readMet && writeMet;
7116    }
7117
7118    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7119        ProviderInfo pi = null;
7120        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7121        if (cpr != null) {
7122            pi = cpr.info;
7123        } else {
7124            try {
7125                pi = AppGlobals.getPackageManager().resolveContentProvider(
7126                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7127            } catch (RemoteException ex) {
7128            }
7129        }
7130        return pi;
7131    }
7132
7133    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7134        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7135        if (targetUris != null) {
7136            return targetUris.get(grantUri);
7137        }
7138        return null;
7139    }
7140
7141    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7142            String targetPkg, int targetUid, GrantUri grantUri) {
7143        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7144        if (targetUris == null) {
7145            targetUris = Maps.newArrayMap();
7146            mGrantedUriPermissions.put(targetUid, targetUris);
7147        }
7148
7149        UriPermission perm = targetUris.get(grantUri);
7150        if (perm == null) {
7151            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7152            targetUris.put(grantUri, perm);
7153        }
7154
7155        return perm;
7156    }
7157
7158    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7159            final int modeFlags) {
7160        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7161        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7162                : UriPermission.STRENGTH_OWNED;
7163
7164        // Root gets to do everything.
7165        if (uid == 0) {
7166            return true;
7167        }
7168
7169        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7170        if (perms == null) return false;
7171
7172        // First look for exact match
7173        final UriPermission exactPerm = perms.get(grantUri);
7174        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7175            return true;
7176        }
7177
7178        // No exact match, look for prefixes
7179        final int N = perms.size();
7180        for (int i = 0; i < N; i++) {
7181            final UriPermission perm = perms.valueAt(i);
7182            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7183                    && perm.getStrength(modeFlags) >= minStrength) {
7184                return true;
7185            }
7186        }
7187
7188        return false;
7189    }
7190
7191    /**
7192     * @param uri This uri must NOT contain an embedded userId.
7193     * @param userId The userId in which the uri is to be resolved.
7194     */
7195    @Override
7196    public int checkUriPermission(Uri uri, int pid, int uid,
7197            final int modeFlags, int userId) {
7198        enforceNotIsolatedCaller("checkUriPermission");
7199
7200        // Another redirected-binder-call permissions check as in
7201        // {@link checkComponentPermission}.
7202        Identity tlsIdentity = sCallerIdentity.get();
7203        if (tlsIdentity != null) {
7204            uid = tlsIdentity.uid;
7205            pid = tlsIdentity.pid;
7206        }
7207
7208        // Our own process gets to do everything.
7209        if (pid == MY_PID) {
7210            return PackageManager.PERMISSION_GRANTED;
7211        }
7212        synchronized (this) {
7213            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7214                    ? PackageManager.PERMISSION_GRANTED
7215                    : PackageManager.PERMISSION_DENIED;
7216        }
7217    }
7218
7219    /**
7220     * Check if the targetPkg can be granted permission to access uri by
7221     * the callingUid using the given modeFlags.  Throws a security exception
7222     * if callingUid is not allowed to do this.  Returns the uid of the target
7223     * if the URI permission grant should be performed; returns -1 if it is not
7224     * needed (for example targetPkg already has permission to access the URI).
7225     * If you already know the uid of the target, you can supply it in
7226     * lastTargetUid else set that to -1.
7227     */
7228    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7229            final int modeFlags, int lastTargetUid) {
7230        if (!Intent.isAccessUriMode(modeFlags)) {
7231            return -1;
7232        }
7233
7234        if (targetPkg != null) {
7235            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7236                    "Checking grant " + targetPkg + " permission to " + grantUri);
7237        }
7238
7239        final IPackageManager pm = AppGlobals.getPackageManager();
7240
7241        // If this is not a content: uri, we can't do anything with it.
7242        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7243            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7244                    "Can't grant URI permission for non-content URI: " + grantUri);
7245            return -1;
7246        }
7247
7248        final String authority = grantUri.uri.getAuthority();
7249        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7250        if (pi == null) {
7251            Slog.w(TAG, "No content provider found for permission check: " +
7252                    grantUri.uri.toSafeString());
7253            return -1;
7254        }
7255
7256        int targetUid = lastTargetUid;
7257        if (targetUid < 0 && targetPkg != null) {
7258            try {
7259                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7260                if (targetUid < 0) {
7261                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7262                            "Can't grant URI permission no uid for: " + targetPkg);
7263                    return -1;
7264                }
7265            } catch (RemoteException ex) {
7266                return -1;
7267            }
7268        }
7269
7270        if (targetUid >= 0) {
7271            // First...  does the target actually need this permission?
7272            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7273                // No need to grant the target this permission.
7274                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7275                        "Target " + targetPkg + " already has full permission to " + grantUri);
7276                return -1;
7277            }
7278        } else {
7279            // First...  there is no target package, so can anyone access it?
7280            boolean allowed = pi.exported;
7281            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7282                if (pi.readPermission != null) {
7283                    allowed = false;
7284                }
7285            }
7286            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7287                if (pi.writePermission != null) {
7288                    allowed = false;
7289                }
7290            }
7291            if (allowed) {
7292                return -1;
7293            }
7294        }
7295
7296        /* There is a special cross user grant if:
7297         * - The target is on another user.
7298         * - Apps on the current user can access the uri without any uid permissions.
7299         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7300         * grant uri permissions.
7301         */
7302        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7303                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7304                modeFlags, false /*without considering the uid permissions*/);
7305
7306        // Second...  is the provider allowing granting of URI permissions?
7307        if (!specialCrossUserGrant) {
7308            if (!pi.grantUriPermissions) {
7309                throw new SecurityException("Provider " + pi.packageName
7310                        + "/" + pi.name
7311                        + " does not allow granting of Uri permissions (uri "
7312                        + grantUri + ")");
7313            }
7314            if (pi.uriPermissionPatterns != null) {
7315                final int N = pi.uriPermissionPatterns.length;
7316                boolean allowed = false;
7317                for (int i=0; i<N; i++) {
7318                    if (pi.uriPermissionPatterns[i] != null
7319                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7320                        allowed = true;
7321                        break;
7322                    }
7323                }
7324                if (!allowed) {
7325                    throw new SecurityException("Provider " + pi.packageName
7326                            + "/" + pi.name
7327                            + " does not allow granting of permission to path of Uri "
7328                            + grantUri);
7329                }
7330            }
7331        }
7332
7333        // Third...  does the caller itself have permission to access
7334        // this uri?
7335        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7336            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7337                // Require they hold a strong enough Uri permission
7338                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7339                    throw new SecurityException("Uid " + callingUid
7340                            + " does not have permission to uri " + grantUri);
7341                }
7342            }
7343        }
7344        return targetUid;
7345    }
7346
7347    /**
7348     * @param uri This uri must NOT contain an embedded userId.
7349     * @param userId The userId in which the uri is to be resolved.
7350     */
7351    @Override
7352    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7353            final int modeFlags, int userId) {
7354        enforceNotIsolatedCaller("checkGrantUriPermission");
7355        synchronized(this) {
7356            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7357                    new GrantUri(userId, uri, false), modeFlags, -1);
7358        }
7359    }
7360
7361    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7362            final int modeFlags, UriPermissionOwner owner) {
7363        if (!Intent.isAccessUriMode(modeFlags)) {
7364            return;
7365        }
7366
7367        // So here we are: the caller has the assumed permission
7368        // to the uri, and the target doesn't.  Let's now give this to
7369        // the target.
7370
7371        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7372                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7373
7374        final String authority = grantUri.uri.getAuthority();
7375        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7376        if (pi == null) {
7377            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7378            return;
7379        }
7380
7381        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7382            grantUri.prefix = true;
7383        }
7384        final UriPermission perm = findOrCreateUriPermissionLocked(
7385                pi.packageName, targetPkg, targetUid, grantUri);
7386        perm.grantModes(modeFlags, owner);
7387    }
7388
7389    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7390            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7391        if (targetPkg == null) {
7392            throw new NullPointerException("targetPkg");
7393        }
7394        int targetUid;
7395        final IPackageManager pm = AppGlobals.getPackageManager();
7396        try {
7397            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7398        } catch (RemoteException ex) {
7399            return;
7400        }
7401
7402        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7403                targetUid);
7404        if (targetUid < 0) {
7405            return;
7406        }
7407
7408        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7409                owner);
7410    }
7411
7412    static class NeededUriGrants extends ArrayList<GrantUri> {
7413        final String targetPkg;
7414        final int targetUid;
7415        final int flags;
7416
7417        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7418            this.targetPkg = targetPkg;
7419            this.targetUid = targetUid;
7420            this.flags = flags;
7421        }
7422    }
7423
7424    /**
7425     * Like checkGrantUriPermissionLocked, but takes an Intent.
7426     */
7427    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7428            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7429        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7430                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7431                + " clip=" + (intent != null ? intent.getClipData() : null)
7432                + " from " + intent + "; flags=0x"
7433                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7434
7435        if (targetPkg == null) {
7436            throw new NullPointerException("targetPkg");
7437        }
7438
7439        if (intent == null) {
7440            return null;
7441        }
7442        Uri data = intent.getData();
7443        ClipData clip = intent.getClipData();
7444        if (data == null && clip == null) {
7445            return null;
7446        }
7447        // Default userId for uris in the intent (if they don't specify it themselves)
7448        int contentUserHint = intent.getContentUserHint();
7449        if (contentUserHint == UserHandle.USER_CURRENT) {
7450            contentUserHint = UserHandle.getUserId(callingUid);
7451        }
7452        final IPackageManager pm = AppGlobals.getPackageManager();
7453        int targetUid;
7454        if (needed != null) {
7455            targetUid = needed.targetUid;
7456        } else {
7457            try {
7458                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7459            } catch (RemoteException ex) {
7460                return null;
7461            }
7462            if (targetUid < 0) {
7463                if (DEBUG_URI_PERMISSION) {
7464                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7465                            + " on user " + targetUserId);
7466                }
7467                return null;
7468            }
7469        }
7470        if (data != null) {
7471            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7472            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7473                    targetUid);
7474            if (targetUid > 0) {
7475                if (needed == null) {
7476                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7477                }
7478                needed.add(grantUri);
7479            }
7480        }
7481        if (clip != null) {
7482            for (int i=0; i<clip.getItemCount(); i++) {
7483                Uri uri = clip.getItemAt(i).getUri();
7484                if (uri != null) {
7485                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7486                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7487                            targetUid);
7488                    if (targetUid > 0) {
7489                        if (needed == null) {
7490                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7491                        }
7492                        needed.add(grantUri);
7493                    }
7494                } else {
7495                    Intent clipIntent = clip.getItemAt(i).getIntent();
7496                    if (clipIntent != null) {
7497                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7498                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7499                        if (newNeeded != null) {
7500                            needed = newNeeded;
7501                        }
7502                    }
7503                }
7504            }
7505        }
7506
7507        return needed;
7508    }
7509
7510    /**
7511     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7512     */
7513    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7514            UriPermissionOwner owner) {
7515        if (needed != null) {
7516            for (int i=0; i<needed.size(); i++) {
7517                GrantUri grantUri = needed.get(i);
7518                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7519                        grantUri, needed.flags, owner);
7520            }
7521        }
7522    }
7523
7524    void grantUriPermissionFromIntentLocked(int callingUid,
7525            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7526        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7527                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7528        if (needed == null) {
7529            return;
7530        }
7531
7532        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7533    }
7534
7535    /**
7536     * @param uri This uri must NOT contain an embedded userId.
7537     * @param userId The userId in which the uri is to be resolved.
7538     */
7539    @Override
7540    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7541            final int modeFlags, int userId) {
7542        enforceNotIsolatedCaller("grantUriPermission");
7543        GrantUri grantUri = new GrantUri(userId, uri, false);
7544        synchronized(this) {
7545            final ProcessRecord r = getRecordForAppLocked(caller);
7546            if (r == null) {
7547                throw new SecurityException("Unable to find app for caller "
7548                        + caller
7549                        + " when granting permission to uri " + grantUri);
7550            }
7551            if (targetPkg == null) {
7552                throw new IllegalArgumentException("null target");
7553            }
7554            if (grantUri == null) {
7555                throw new IllegalArgumentException("null uri");
7556            }
7557
7558            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7559                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7560                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7561                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7562
7563            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7564                    UserHandle.getUserId(r.uid));
7565        }
7566    }
7567
7568    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7569        if (perm.modeFlags == 0) {
7570            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7571                    perm.targetUid);
7572            if (perms != null) {
7573                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7574                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7575
7576                perms.remove(perm.uri);
7577                if (perms.isEmpty()) {
7578                    mGrantedUriPermissions.remove(perm.targetUid);
7579                }
7580            }
7581        }
7582    }
7583
7584    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7585        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7586
7587        final IPackageManager pm = AppGlobals.getPackageManager();
7588        final String authority = grantUri.uri.getAuthority();
7589        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7590        if (pi == null) {
7591            Slog.w(TAG, "No content provider found for permission revoke: "
7592                    + grantUri.toSafeString());
7593            return;
7594        }
7595
7596        // Does the caller have this permission on the URI?
7597        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7598            // If they don't have direct access to the URI, then revoke any
7599            // ownerless URI permissions that have been granted to them.
7600            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7601            if (perms != null) {
7602                boolean persistChanged = false;
7603                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7604                    final UriPermission perm = it.next();
7605                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7606                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7607                        if (DEBUG_URI_PERMISSION)
7608                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7609                                    " permission to " + perm.uri);
7610                        persistChanged |= perm.revokeModes(
7611                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7612                        if (perm.modeFlags == 0) {
7613                            it.remove();
7614                        }
7615                    }
7616                }
7617                if (perms.isEmpty()) {
7618                    mGrantedUriPermissions.remove(callingUid);
7619                }
7620                if (persistChanged) {
7621                    schedulePersistUriGrants();
7622                }
7623            }
7624            return;
7625        }
7626
7627        boolean persistChanged = false;
7628
7629        // Go through all of the permissions and remove any that match.
7630        int N = mGrantedUriPermissions.size();
7631        for (int i = 0; i < N; i++) {
7632            final int targetUid = mGrantedUriPermissions.keyAt(i);
7633            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7634
7635            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7636                final UriPermission perm = it.next();
7637                if (perm.uri.sourceUserId == grantUri.sourceUserId
7638                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7639                    if (DEBUG_URI_PERMISSION)
7640                        Slog.v(TAG,
7641                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7642                    persistChanged |= perm.revokeModes(
7643                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7644                    if (perm.modeFlags == 0) {
7645                        it.remove();
7646                    }
7647                }
7648            }
7649
7650            if (perms.isEmpty()) {
7651                mGrantedUriPermissions.remove(targetUid);
7652                N--;
7653                i--;
7654            }
7655        }
7656
7657        if (persistChanged) {
7658            schedulePersistUriGrants();
7659        }
7660    }
7661
7662    /**
7663     * @param uri This uri must NOT contain an embedded userId.
7664     * @param userId The userId in which the uri is to be resolved.
7665     */
7666    @Override
7667    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7668            int userId) {
7669        enforceNotIsolatedCaller("revokeUriPermission");
7670        synchronized(this) {
7671            final ProcessRecord r = getRecordForAppLocked(caller);
7672            if (r == null) {
7673                throw new SecurityException("Unable to find app for caller "
7674                        + caller
7675                        + " when revoking permission to uri " + uri);
7676            }
7677            if (uri == null) {
7678                Slog.w(TAG, "revokeUriPermission: null uri");
7679                return;
7680            }
7681
7682            if (!Intent.isAccessUriMode(modeFlags)) {
7683                return;
7684            }
7685
7686            final IPackageManager pm = AppGlobals.getPackageManager();
7687            final String authority = uri.getAuthority();
7688            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7689            if (pi == null) {
7690                Slog.w(TAG, "No content provider found for permission revoke: "
7691                        + uri.toSafeString());
7692                return;
7693            }
7694
7695            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7696        }
7697    }
7698
7699    /**
7700     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7701     * given package.
7702     *
7703     * @param packageName Package name to match, or {@code null} to apply to all
7704     *            packages.
7705     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7706     *            to all users.
7707     * @param persistable If persistable grants should be removed.
7708     */
7709    private void removeUriPermissionsForPackageLocked(
7710            String packageName, int userHandle, boolean persistable) {
7711        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7712            throw new IllegalArgumentException("Must narrow by either package or user");
7713        }
7714
7715        boolean persistChanged = false;
7716
7717        int N = mGrantedUriPermissions.size();
7718        for (int i = 0; i < N; i++) {
7719            final int targetUid = mGrantedUriPermissions.keyAt(i);
7720            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7721
7722            // Only inspect grants matching user
7723            if (userHandle == UserHandle.USER_ALL
7724                    || userHandle == UserHandle.getUserId(targetUid)) {
7725                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7726                    final UriPermission perm = it.next();
7727
7728                    // Only inspect grants matching package
7729                    if (packageName == null || perm.sourcePkg.equals(packageName)
7730                            || perm.targetPkg.equals(packageName)) {
7731                        persistChanged |= perm.revokeModes(persistable
7732                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7733
7734                        // Only remove when no modes remain; any persisted grants
7735                        // will keep this alive.
7736                        if (perm.modeFlags == 0) {
7737                            it.remove();
7738                        }
7739                    }
7740                }
7741
7742                if (perms.isEmpty()) {
7743                    mGrantedUriPermissions.remove(targetUid);
7744                    N--;
7745                    i--;
7746                }
7747            }
7748        }
7749
7750        if (persistChanged) {
7751            schedulePersistUriGrants();
7752        }
7753    }
7754
7755    @Override
7756    public IBinder newUriPermissionOwner(String name) {
7757        enforceNotIsolatedCaller("newUriPermissionOwner");
7758        synchronized(this) {
7759            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7760            return owner.getExternalTokenLocked();
7761        }
7762    }
7763
7764    /**
7765     * @param uri This uri must NOT contain an embedded userId.
7766     * @param sourceUserId The userId in which the uri is to be resolved.
7767     * @param targetUserId The userId of the app that receives the grant.
7768     */
7769    @Override
7770    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7771            final int modeFlags, int sourceUserId, int targetUserId) {
7772        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7773                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7774        synchronized(this) {
7775            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7776            if (owner == null) {
7777                throw new IllegalArgumentException("Unknown owner: " + token);
7778            }
7779            if (fromUid != Binder.getCallingUid()) {
7780                if (Binder.getCallingUid() != Process.myUid()) {
7781                    // Only system code can grant URI permissions on behalf
7782                    // of other users.
7783                    throw new SecurityException("nice try");
7784                }
7785            }
7786            if (targetPkg == null) {
7787                throw new IllegalArgumentException("null target");
7788            }
7789            if (uri == null) {
7790                throw new IllegalArgumentException("null uri");
7791            }
7792
7793            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7794                    modeFlags, owner, targetUserId);
7795        }
7796    }
7797
7798    /**
7799     * @param uri This uri must NOT contain an embedded userId.
7800     * @param userId The userId in which the uri is to be resolved.
7801     */
7802    @Override
7803    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7804        synchronized(this) {
7805            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7806            if (owner == null) {
7807                throw new IllegalArgumentException("Unknown owner: " + token);
7808            }
7809
7810            if (uri == null) {
7811                owner.removeUriPermissionsLocked(mode);
7812            } else {
7813                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7814            }
7815        }
7816    }
7817
7818    private void schedulePersistUriGrants() {
7819        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7820            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7821                    10 * DateUtils.SECOND_IN_MILLIS);
7822        }
7823    }
7824
7825    private void writeGrantedUriPermissions() {
7826        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7827
7828        // Snapshot permissions so we can persist without lock
7829        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7830        synchronized (this) {
7831            final int size = mGrantedUriPermissions.size();
7832            for (int i = 0; i < size; i++) {
7833                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7834                for (UriPermission perm : perms.values()) {
7835                    if (perm.persistedModeFlags != 0) {
7836                        persist.add(perm.snapshot());
7837                    }
7838                }
7839            }
7840        }
7841
7842        FileOutputStream fos = null;
7843        try {
7844            fos = mGrantFile.startWrite();
7845
7846            XmlSerializer out = new FastXmlSerializer();
7847            out.setOutput(fos, "utf-8");
7848            out.startDocument(null, true);
7849            out.startTag(null, TAG_URI_GRANTS);
7850            for (UriPermission.Snapshot perm : persist) {
7851                out.startTag(null, TAG_URI_GRANT);
7852                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7853                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7854                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7855                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7856                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7857                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7858                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7859                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7860                out.endTag(null, TAG_URI_GRANT);
7861            }
7862            out.endTag(null, TAG_URI_GRANTS);
7863            out.endDocument();
7864
7865            mGrantFile.finishWrite(fos);
7866        } catch (IOException e) {
7867            if (fos != null) {
7868                mGrantFile.failWrite(fos);
7869            }
7870        }
7871    }
7872
7873    private void readGrantedUriPermissionsLocked() {
7874        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7875
7876        final long now = System.currentTimeMillis();
7877
7878        FileInputStream fis = null;
7879        try {
7880            fis = mGrantFile.openRead();
7881            final XmlPullParser in = Xml.newPullParser();
7882            in.setInput(fis, null);
7883
7884            int type;
7885            while ((type = in.next()) != END_DOCUMENT) {
7886                final String tag = in.getName();
7887                if (type == START_TAG) {
7888                    if (TAG_URI_GRANT.equals(tag)) {
7889                        final int sourceUserId;
7890                        final int targetUserId;
7891                        final int userHandle = readIntAttribute(in,
7892                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7893                        if (userHandle != UserHandle.USER_NULL) {
7894                            // For backwards compatibility.
7895                            sourceUserId = userHandle;
7896                            targetUserId = userHandle;
7897                        } else {
7898                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7899                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7900                        }
7901                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7902                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7903                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7904                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7905                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7906                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7907
7908                        // Sanity check that provider still belongs to source package
7909                        final ProviderInfo pi = getProviderInfoLocked(
7910                                uri.getAuthority(), sourceUserId);
7911                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7912                            int targetUid = -1;
7913                            try {
7914                                targetUid = AppGlobals.getPackageManager()
7915                                        .getPackageUid(targetPkg, targetUserId);
7916                            } catch (RemoteException e) {
7917                            }
7918                            if (targetUid != -1) {
7919                                final UriPermission perm = findOrCreateUriPermissionLocked(
7920                                        sourcePkg, targetPkg, targetUid,
7921                                        new GrantUri(sourceUserId, uri, prefix));
7922                                perm.initPersistedModes(modeFlags, createdTime);
7923                            }
7924                        } else {
7925                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7926                                    + " but instead found " + pi);
7927                        }
7928                    }
7929                }
7930            }
7931        } catch (FileNotFoundException e) {
7932            // Missing grants is okay
7933        } catch (IOException e) {
7934            Slog.wtf(TAG, "Failed reading Uri grants", e);
7935        } catch (XmlPullParserException e) {
7936            Slog.wtf(TAG, "Failed reading Uri grants", e);
7937        } finally {
7938            IoUtils.closeQuietly(fis);
7939        }
7940    }
7941
7942    /**
7943     * @param uri This uri must NOT contain an embedded userId.
7944     * @param userId The userId in which the uri is to be resolved.
7945     */
7946    @Override
7947    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7948        enforceNotIsolatedCaller("takePersistableUriPermission");
7949
7950        Preconditions.checkFlagsArgument(modeFlags,
7951                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7952
7953        synchronized (this) {
7954            final int callingUid = Binder.getCallingUid();
7955            boolean persistChanged = false;
7956            GrantUri grantUri = new GrantUri(userId, uri, false);
7957
7958            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7959                    new GrantUri(userId, uri, false));
7960            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7961                    new GrantUri(userId, uri, true));
7962
7963            final boolean exactValid = (exactPerm != null)
7964                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7965            final boolean prefixValid = (prefixPerm != null)
7966                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7967
7968            if (!(exactValid || prefixValid)) {
7969                throw new SecurityException("No persistable permission grants found for UID "
7970                        + callingUid + " and Uri " + grantUri.toSafeString());
7971            }
7972
7973            if (exactValid) {
7974                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7975            }
7976            if (prefixValid) {
7977                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7978            }
7979
7980            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7981
7982            if (persistChanged) {
7983                schedulePersistUriGrants();
7984            }
7985        }
7986    }
7987
7988    /**
7989     * @param uri This uri must NOT contain an embedded userId.
7990     * @param userId The userId in which the uri is to be resolved.
7991     */
7992    @Override
7993    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7994        enforceNotIsolatedCaller("releasePersistableUriPermission");
7995
7996        Preconditions.checkFlagsArgument(modeFlags,
7997                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7998
7999        synchronized (this) {
8000            final int callingUid = Binder.getCallingUid();
8001            boolean persistChanged = false;
8002
8003            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8004                    new GrantUri(userId, uri, false));
8005            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8006                    new GrantUri(userId, uri, true));
8007            if (exactPerm == null && prefixPerm == null) {
8008                throw new SecurityException("No permission grants found for UID " + callingUid
8009                        + " and Uri " + uri.toSafeString());
8010            }
8011
8012            if (exactPerm != null) {
8013                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8014                removeUriPermissionIfNeededLocked(exactPerm);
8015            }
8016            if (prefixPerm != null) {
8017                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8018                removeUriPermissionIfNeededLocked(prefixPerm);
8019            }
8020
8021            if (persistChanged) {
8022                schedulePersistUriGrants();
8023            }
8024        }
8025    }
8026
8027    /**
8028     * Prune any older {@link UriPermission} for the given UID until outstanding
8029     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8030     *
8031     * @return if any mutations occured that require persisting.
8032     */
8033    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8034        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8035        if (perms == null) return false;
8036        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8037
8038        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8039        for (UriPermission perm : perms.values()) {
8040            if (perm.persistedModeFlags != 0) {
8041                persisted.add(perm);
8042            }
8043        }
8044
8045        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8046        if (trimCount <= 0) return false;
8047
8048        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8049        for (int i = 0; i < trimCount; i++) {
8050            final UriPermission perm = persisted.get(i);
8051
8052            if (DEBUG_URI_PERMISSION) {
8053                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8054            }
8055
8056            perm.releasePersistableModes(~0);
8057            removeUriPermissionIfNeededLocked(perm);
8058        }
8059
8060        return true;
8061    }
8062
8063    @Override
8064    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8065            String packageName, boolean incoming) {
8066        enforceNotIsolatedCaller("getPersistedUriPermissions");
8067        Preconditions.checkNotNull(packageName, "packageName");
8068
8069        final int callingUid = Binder.getCallingUid();
8070        final IPackageManager pm = AppGlobals.getPackageManager();
8071        try {
8072            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8073            if (packageUid != callingUid) {
8074                throw new SecurityException(
8075                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8076            }
8077        } catch (RemoteException e) {
8078            throw new SecurityException("Failed to verify package name ownership");
8079        }
8080
8081        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8082        synchronized (this) {
8083            if (incoming) {
8084                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8085                        callingUid);
8086                if (perms == null) {
8087                    Slog.w(TAG, "No permission grants found for " + packageName);
8088                } else {
8089                    for (UriPermission perm : perms.values()) {
8090                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8091                            result.add(perm.buildPersistedPublicApiObject());
8092                        }
8093                    }
8094                }
8095            } else {
8096                final int size = mGrantedUriPermissions.size();
8097                for (int i = 0; i < size; i++) {
8098                    final ArrayMap<GrantUri, UriPermission> perms =
8099                            mGrantedUriPermissions.valueAt(i);
8100                    for (UriPermission perm : perms.values()) {
8101                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8102                            result.add(perm.buildPersistedPublicApiObject());
8103                        }
8104                    }
8105                }
8106            }
8107        }
8108        return new ParceledListSlice<android.content.UriPermission>(result);
8109    }
8110
8111    @Override
8112    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8113        synchronized (this) {
8114            ProcessRecord app =
8115                who != null ? getRecordForAppLocked(who) : null;
8116            if (app == null) return;
8117
8118            Message msg = Message.obtain();
8119            msg.what = WAIT_FOR_DEBUGGER_MSG;
8120            msg.obj = app;
8121            msg.arg1 = waiting ? 1 : 0;
8122            mHandler.sendMessage(msg);
8123        }
8124    }
8125
8126    @Override
8127    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8128        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8129        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8130        outInfo.availMem = Process.getFreeMemory();
8131        outInfo.totalMem = Process.getTotalMemory();
8132        outInfo.threshold = homeAppMem;
8133        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8134        outInfo.hiddenAppThreshold = cachedAppMem;
8135        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8136                ProcessList.SERVICE_ADJ);
8137        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8138                ProcessList.VISIBLE_APP_ADJ);
8139        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8140                ProcessList.FOREGROUND_APP_ADJ);
8141    }
8142
8143    // =========================================================
8144    // TASK MANAGEMENT
8145    // =========================================================
8146
8147    @Override
8148    public List<IAppTask> getAppTasks(String callingPackage) {
8149        int callingUid = Binder.getCallingUid();
8150        long ident = Binder.clearCallingIdentity();
8151
8152        synchronized(this) {
8153            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8154            try {
8155                if (localLOGV) Slog.v(TAG, "getAppTasks");
8156
8157                final int N = mRecentTasks.size();
8158                for (int i = 0; i < N; i++) {
8159                    TaskRecord tr = mRecentTasks.get(i);
8160                    // Skip tasks that do not match the caller.  We don't need to verify
8161                    // callingPackage, because we are also limiting to callingUid and know
8162                    // that will limit to the correct security sandbox.
8163                    if (tr.effectiveUid != callingUid) {
8164                        continue;
8165                    }
8166                    Intent intent = tr.getBaseIntent();
8167                    if (intent == null ||
8168                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8169                        continue;
8170                    }
8171                    ActivityManager.RecentTaskInfo taskInfo =
8172                            createRecentTaskInfoFromTaskRecord(tr);
8173                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8174                    list.add(taskImpl);
8175                }
8176            } finally {
8177                Binder.restoreCallingIdentity(ident);
8178            }
8179            return list;
8180        }
8181    }
8182
8183    @Override
8184    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8185        final int callingUid = Binder.getCallingUid();
8186        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8187
8188        synchronized(this) {
8189            if (localLOGV) Slog.v(
8190                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8191
8192            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8193                    callingUid);
8194
8195            // TODO: Improve with MRU list from all ActivityStacks.
8196            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8197        }
8198
8199        return list;
8200    }
8201
8202    TaskRecord getMostRecentTask() {
8203        return mRecentTasks.get(0);
8204    }
8205
8206    /**
8207     * Creates a new RecentTaskInfo from a TaskRecord.
8208     */
8209    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8210        // Update the task description to reflect any changes in the task stack
8211        tr.updateTaskDescription();
8212
8213        // Compose the recent task info
8214        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8215        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8216        rti.persistentId = tr.taskId;
8217        rti.baseIntent = new Intent(tr.getBaseIntent());
8218        rti.origActivity = tr.origActivity;
8219        rti.description = tr.lastDescription;
8220        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8221        rti.userId = tr.userId;
8222        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8223        rti.firstActiveTime = tr.firstActiveTime;
8224        rti.lastActiveTime = tr.lastActiveTime;
8225        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8226        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8227        return rti;
8228    }
8229
8230    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8231        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8232                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8233        if (!allowed) {
8234            if (checkPermission(android.Manifest.permission.GET_TASKS,
8235                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8236                // Temporary compatibility: some existing apps on the system image may
8237                // still be requesting the old permission and not switched to the new
8238                // one; if so, we'll still allow them full access.  This means we need
8239                // to see if they are holding the old permission and are a system app.
8240                try {
8241                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8242                        allowed = true;
8243                        Slog.w(TAG, caller + ": caller " + callingUid
8244                                + " is using old GET_TASKS but privileged; allowing");
8245                    }
8246                } catch (RemoteException e) {
8247                }
8248            }
8249        }
8250        if (!allowed) {
8251            Slog.w(TAG, caller + ": caller " + callingUid
8252                    + " does not hold GET_TASKS; limiting output");
8253        }
8254        return allowed;
8255    }
8256
8257    @Override
8258    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8259        final int callingUid = Binder.getCallingUid();
8260        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8261                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8262
8263        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8264        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8265        synchronized (this) {
8266            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8267                    callingUid);
8268            final boolean detailed = checkCallingPermission(
8269                    android.Manifest.permission.GET_DETAILED_TASKS)
8270                    == PackageManager.PERMISSION_GRANTED;
8271
8272            final int N = mRecentTasks.size();
8273            ArrayList<ActivityManager.RecentTaskInfo> res
8274                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8275                            maxNum < N ? maxNum : N);
8276
8277            final Set<Integer> includedUsers;
8278            if (includeProfiles) {
8279                includedUsers = getProfileIdsLocked(userId);
8280            } else {
8281                includedUsers = new HashSet<Integer>();
8282            }
8283            includedUsers.add(Integer.valueOf(userId));
8284
8285            for (int i=0; i<N && maxNum > 0; i++) {
8286                TaskRecord tr = mRecentTasks.get(i);
8287                // Only add calling user or related users recent tasks
8288                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8289                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8290                    continue;
8291                }
8292
8293                // Return the entry if desired by the caller.  We always return
8294                // the first entry, because callers always expect this to be the
8295                // foreground app.  We may filter others if the caller has
8296                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8297                // we should exclude the entry.
8298
8299                if (i == 0
8300                        || withExcluded
8301                        || (tr.intent == null)
8302                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8303                                == 0)) {
8304                    if (!allowed) {
8305                        // If the caller doesn't have the GET_TASKS permission, then only
8306                        // allow them to see a small subset of tasks -- their own and home.
8307                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8308                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8309                            continue;
8310                        }
8311                    }
8312                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8313                        if (tr.stack != null && tr.stack.isHomeStack()) {
8314                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8315                            continue;
8316                        }
8317                    }
8318                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8319                        // Don't include auto remove tasks that are finished or finishing.
8320                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8321                                + tr);
8322                        continue;
8323                    }
8324                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8325                            && !tr.isAvailable) {
8326                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8327                        continue;
8328                    }
8329
8330                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8331                    if (!detailed) {
8332                        rti.baseIntent.replaceExtras((Bundle)null);
8333                    }
8334
8335                    res.add(rti);
8336                    maxNum--;
8337                }
8338            }
8339            return res;
8340        }
8341    }
8342
8343    private TaskRecord recentTaskForIdLocked(int id) {
8344        final int N = mRecentTasks.size();
8345            for (int i=0; i<N; i++) {
8346                TaskRecord tr = mRecentTasks.get(i);
8347                if (tr.taskId == id) {
8348                    return tr;
8349                }
8350            }
8351            return null;
8352    }
8353
8354    @Override
8355    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8356        synchronized (this) {
8357            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8358                    "getTaskThumbnail()");
8359            TaskRecord tr = recentTaskForIdLocked(id);
8360            if (tr != null) {
8361                return tr.getTaskThumbnailLocked();
8362            }
8363        }
8364        return null;
8365    }
8366
8367    @Override
8368    public int addAppTask(IBinder activityToken, Intent intent,
8369            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8370        final int callingUid = Binder.getCallingUid();
8371        final long callingIdent = Binder.clearCallingIdentity();
8372
8373        try {
8374            synchronized (this) {
8375                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8376                if (r == null) {
8377                    throw new IllegalArgumentException("Activity does not exist; token="
8378                            + activityToken);
8379                }
8380                ComponentName comp = intent.getComponent();
8381                if (comp == null) {
8382                    throw new IllegalArgumentException("Intent " + intent
8383                            + " must specify explicit component");
8384                }
8385                if (thumbnail.getWidth() != mThumbnailWidth
8386                        || thumbnail.getHeight() != mThumbnailHeight) {
8387                    throw new IllegalArgumentException("Bad thumbnail size: got "
8388                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8389                            + mThumbnailWidth + "x" + mThumbnailHeight);
8390                }
8391                if (intent.getSelector() != null) {
8392                    intent.setSelector(null);
8393                }
8394                if (intent.getSourceBounds() != null) {
8395                    intent.setSourceBounds(null);
8396                }
8397                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8398                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8399                        // The caller has added this as an auto-remove task...  that makes no
8400                        // sense, so turn off auto-remove.
8401                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8402                    }
8403                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8404                    // Must be a new task.
8405                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8406                }
8407                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8408                    mLastAddedTaskActivity = null;
8409                }
8410                ActivityInfo ainfo = mLastAddedTaskActivity;
8411                if (ainfo == null) {
8412                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8413                            comp, 0, UserHandle.getUserId(callingUid));
8414                    if (ainfo.applicationInfo.uid != callingUid) {
8415                        throw new SecurityException(
8416                                "Can't add task for another application: target uid="
8417                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8418                    }
8419                }
8420
8421                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8422                        intent, description);
8423
8424                int trimIdx = trimRecentsForTask(task, false);
8425                if (trimIdx >= 0) {
8426                    // If this would have caused a trim, then we'll abort because that
8427                    // means it would be added at the end of the list but then just removed.
8428                    return -1;
8429                }
8430
8431                final int N = mRecentTasks.size();
8432                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8433                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8434                    tr.removedFromRecents(mTaskPersister);
8435                }
8436
8437                task.inRecents = true;
8438                mRecentTasks.add(task);
8439                r.task.stack.addTask(task, false, false);
8440
8441                task.setLastThumbnail(thumbnail);
8442                task.freeLastThumbnail();
8443
8444                return task.taskId;
8445            }
8446        } finally {
8447            Binder.restoreCallingIdentity(callingIdent);
8448        }
8449    }
8450
8451    @Override
8452    public Point getAppTaskThumbnailSize() {
8453        synchronized (this) {
8454            return new Point(mThumbnailWidth,  mThumbnailHeight);
8455        }
8456    }
8457
8458    @Override
8459    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8460        synchronized (this) {
8461            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8462            if (r != null) {
8463                r.setTaskDescription(td);
8464                r.task.updateTaskDescription();
8465            }
8466        }
8467    }
8468
8469    @Override
8470    public Bitmap getTaskDescriptionIcon(String filename) {
8471        if (!FileUtils.isValidExtFilename(filename)
8472                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8473            throw new IllegalArgumentException("Bad filename: " + filename);
8474        }
8475        return mTaskPersister.getTaskDescriptionIcon(filename);
8476    }
8477
8478    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8479        mRecentTasks.remove(tr);
8480        tr.removedFromRecents(mTaskPersister);
8481        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8482        Intent baseIntent = new Intent(
8483                tr.intent != null ? tr.intent : tr.affinityIntent);
8484        ComponentName component = baseIntent.getComponent();
8485        if (component == null) {
8486            Slog.w(TAG, "Now component for base intent of task: " + tr);
8487            return;
8488        }
8489
8490        // Find any running services associated with this app.
8491        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8492
8493        if (killProcesses) {
8494            // Find any running processes associated with this app.
8495            final String pkg = component.getPackageName();
8496            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8497            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8498            for (int i=0; i<pmap.size(); i++) {
8499                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8500                for (int j=0; j<uids.size(); j++) {
8501                    ProcessRecord proc = uids.valueAt(j);
8502                    if (proc.userId != tr.userId) {
8503                        continue;
8504                    }
8505                    if (!proc.pkgList.containsKey(pkg)) {
8506                        continue;
8507                    }
8508                    procs.add(proc);
8509                }
8510            }
8511
8512            // Kill the running processes.
8513            for (int i=0; i<procs.size(); i++) {
8514                ProcessRecord pr = procs.get(i);
8515                if (pr == mHomeProcess) {
8516                    // Don't kill the home process along with tasks from the same package.
8517                    continue;
8518                }
8519                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8520                    pr.kill("remove task", true);
8521                } else {
8522                    pr.waitingToKill = "remove task";
8523                }
8524            }
8525        }
8526    }
8527
8528    /**
8529     * Removes the task with the specified task id.
8530     *
8531     * @param taskId Identifier of the task to be removed.
8532     * @param flags Additional operational flags.  May be 0 or
8533     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8534     * @return Returns true if the given task was found and removed.
8535     */
8536    private boolean removeTaskByIdLocked(int taskId, int flags) {
8537        TaskRecord tr = recentTaskForIdLocked(taskId);
8538        if (tr != null) {
8539            tr.removeTaskActivitiesLocked();
8540            cleanUpRemovedTaskLocked(tr, flags);
8541            if (tr.isPersistable) {
8542                notifyTaskPersisterLocked(null, true);
8543            }
8544            return true;
8545        }
8546        return false;
8547    }
8548
8549    @Override
8550    public boolean removeTask(int taskId, int flags) {
8551        synchronized (this) {
8552            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8553                    "removeTask()");
8554            long ident = Binder.clearCallingIdentity();
8555            try {
8556                return removeTaskByIdLocked(taskId, flags);
8557            } finally {
8558                Binder.restoreCallingIdentity(ident);
8559            }
8560        }
8561    }
8562
8563    /**
8564     * TODO: Add mController hook
8565     */
8566    @Override
8567    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8568        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8569                "moveTaskToFront()");
8570
8571        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8572        synchronized(this) {
8573            moveTaskToFrontLocked(taskId, flags, options);
8574        }
8575    }
8576
8577    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8578        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8579                Binder.getCallingUid(), -1, -1, "Task to front")) {
8580            ActivityOptions.abort(options);
8581            return;
8582        }
8583        final long origId = Binder.clearCallingIdentity();
8584        try {
8585            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8586            if (task == null) {
8587                return;
8588            }
8589            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8590                mStackSupervisor.showLockTaskToast();
8591                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8592                return;
8593            }
8594            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8595            if (prev != null && prev.isRecentsActivity()) {
8596                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8597            }
8598            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8599        } finally {
8600            Binder.restoreCallingIdentity(origId);
8601        }
8602        ActivityOptions.abort(options);
8603    }
8604
8605    @Override
8606    public void moveTaskToBack(int taskId) {
8607        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8608                "moveTaskToBack()");
8609
8610        synchronized(this) {
8611            TaskRecord tr = recentTaskForIdLocked(taskId);
8612            if (tr != null) {
8613                if (tr == mStackSupervisor.mLockTaskModeTask) {
8614                    mStackSupervisor.showLockTaskToast();
8615                    return;
8616                }
8617                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8618                ActivityStack stack = tr.stack;
8619                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8620                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8621                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8622                        return;
8623                    }
8624                }
8625                final long origId = Binder.clearCallingIdentity();
8626                try {
8627                    stack.moveTaskToBackLocked(taskId, null);
8628                } finally {
8629                    Binder.restoreCallingIdentity(origId);
8630                }
8631            }
8632        }
8633    }
8634
8635    /**
8636     * Moves an activity, and all of the other activities within the same task, to the bottom
8637     * of the history stack.  The activity's order within the task is unchanged.
8638     *
8639     * @param token A reference to the activity we wish to move
8640     * @param nonRoot If false then this only works if the activity is the root
8641     *                of a task; if true it will work for any activity in a task.
8642     * @return Returns true if the move completed, false if not.
8643     */
8644    @Override
8645    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8646        enforceNotIsolatedCaller("moveActivityTaskToBack");
8647        synchronized(this) {
8648            final long origId = Binder.clearCallingIdentity();
8649            try {
8650                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8651                if (taskId >= 0) {
8652                    if ((mStackSupervisor.mLockTaskModeTask != null)
8653                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8654                        mStackSupervisor.showLockTaskToast();
8655                        return false;
8656                    }
8657                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8658                }
8659            } finally {
8660                Binder.restoreCallingIdentity(origId);
8661            }
8662        }
8663        return false;
8664    }
8665
8666    @Override
8667    public void moveTaskBackwards(int task) {
8668        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8669                "moveTaskBackwards()");
8670
8671        synchronized(this) {
8672            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8673                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8674                return;
8675            }
8676            final long origId = Binder.clearCallingIdentity();
8677            moveTaskBackwardsLocked(task);
8678            Binder.restoreCallingIdentity(origId);
8679        }
8680    }
8681
8682    private final void moveTaskBackwardsLocked(int task) {
8683        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8684    }
8685
8686    @Override
8687    public IBinder getHomeActivityToken() throws RemoteException {
8688        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8689                "getHomeActivityToken()");
8690        synchronized (this) {
8691            return mStackSupervisor.getHomeActivityToken();
8692        }
8693    }
8694
8695    @Override
8696    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8697            IActivityContainerCallback callback) throws RemoteException {
8698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8699                "createActivityContainer()");
8700        synchronized (this) {
8701            if (parentActivityToken == null) {
8702                throw new IllegalArgumentException("parent token must not be null");
8703            }
8704            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8705            if (r == null) {
8706                return null;
8707            }
8708            if (callback == null) {
8709                throw new IllegalArgumentException("callback must not be null");
8710            }
8711            return mStackSupervisor.createActivityContainer(r, callback);
8712        }
8713    }
8714
8715    @Override
8716    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8718                "deleteActivityContainer()");
8719        synchronized (this) {
8720            mStackSupervisor.deleteActivityContainer(container);
8721        }
8722    }
8723
8724    @Override
8725    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8726            throws RemoteException {
8727        synchronized (this) {
8728            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8729            if (stack != null) {
8730                return stack.mActivityContainer;
8731            }
8732            return null;
8733        }
8734    }
8735
8736    @Override
8737    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8738        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8739                "moveTaskToStack()");
8740        if (stackId == HOME_STACK_ID) {
8741            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8742                    new RuntimeException("here").fillInStackTrace());
8743        }
8744        synchronized (this) {
8745            long ident = Binder.clearCallingIdentity();
8746            try {
8747                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8748                        + stackId + " toTop=" + toTop);
8749                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8750            } finally {
8751                Binder.restoreCallingIdentity(ident);
8752            }
8753        }
8754    }
8755
8756    @Override
8757    public void resizeStack(int stackBoxId, Rect bounds) {
8758        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8759                "resizeStackBox()");
8760        long ident = Binder.clearCallingIdentity();
8761        try {
8762            mWindowManager.resizeStack(stackBoxId, bounds);
8763        } finally {
8764            Binder.restoreCallingIdentity(ident);
8765        }
8766    }
8767
8768    @Override
8769    public List<StackInfo> getAllStackInfos() {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "getAllStackInfos()");
8772        long ident = Binder.clearCallingIdentity();
8773        try {
8774            synchronized (this) {
8775                return mStackSupervisor.getAllStackInfosLocked();
8776            }
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public StackInfo getStackInfo(int stackId) {
8784        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8785                "getStackInfo()");
8786        long ident = Binder.clearCallingIdentity();
8787        try {
8788            synchronized (this) {
8789                return mStackSupervisor.getStackInfoLocked(stackId);
8790            }
8791        } finally {
8792            Binder.restoreCallingIdentity(ident);
8793        }
8794    }
8795
8796    @Override
8797    public boolean isInHomeStack(int taskId) {
8798        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8799                "getStackInfo()");
8800        long ident = Binder.clearCallingIdentity();
8801        try {
8802            synchronized (this) {
8803                TaskRecord tr = recentTaskForIdLocked(taskId);
8804                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8805            }
8806        } finally {
8807            Binder.restoreCallingIdentity(ident);
8808        }
8809    }
8810
8811    @Override
8812    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8813        synchronized(this) {
8814            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8815        }
8816    }
8817
8818    private boolean isLockTaskAuthorized(String pkg) {
8819        final DevicePolicyManager dpm = (DevicePolicyManager)
8820                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8821        try {
8822            int uid = mContext.getPackageManager().getPackageUid(pkg,
8823                    Binder.getCallingUserHandle().getIdentifier());
8824            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8825        } catch (NameNotFoundException e) {
8826            return false;
8827        }
8828    }
8829
8830    void startLockTaskMode(TaskRecord task) {
8831        final String pkg;
8832        synchronized (this) {
8833            pkg = task.intent.getComponent().getPackageName();
8834        }
8835        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8836        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8837            final TaskRecord taskRecord = task;
8838            mHandler.post(new Runnable() {
8839                @Override
8840                public void run() {
8841                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8842                }
8843            });
8844            return;
8845        }
8846        long ident = Binder.clearCallingIdentity();
8847        try {
8848            synchronized (this) {
8849                // Since we lost lock on task, make sure it is still there.
8850                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8851                if (task != null) {
8852                    if (!isSystemInitiated
8853                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8854                        throw new IllegalArgumentException("Invalid task, not in foreground");
8855                    }
8856                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8857                }
8858            }
8859        } finally {
8860            Binder.restoreCallingIdentity(ident);
8861        }
8862    }
8863
8864    @Override
8865    public void startLockTaskMode(int taskId) {
8866        final TaskRecord task;
8867        long ident = Binder.clearCallingIdentity();
8868        try {
8869            synchronized (this) {
8870                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8871            }
8872        } finally {
8873            Binder.restoreCallingIdentity(ident);
8874        }
8875        if (task != null) {
8876            startLockTaskMode(task);
8877        }
8878    }
8879
8880    @Override
8881    public void startLockTaskMode(IBinder token) {
8882        final TaskRecord task;
8883        long ident = Binder.clearCallingIdentity();
8884        try {
8885            synchronized (this) {
8886                final ActivityRecord r = ActivityRecord.forToken(token);
8887                if (r == null) {
8888                    return;
8889                }
8890                task = r.task;
8891            }
8892        } finally {
8893            Binder.restoreCallingIdentity(ident);
8894        }
8895        if (task != null) {
8896            startLockTaskMode(task);
8897        }
8898    }
8899
8900    @Override
8901    public void startLockTaskModeOnCurrent() throws RemoteException {
8902        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8903                "startLockTaskModeOnCurrent");
8904        ActivityRecord r = null;
8905        synchronized (this) {
8906            r = mStackSupervisor.topRunningActivityLocked();
8907        }
8908        startLockTaskMode(r.task);
8909    }
8910
8911    @Override
8912    public void stopLockTaskMode() {
8913        // Verify that the user matches the package of the intent for the TaskRecord
8914        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8915        // and stopLockTaskMode.
8916        final int callingUid = Binder.getCallingUid();
8917        if (callingUid != Process.SYSTEM_UID) {
8918            try {
8919                String pkg =
8920                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8921                int uid = mContext.getPackageManager().getPackageUid(pkg,
8922                        Binder.getCallingUserHandle().getIdentifier());
8923                if (uid != callingUid) {
8924                    throw new SecurityException("Invalid uid, expected " + uid);
8925                }
8926            } catch (NameNotFoundException e) {
8927                Log.d(TAG, "stopLockTaskMode " + e);
8928                return;
8929            }
8930        }
8931        long ident = Binder.clearCallingIdentity();
8932        try {
8933            Log.d(TAG, "stopLockTaskMode");
8934            // Stop lock task
8935            synchronized (this) {
8936                mStackSupervisor.setLockTaskModeLocked(null, false);
8937            }
8938        } finally {
8939            Binder.restoreCallingIdentity(ident);
8940        }
8941    }
8942
8943    @Override
8944    public void stopLockTaskModeOnCurrent() throws RemoteException {
8945        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8946                "stopLockTaskModeOnCurrent");
8947        long ident = Binder.clearCallingIdentity();
8948        try {
8949            stopLockTaskMode();
8950        } finally {
8951            Binder.restoreCallingIdentity(ident);
8952        }
8953    }
8954
8955    @Override
8956    public boolean isInLockTaskMode() {
8957        synchronized (this) {
8958            return mStackSupervisor.isInLockTaskMode();
8959        }
8960    }
8961
8962    // =========================================================
8963    // CONTENT PROVIDERS
8964    // =========================================================
8965
8966    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8967        List<ProviderInfo> providers = null;
8968        try {
8969            providers = AppGlobals.getPackageManager().
8970                queryContentProviders(app.processName, app.uid,
8971                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8972        } catch (RemoteException ex) {
8973        }
8974        if (DEBUG_MU)
8975            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8976        int userId = app.userId;
8977        if (providers != null) {
8978            int N = providers.size();
8979            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8980            for (int i=0; i<N; i++) {
8981                ProviderInfo cpi =
8982                    (ProviderInfo)providers.get(i);
8983                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8984                        cpi.name, cpi.flags);
8985                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8986                    // This is a singleton provider, but a user besides the
8987                    // default user is asking to initialize a process it runs
8988                    // in...  well, no, it doesn't actually run in this process,
8989                    // it runs in the process of the default user.  Get rid of it.
8990                    providers.remove(i);
8991                    N--;
8992                    i--;
8993                    continue;
8994                }
8995
8996                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8997                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8998                if (cpr == null) {
8999                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9000                    mProviderMap.putProviderByClass(comp, cpr);
9001                }
9002                if (DEBUG_MU)
9003                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9004                app.pubProviders.put(cpi.name, cpr);
9005                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9006                    // Don't add this if it is a platform component that is marked
9007                    // to run in multiple processes, because this is actually
9008                    // part of the framework so doesn't make sense to track as a
9009                    // separate apk in the process.
9010                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9011                            mProcessStats);
9012                }
9013                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9014            }
9015        }
9016        return providers;
9017    }
9018
9019    /**
9020     * Check if {@link ProcessRecord} has a possible chance at accessing the
9021     * given {@link ProviderInfo}. Final permission checking is always done
9022     * in {@link ContentProvider}.
9023     */
9024    private final String checkContentProviderPermissionLocked(
9025            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9026        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9027        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9028        boolean checkedGrants = false;
9029        if (checkUser) {
9030            // Looking for cross-user grants before enforcing the typical cross-users permissions
9031            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9032            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9033                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9034                    return null;
9035                }
9036                checkedGrants = true;
9037            }
9038            userId = handleIncomingUser(callingPid, callingUid, userId,
9039                    false, ALLOW_NON_FULL,
9040                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9041            if (userId != tmpTargetUserId) {
9042                // When we actually went to determine the final targer user ID, this ended
9043                // up different than our initial check for the authority.  This is because
9044                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9045                // SELF.  So we need to re-check the grants again.
9046                checkedGrants = false;
9047            }
9048        }
9049        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9050                cpi.applicationInfo.uid, cpi.exported)
9051                == PackageManager.PERMISSION_GRANTED) {
9052            return null;
9053        }
9054        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9055                cpi.applicationInfo.uid, cpi.exported)
9056                == PackageManager.PERMISSION_GRANTED) {
9057            return null;
9058        }
9059
9060        PathPermission[] pps = cpi.pathPermissions;
9061        if (pps != null) {
9062            int i = pps.length;
9063            while (i > 0) {
9064                i--;
9065                PathPermission pp = pps[i];
9066                String pprperm = pp.getReadPermission();
9067                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9068                        cpi.applicationInfo.uid, cpi.exported)
9069                        == PackageManager.PERMISSION_GRANTED) {
9070                    return null;
9071                }
9072                String ppwperm = pp.getWritePermission();
9073                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9074                        cpi.applicationInfo.uid, cpi.exported)
9075                        == PackageManager.PERMISSION_GRANTED) {
9076                    return null;
9077                }
9078            }
9079        }
9080        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9081            return null;
9082        }
9083
9084        String msg;
9085        if (!cpi.exported) {
9086            msg = "Permission Denial: opening provider " + cpi.name
9087                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9088                    + ", uid=" + callingUid + ") that is not exported from uid "
9089                    + cpi.applicationInfo.uid;
9090        } else {
9091            msg = "Permission Denial: opening provider " + cpi.name
9092                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9093                    + ", uid=" + callingUid + ") requires "
9094                    + cpi.readPermission + " or " + cpi.writePermission;
9095        }
9096        Slog.w(TAG, msg);
9097        return msg;
9098    }
9099
9100    /**
9101     * Returns if the ContentProvider has granted a uri to callingUid
9102     */
9103    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9104        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9105        if (perms != null) {
9106            for (int i=perms.size()-1; i>=0; i--) {
9107                GrantUri grantUri = perms.keyAt(i);
9108                if (grantUri.sourceUserId == userId || !checkUser) {
9109                    if (matchesProvider(grantUri.uri, cpi)) {
9110                        return true;
9111                    }
9112                }
9113            }
9114        }
9115        return false;
9116    }
9117
9118    /**
9119     * Returns true if the uri authority is one of the authorities specified in the provider.
9120     */
9121    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9122        String uriAuth = uri.getAuthority();
9123        String cpiAuth = cpi.authority;
9124        if (cpiAuth.indexOf(';') == -1) {
9125            return cpiAuth.equals(uriAuth);
9126        }
9127        String[] cpiAuths = cpiAuth.split(";");
9128        int length = cpiAuths.length;
9129        for (int i = 0; i < length; i++) {
9130            if (cpiAuths[i].equals(uriAuth)) return true;
9131        }
9132        return false;
9133    }
9134
9135    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9136            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9137        if (r != null) {
9138            for (int i=0; i<r.conProviders.size(); i++) {
9139                ContentProviderConnection conn = r.conProviders.get(i);
9140                if (conn.provider == cpr) {
9141                    if (DEBUG_PROVIDER) Slog.v(TAG,
9142                            "Adding provider requested by "
9143                            + r.processName + " from process "
9144                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9145                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9146                    if (stable) {
9147                        conn.stableCount++;
9148                        conn.numStableIncs++;
9149                    } else {
9150                        conn.unstableCount++;
9151                        conn.numUnstableIncs++;
9152                    }
9153                    return conn;
9154                }
9155            }
9156            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9157            if (stable) {
9158                conn.stableCount = 1;
9159                conn.numStableIncs = 1;
9160            } else {
9161                conn.unstableCount = 1;
9162                conn.numUnstableIncs = 1;
9163            }
9164            cpr.connections.add(conn);
9165            r.conProviders.add(conn);
9166            return conn;
9167        }
9168        cpr.addExternalProcessHandleLocked(externalProcessToken);
9169        return null;
9170    }
9171
9172    boolean decProviderCountLocked(ContentProviderConnection conn,
9173            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9174        if (conn != null) {
9175            cpr = conn.provider;
9176            if (DEBUG_PROVIDER) Slog.v(TAG,
9177                    "Removing provider requested by "
9178                    + conn.client.processName + " from process "
9179                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9180                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9181            if (stable) {
9182                conn.stableCount--;
9183            } else {
9184                conn.unstableCount--;
9185            }
9186            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9187                cpr.connections.remove(conn);
9188                conn.client.conProviders.remove(conn);
9189                return true;
9190            }
9191            return false;
9192        }
9193        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9194        return false;
9195    }
9196
9197    private void checkTime(long startTime, String where) {
9198        long now = SystemClock.elapsedRealtime();
9199        if ((now-startTime) > 1000) {
9200            // If we are taking more than a second, log about it.
9201            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9202        }
9203    }
9204
9205    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9206            String name, IBinder token, boolean stable, int userId) {
9207        ContentProviderRecord cpr;
9208        ContentProviderConnection conn = null;
9209        ProviderInfo cpi = null;
9210
9211        synchronized(this) {
9212            long startTime = SystemClock.elapsedRealtime();
9213
9214            ProcessRecord r = null;
9215            if (caller != null) {
9216                r = getRecordForAppLocked(caller);
9217                if (r == null) {
9218                    throw new SecurityException(
9219                            "Unable to find app for caller " + caller
9220                          + " (pid=" + Binder.getCallingPid()
9221                          + ") when getting content provider " + name);
9222                }
9223            }
9224
9225            boolean checkCrossUser = true;
9226
9227            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9228
9229            // First check if this content provider has been published...
9230            cpr = mProviderMap.getProviderByName(name, userId);
9231            // If that didn't work, check if it exists for user 0 and then
9232            // verify that it's a singleton provider before using it.
9233            if (cpr == null && userId != UserHandle.USER_OWNER) {
9234                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9235                if (cpr != null) {
9236                    cpi = cpr.info;
9237                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9238                            cpi.name, cpi.flags)
9239                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9240                        userId = UserHandle.USER_OWNER;
9241                        checkCrossUser = false;
9242                    } else {
9243                        cpr = null;
9244                        cpi = null;
9245                    }
9246                }
9247            }
9248
9249            boolean providerRunning = cpr != null;
9250            if (providerRunning) {
9251                cpi = cpr.info;
9252                String msg;
9253                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9254                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9255                        != null) {
9256                    throw new SecurityException(msg);
9257                }
9258                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9259
9260                if (r != null && cpr.canRunHere(r)) {
9261                    // This provider has been published or is in the process
9262                    // of being published...  but it is also allowed to run
9263                    // in the caller's process, so don't make a connection
9264                    // and just let the caller instantiate its own instance.
9265                    ContentProviderHolder holder = cpr.newHolder(null);
9266                    // don't give caller the provider object, it needs
9267                    // to make its own.
9268                    holder.provider = null;
9269                    return holder;
9270                }
9271
9272                final long origId = Binder.clearCallingIdentity();
9273
9274                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9275
9276                // In this case the provider instance already exists, so we can
9277                // return it right away.
9278                conn = incProviderCountLocked(r, cpr, token, stable);
9279                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9280                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9281                        // If this is a perceptible app accessing the provider,
9282                        // make sure to count it as being accessed and thus
9283                        // back up on the LRU list.  This is good because
9284                        // content providers are often expensive to start.
9285                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9286                        updateLruProcessLocked(cpr.proc, false, null);
9287                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9288                    }
9289                }
9290
9291                if (cpr.proc != null) {
9292                    if (false) {
9293                        if (cpr.name.flattenToShortString().equals(
9294                                "com.android.providers.calendar/.CalendarProvider2")) {
9295                            Slog.v(TAG, "****************** KILLING "
9296                                + cpr.name.flattenToShortString());
9297                            Process.killProcess(cpr.proc.pid);
9298                        }
9299                    }
9300                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9301                    boolean success = updateOomAdjLocked(cpr.proc);
9302                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9303                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9304                    // NOTE: there is still a race here where a signal could be
9305                    // pending on the process even though we managed to update its
9306                    // adj level.  Not sure what to do about this, but at least
9307                    // the race is now smaller.
9308                    if (!success) {
9309                        // Uh oh...  it looks like the provider's process
9310                        // has been killed on us.  We need to wait for a new
9311                        // process to be started, and make sure its death
9312                        // doesn't kill our process.
9313                        Slog.i(TAG,
9314                                "Existing provider " + cpr.name.flattenToShortString()
9315                                + " is crashing; detaching " + r);
9316                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9317                        checkTime(startTime, "getContentProviderImpl: before appDied");
9318                        appDiedLocked(cpr.proc);
9319                        checkTime(startTime, "getContentProviderImpl: after appDied");
9320                        if (!lastRef) {
9321                            // This wasn't the last ref our process had on
9322                            // the provider...  we have now been killed, bail.
9323                            return null;
9324                        }
9325                        providerRunning = false;
9326                        conn = null;
9327                    }
9328                }
9329
9330                Binder.restoreCallingIdentity(origId);
9331            }
9332
9333            boolean singleton;
9334            if (!providerRunning) {
9335                try {
9336                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9337                    cpi = AppGlobals.getPackageManager().
9338                        resolveContentProvider(name,
9339                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9340                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9341                } catch (RemoteException ex) {
9342                }
9343                if (cpi == null) {
9344                    return null;
9345                }
9346                // If the provider is a singleton AND
9347                // (it's a call within the same user || the provider is a
9348                // privileged app)
9349                // Then allow connecting to the singleton provider
9350                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9351                        cpi.name, cpi.flags)
9352                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9353                if (singleton) {
9354                    userId = UserHandle.USER_OWNER;
9355                }
9356                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9357                checkTime(startTime, "getContentProviderImpl: got app info for user");
9358
9359                String msg;
9360                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9361                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9362                        != null) {
9363                    throw new SecurityException(msg);
9364                }
9365                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9366
9367                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9368                        && !cpi.processName.equals("system")) {
9369                    // If this content provider does not run in the system
9370                    // process, and the system is not yet ready to run other
9371                    // processes, then fail fast instead of hanging.
9372                    throw new IllegalArgumentException(
9373                            "Attempt to launch content provider before system ready");
9374                }
9375
9376                // Make sure that the user who owns this provider is started.  If not,
9377                // we don't want to allow it to run.
9378                if (mStartedUsers.get(userId) == null) {
9379                    Slog.w(TAG, "Unable to launch app "
9380                            + cpi.applicationInfo.packageName + "/"
9381                            + cpi.applicationInfo.uid + " for provider "
9382                            + name + ": user " + userId + " is stopped");
9383                    return null;
9384                }
9385
9386                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9387                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9388                cpr = mProviderMap.getProviderByClass(comp, userId);
9389                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9390                final boolean firstClass = cpr == null;
9391                if (firstClass) {
9392                    final long ident = Binder.clearCallingIdentity();
9393                    try {
9394                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9395                        ApplicationInfo ai =
9396                            AppGlobals.getPackageManager().
9397                                getApplicationInfo(
9398                                        cpi.applicationInfo.packageName,
9399                                        STOCK_PM_FLAGS, userId);
9400                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9401                        if (ai == null) {
9402                            Slog.w(TAG, "No package info for content provider "
9403                                    + cpi.name);
9404                            return null;
9405                        }
9406                        ai = getAppInfoForUser(ai, userId);
9407                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9408                    } catch (RemoteException ex) {
9409                        // pm is in same process, this will never happen.
9410                    } finally {
9411                        Binder.restoreCallingIdentity(ident);
9412                    }
9413                }
9414
9415                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9416
9417                if (r != null && cpr.canRunHere(r)) {
9418                    // If this is a multiprocess provider, then just return its
9419                    // info and allow the caller to instantiate it.  Only do
9420                    // this if the provider is the same user as the caller's
9421                    // process, or can run as root (so can be in any process).
9422                    return cpr.newHolder(null);
9423                }
9424
9425                if (DEBUG_PROVIDER) {
9426                    RuntimeException e = new RuntimeException("here");
9427                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9428                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9429                }
9430
9431                // This is single process, and our app is now connecting to it.
9432                // See if we are already in the process of launching this
9433                // provider.
9434                final int N = mLaunchingProviders.size();
9435                int i;
9436                for (i=0; i<N; i++) {
9437                    if (mLaunchingProviders.get(i) == cpr) {
9438                        break;
9439                    }
9440                }
9441
9442                // If the provider is not already being launched, then get it
9443                // started.
9444                if (i >= N) {
9445                    final long origId = Binder.clearCallingIdentity();
9446
9447                    try {
9448                        // Content provider is now in use, its package can't be stopped.
9449                        try {
9450                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9451                            AppGlobals.getPackageManager().setPackageStoppedState(
9452                                    cpr.appInfo.packageName, false, userId);
9453                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9454                        } catch (RemoteException e) {
9455                        } catch (IllegalArgumentException e) {
9456                            Slog.w(TAG, "Failed trying to unstop package "
9457                                    + cpr.appInfo.packageName + ": " + e);
9458                        }
9459
9460                        // Use existing process if already started
9461                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9462                        ProcessRecord proc = getProcessRecordLocked(
9463                                cpi.processName, cpr.appInfo.uid, false);
9464                        if (proc != null && proc.thread != null) {
9465                            if (DEBUG_PROVIDER) {
9466                                Slog.d(TAG, "Installing in existing process " + proc);
9467                            }
9468                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9469                            proc.pubProviders.put(cpi.name, cpr);
9470                            try {
9471                                proc.thread.scheduleInstallProvider(cpi);
9472                            } catch (RemoteException e) {
9473                            }
9474                        } else {
9475                            checkTime(startTime, "getContentProviderImpl: before start process");
9476                            proc = startProcessLocked(cpi.processName,
9477                                    cpr.appInfo, false, 0, "content provider",
9478                                    new ComponentName(cpi.applicationInfo.packageName,
9479                                            cpi.name), false, false, false);
9480                            checkTime(startTime, "getContentProviderImpl: after start process");
9481                            if (proc == null) {
9482                                Slog.w(TAG, "Unable to launch app "
9483                                        + cpi.applicationInfo.packageName + "/"
9484                                        + cpi.applicationInfo.uid + " for provider "
9485                                        + name + ": process is bad");
9486                                return null;
9487                            }
9488                        }
9489                        cpr.launchingApp = proc;
9490                        mLaunchingProviders.add(cpr);
9491                    } finally {
9492                        Binder.restoreCallingIdentity(origId);
9493                    }
9494                }
9495
9496                checkTime(startTime, "getContentProviderImpl: updating data structures");
9497
9498                // Make sure the provider is published (the same provider class
9499                // may be published under multiple names).
9500                if (firstClass) {
9501                    mProviderMap.putProviderByClass(comp, cpr);
9502                }
9503
9504                mProviderMap.putProviderByName(name, cpr);
9505                conn = incProviderCountLocked(r, cpr, token, stable);
9506                if (conn != null) {
9507                    conn.waiting = true;
9508                }
9509            }
9510            checkTime(startTime, "getContentProviderImpl: done!");
9511        }
9512
9513        // Wait for the provider to be published...
9514        synchronized (cpr) {
9515            while (cpr.provider == null) {
9516                if (cpr.launchingApp == null) {
9517                    Slog.w(TAG, "Unable to launch app "
9518                            + cpi.applicationInfo.packageName + "/"
9519                            + cpi.applicationInfo.uid + " for provider "
9520                            + name + ": launching app became null");
9521                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9522                            UserHandle.getUserId(cpi.applicationInfo.uid),
9523                            cpi.applicationInfo.packageName,
9524                            cpi.applicationInfo.uid, name);
9525                    return null;
9526                }
9527                try {
9528                    if (DEBUG_MU) {
9529                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9530                                + cpr.launchingApp);
9531                    }
9532                    if (conn != null) {
9533                        conn.waiting = true;
9534                    }
9535                    cpr.wait();
9536                } catch (InterruptedException ex) {
9537                } finally {
9538                    if (conn != null) {
9539                        conn.waiting = false;
9540                    }
9541                }
9542            }
9543        }
9544        return cpr != null ? cpr.newHolder(conn) : null;
9545    }
9546
9547    @Override
9548    public final ContentProviderHolder getContentProvider(
9549            IApplicationThread caller, String name, int userId, boolean stable) {
9550        enforceNotIsolatedCaller("getContentProvider");
9551        if (caller == null) {
9552            String msg = "null IApplicationThread when getting content provider "
9553                    + name;
9554            Slog.w(TAG, msg);
9555            throw new SecurityException(msg);
9556        }
9557        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9558        // with cross-user grant.
9559        return getContentProviderImpl(caller, name, null, stable, userId);
9560    }
9561
9562    public ContentProviderHolder getContentProviderExternal(
9563            String name, int userId, IBinder token) {
9564        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9565            "Do not have permission in call getContentProviderExternal()");
9566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9567                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9568        return getContentProviderExternalUnchecked(name, token, userId);
9569    }
9570
9571    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9572            IBinder token, int userId) {
9573        return getContentProviderImpl(null, name, token, true, userId);
9574    }
9575
9576    /**
9577     * Drop a content provider from a ProcessRecord's bookkeeping
9578     */
9579    public void removeContentProvider(IBinder connection, boolean stable) {
9580        enforceNotIsolatedCaller("removeContentProvider");
9581        long ident = Binder.clearCallingIdentity();
9582        try {
9583            synchronized (this) {
9584                ContentProviderConnection conn;
9585                try {
9586                    conn = (ContentProviderConnection)connection;
9587                } catch (ClassCastException e) {
9588                    String msg ="removeContentProvider: " + connection
9589                            + " not a ContentProviderConnection";
9590                    Slog.w(TAG, msg);
9591                    throw new IllegalArgumentException(msg);
9592                }
9593                if (conn == null) {
9594                    throw new NullPointerException("connection is null");
9595                }
9596                if (decProviderCountLocked(conn, null, null, stable)) {
9597                    updateOomAdjLocked();
9598                }
9599            }
9600        } finally {
9601            Binder.restoreCallingIdentity(ident);
9602        }
9603    }
9604
9605    public void removeContentProviderExternal(String name, IBinder token) {
9606        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9607            "Do not have permission in call removeContentProviderExternal()");
9608        int userId = UserHandle.getCallingUserId();
9609        long ident = Binder.clearCallingIdentity();
9610        try {
9611            removeContentProviderExternalUnchecked(name, token, userId);
9612        } finally {
9613            Binder.restoreCallingIdentity(ident);
9614        }
9615    }
9616
9617    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9618        synchronized (this) {
9619            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9620            if(cpr == null) {
9621                //remove from mProvidersByClass
9622                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9623                return;
9624            }
9625
9626            //update content provider record entry info
9627            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9628            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9629            if (localCpr.hasExternalProcessHandles()) {
9630                if (localCpr.removeExternalProcessHandleLocked(token)) {
9631                    updateOomAdjLocked();
9632                } else {
9633                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9634                            + " with no external reference for token: "
9635                            + token + ".");
9636                }
9637            } else {
9638                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9639                        + " with no external references.");
9640            }
9641        }
9642    }
9643
9644    public final void publishContentProviders(IApplicationThread caller,
9645            List<ContentProviderHolder> providers) {
9646        if (providers == null) {
9647            return;
9648        }
9649
9650        enforceNotIsolatedCaller("publishContentProviders");
9651        synchronized (this) {
9652            final ProcessRecord r = getRecordForAppLocked(caller);
9653            if (DEBUG_MU)
9654                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9655            if (r == null) {
9656                throw new SecurityException(
9657                        "Unable to find app for caller " + caller
9658                      + " (pid=" + Binder.getCallingPid()
9659                      + ") when publishing content providers");
9660            }
9661
9662            final long origId = Binder.clearCallingIdentity();
9663
9664            final int N = providers.size();
9665            for (int i=0; i<N; i++) {
9666                ContentProviderHolder src = providers.get(i);
9667                if (src == null || src.info == null || src.provider == null) {
9668                    continue;
9669                }
9670                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9671                if (DEBUG_MU)
9672                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9673                if (dst != null) {
9674                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9675                    mProviderMap.putProviderByClass(comp, dst);
9676                    String names[] = dst.info.authority.split(";");
9677                    for (int j = 0; j < names.length; j++) {
9678                        mProviderMap.putProviderByName(names[j], dst);
9679                    }
9680
9681                    int NL = mLaunchingProviders.size();
9682                    int j;
9683                    for (j=0; j<NL; j++) {
9684                        if (mLaunchingProviders.get(j) == dst) {
9685                            mLaunchingProviders.remove(j);
9686                            j--;
9687                            NL--;
9688                        }
9689                    }
9690                    synchronized (dst) {
9691                        dst.provider = src.provider;
9692                        dst.proc = r;
9693                        dst.notifyAll();
9694                    }
9695                    updateOomAdjLocked(r);
9696                }
9697            }
9698
9699            Binder.restoreCallingIdentity(origId);
9700        }
9701    }
9702
9703    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9704        ContentProviderConnection conn;
9705        try {
9706            conn = (ContentProviderConnection)connection;
9707        } catch (ClassCastException e) {
9708            String msg ="refContentProvider: " + connection
9709                    + " not a ContentProviderConnection";
9710            Slog.w(TAG, msg);
9711            throw new IllegalArgumentException(msg);
9712        }
9713        if (conn == null) {
9714            throw new NullPointerException("connection is null");
9715        }
9716
9717        synchronized (this) {
9718            if (stable > 0) {
9719                conn.numStableIncs += stable;
9720            }
9721            stable = conn.stableCount + stable;
9722            if (stable < 0) {
9723                throw new IllegalStateException("stableCount < 0: " + stable);
9724            }
9725
9726            if (unstable > 0) {
9727                conn.numUnstableIncs += unstable;
9728            }
9729            unstable = conn.unstableCount + unstable;
9730            if (unstable < 0) {
9731                throw new IllegalStateException("unstableCount < 0: " + unstable);
9732            }
9733
9734            if ((stable+unstable) <= 0) {
9735                throw new IllegalStateException("ref counts can't go to zero here: stable="
9736                        + stable + " unstable=" + unstable);
9737            }
9738            conn.stableCount = stable;
9739            conn.unstableCount = unstable;
9740            return !conn.dead;
9741        }
9742    }
9743
9744    public void unstableProviderDied(IBinder connection) {
9745        ContentProviderConnection conn;
9746        try {
9747            conn = (ContentProviderConnection)connection;
9748        } catch (ClassCastException e) {
9749            String msg ="refContentProvider: " + connection
9750                    + " not a ContentProviderConnection";
9751            Slog.w(TAG, msg);
9752            throw new IllegalArgumentException(msg);
9753        }
9754        if (conn == null) {
9755            throw new NullPointerException("connection is null");
9756        }
9757
9758        // Safely retrieve the content provider associated with the connection.
9759        IContentProvider provider;
9760        synchronized (this) {
9761            provider = conn.provider.provider;
9762        }
9763
9764        if (provider == null) {
9765            // Um, yeah, we're way ahead of you.
9766            return;
9767        }
9768
9769        // Make sure the caller is being honest with us.
9770        if (provider.asBinder().pingBinder()) {
9771            // Er, no, still looks good to us.
9772            synchronized (this) {
9773                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9774                        + " says " + conn + " died, but we don't agree");
9775                return;
9776            }
9777        }
9778
9779        // Well look at that!  It's dead!
9780        synchronized (this) {
9781            if (conn.provider.provider != provider) {
9782                // But something changed...  good enough.
9783                return;
9784            }
9785
9786            ProcessRecord proc = conn.provider.proc;
9787            if (proc == null || proc.thread == null) {
9788                // Seems like the process is already cleaned up.
9789                return;
9790            }
9791
9792            // As far as we're concerned, this is just like receiving a
9793            // death notification...  just a bit prematurely.
9794            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9795                    + ") early provider death");
9796            final long ident = Binder.clearCallingIdentity();
9797            try {
9798                appDiedLocked(proc);
9799            } finally {
9800                Binder.restoreCallingIdentity(ident);
9801            }
9802        }
9803    }
9804
9805    @Override
9806    public void appNotRespondingViaProvider(IBinder connection) {
9807        enforceCallingPermission(
9808                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9809
9810        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9811        if (conn == null) {
9812            Slog.w(TAG, "ContentProviderConnection is null");
9813            return;
9814        }
9815
9816        final ProcessRecord host = conn.provider.proc;
9817        if (host == null) {
9818            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9819            return;
9820        }
9821
9822        final long token = Binder.clearCallingIdentity();
9823        try {
9824            appNotResponding(host, null, null, false, "ContentProvider not responding");
9825        } finally {
9826            Binder.restoreCallingIdentity(token);
9827        }
9828    }
9829
9830    public final void installSystemProviders() {
9831        List<ProviderInfo> providers;
9832        synchronized (this) {
9833            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9834            providers = generateApplicationProvidersLocked(app);
9835            if (providers != null) {
9836                for (int i=providers.size()-1; i>=0; i--) {
9837                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9838                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9839                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9840                                + ": not system .apk");
9841                        providers.remove(i);
9842                    }
9843                }
9844            }
9845        }
9846        if (providers != null) {
9847            mSystemThread.installSystemProviders(providers);
9848        }
9849
9850        mCoreSettingsObserver = new CoreSettingsObserver(this);
9851
9852        //mUsageStatsService.monitorPackages();
9853    }
9854
9855    /**
9856     * Allows apps to retrieve the MIME type of a URI.
9857     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9858     * users, then it does not need permission to access the ContentProvider.
9859     * Either, it needs cross-user uri grants.
9860     *
9861     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9862     *
9863     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9864     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9865     */
9866    public String getProviderMimeType(Uri uri, int userId) {
9867        enforceNotIsolatedCaller("getProviderMimeType");
9868        final String name = uri.getAuthority();
9869        int callingUid = Binder.getCallingUid();
9870        int callingPid = Binder.getCallingPid();
9871        long ident = 0;
9872        boolean clearedIdentity = false;
9873        userId = unsafeConvertIncomingUser(userId);
9874        if (canClearIdentity(callingPid, callingUid, userId)) {
9875            clearedIdentity = true;
9876            ident = Binder.clearCallingIdentity();
9877        }
9878        ContentProviderHolder holder = null;
9879        try {
9880            holder = getContentProviderExternalUnchecked(name, null, userId);
9881            if (holder != null) {
9882                return holder.provider.getType(uri);
9883            }
9884        } catch (RemoteException e) {
9885            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9886            return null;
9887        } finally {
9888            // We need to clear the identity to call removeContentProviderExternalUnchecked
9889            if (!clearedIdentity) {
9890                ident = Binder.clearCallingIdentity();
9891            }
9892            try {
9893                if (holder != null) {
9894                    removeContentProviderExternalUnchecked(name, null, userId);
9895                }
9896            } finally {
9897                Binder.restoreCallingIdentity(ident);
9898            }
9899        }
9900
9901        return null;
9902    }
9903
9904    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9905        if (UserHandle.getUserId(callingUid) == userId) {
9906            return true;
9907        }
9908        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9909                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9910                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9911                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9912                return true;
9913        }
9914        return false;
9915    }
9916
9917    // =========================================================
9918    // GLOBAL MANAGEMENT
9919    // =========================================================
9920
9921    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9922            boolean isolated, int isolatedUid) {
9923        String proc = customProcess != null ? customProcess : info.processName;
9924        BatteryStatsImpl.Uid.Proc ps = null;
9925        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9926        int uid = info.uid;
9927        if (isolated) {
9928            if (isolatedUid == 0) {
9929                int userId = UserHandle.getUserId(uid);
9930                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9931                while (true) {
9932                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9933                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9934                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9935                    }
9936                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9937                    mNextIsolatedProcessUid++;
9938                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9939                        // No process for this uid, use it.
9940                        break;
9941                    }
9942                    stepsLeft--;
9943                    if (stepsLeft <= 0) {
9944                        return null;
9945                    }
9946                }
9947            } else {
9948                // Special case for startIsolatedProcess (internal only), where
9949                // the uid of the isolated process is specified by the caller.
9950                uid = isolatedUid;
9951            }
9952        }
9953        return new ProcessRecord(stats, info, proc, uid);
9954    }
9955
9956    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9957            String abiOverride) {
9958        ProcessRecord app;
9959        if (!isolated) {
9960            app = getProcessRecordLocked(info.processName, info.uid, true);
9961        } else {
9962            app = null;
9963        }
9964
9965        if (app == null) {
9966            app = newProcessRecordLocked(info, null, isolated, 0);
9967            mProcessNames.put(info.processName, app.uid, app);
9968            if (isolated) {
9969                mIsolatedProcesses.put(app.uid, app);
9970            }
9971            updateLruProcessLocked(app, false, null);
9972            updateOomAdjLocked();
9973        }
9974
9975        // This package really, really can not be stopped.
9976        try {
9977            AppGlobals.getPackageManager().setPackageStoppedState(
9978                    info.packageName, false, UserHandle.getUserId(app.uid));
9979        } catch (RemoteException e) {
9980        } catch (IllegalArgumentException e) {
9981            Slog.w(TAG, "Failed trying to unstop package "
9982                    + info.packageName + ": " + e);
9983        }
9984
9985        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9986                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9987            app.persistent = true;
9988            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9989        }
9990        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9991            mPersistentStartingProcesses.add(app);
9992            startProcessLocked(app, "added application", app.processName, abiOverride,
9993                    null /* entryPoint */, null /* entryPointArgs */);
9994        }
9995
9996        return app;
9997    }
9998
9999    public void unhandledBack() {
10000        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10001                "unhandledBack()");
10002
10003        synchronized(this) {
10004            final long origId = Binder.clearCallingIdentity();
10005            try {
10006                getFocusedStack().unhandledBackLocked();
10007            } finally {
10008                Binder.restoreCallingIdentity(origId);
10009            }
10010        }
10011    }
10012
10013    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10014        enforceNotIsolatedCaller("openContentUri");
10015        final int userId = UserHandle.getCallingUserId();
10016        String name = uri.getAuthority();
10017        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10018        ParcelFileDescriptor pfd = null;
10019        if (cph != null) {
10020            // We record the binder invoker's uid in thread-local storage before
10021            // going to the content provider to open the file.  Later, in the code
10022            // that handles all permissions checks, we look for this uid and use
10023            // that rather than the Activity Manager's own uid.  The effect is that
10024            // we do the check against the caller's permissions even though it looks
10025            // to the content provider like the Activity Manager itself is making
10026            // the request.
10027            sCallerIdentity.set(new Identity(
10028                    Binder.getCallingPid(), Binder.getCallingUid()));
10029            try {
10030                pfd = cph.provider.openFile(null, uri, "r", null);
10031            } catch (FileNotFoundException e) {
10032                // do nothing; pfd will be returned null
10033            } finally {
10034                // Ensure that whatever happens, we clean up the identity state
10035                sCallerIdentity.remove();
10036            }
10037
10038            // We've got the fd now, so we're done with the provider.
10039            removeContentProviderExternalUnchecked(name, null, userId);
10040        } else {
10041            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10042        }
10043        return pfd;
10044    }
10045
10046    // Actually is sleeping or shutting down or whatever else in the future
10047    // is an inactive state.
10048    public boolean isSleepingOrShuttingDown() {
10049        return isSleeping() || mShuttingDown;
10050    }
10051
10052    public boolean isSleeping() {
10053        return mSleeping;
10054    }
10055
10056    void onWakefulnessChanged(int wakefulness) {
10057        synchronized(this) {
10058            mWakefulness = wakefulness;
10059            updateSleepIfNeededLocked();
10060        }
10061    }
10062
10063    void finishRunningVoiceLocked() {
10064        if (mRunningVoice) {
10065            mRunningVoice = false;
10066            updateSleepIfNeededLocked();
10067        }
10068    }
10069
10070    void updateSleepIfNeededLocked() {
10071        if (mSleeping && !shouldSleepLocked()) {
10072            mSleeping = false;
10073            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10074        } else if (!mSleeping && shouldSleepLocked()) {
10075            mSleeping = true;
10076            mStackSupervisor.goingToSleepLocked();
10077
10078            // Initialize the wake times of all processes.
10079            checkExcessivePowerUsageLocked(false);
10080            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10081            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10082            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10083        }
10084    }
10085
10086    private boolean shouldSleepLocked() {
10087        // Resume applications while running a voice interactor.
10088        if (mRunningVoice) {
10089            return false;
10090        }
10091
10092        switch (mWakefulness) {
10093            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10094            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10095                // If we're interactive but applications are already paused then defer
10096                // resuming them until the lock screen is hidden.
10097                return mSleeping && mLockScreenShown;
10098            case PowerManagerInternal.WAKEFULNESS_DOZING:
10099                // If we're dozing then pause applications whenever the lock screen is shown.
10100                return mLockScreenShown;
10101            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10102            default:
10103                // If we're asleep then pause applications unconditionally.
10104                return true;
10105        }
10106    }
10107
10108    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10109        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10110            // Never persist the home stack.
10111            return;
10112        }
10113        mTaskPersister.wakeup(task, flush);
10114    }
10115
10116    @Override
10117    public boolean shutdown(int timeout) {
10118        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10119                != PackageManager.PERMISSION_GRANTED) {
10120            throw new SecurityException("Requires permission "
10121                    + android.Manifest.permission.SHUTDOWN);
10122        }
10123
10124        boolean timedout = false;
10125
10126        synchronized(this) {
10127            mShuttingDown = true;
10128            updateEventDispatchingLocked();
10129            timedout = mStackSupervisor.shutdownLocked(timeout);
10130        }
10131
10132        mAppOpsService.shutdown();
10133        if (mUsageStatsService != null) {
10134            mUsageStatsService.prepareShutdown();
10135        }
10136        mBatteryStatsService.shutdown();
10137        synchronized (this) {
10138            mProcessStats.shutdownLocked();
10139        }
10140        notifyTaskPersisterLocked(null, true);
10141
10142        return timedout;
10143    }
10144
10145    public final void activitySlept(IBinder token) {
10146        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10147
10148        final long origId = Binder.clearCallingIdentity();
10149
10150        synchronized (this) {
10151            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10152            if (r != null) {
10153                mStackSupervisor.activitySleptLocked(r);
10154            }
10155        }
10156
10157        Binder.restoreCallingIdentity(origId);
10158    }
10159
10160    void logLockScreen(String msg) {
10161        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10162                + " mLockScreenShown=" + mLockScreenShown + " mWakefulness="
10163                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10164                + " mSleeping=" + mSleeping);
10165    }
10166
10167    void startRunningVoiceLocked() {
10168        if (!mRunningVoice) {
10169            mRunningVoice = true;
10170            updateSleepIfNeededLocked();
10171        }
10172    }
10173
10174    private void updateEventDispatchingLocked() {
10175        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10176    }
10177
10178    public void setLockScreenShown(boolean shown) {
10179        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10180                != PackageManager.PERMISSION_GRANTED) {
10181            throw new SecurityException("Requires permission "
10182                    + android.Manifest.permission.DEVICE_POWER);
10183        }
10184
10185        synchronized(this) {
10186            long ident = Binder.clearCallingIdentity();
10187            try {
10188                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10189                mLockScreenShown = shown;
10190                updateSleepIfNeededLocked();
10191            } finally {
10192                Binder.restoreCallingIdentity(ident);
10193            }
10194        }
10195    }
10196
10197    @Override
10198    public void stopAppSwitches() {
10199        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10200                != PackageManager.PERMISSION_GRANTED) {
10201            throw new SecurityException("Requires permission "
10202                    + android.Manifest.permission.STOP_APP_SWITCHES);
10203        }
10204
10205        synchronized(this) {
10206            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10207                    + APP_SWITCH_DELAY_TIME;
10208            mDidAppSwitch = false;
10209            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10210            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10211            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10212        }
10213    }
10214
10215    public void resumeAppSwitches() {
10216        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10217                != PackageManager.PERMISSION_GRANTED) {
10218            throw new SecurityException("Requires permission "
10219                    + android.Manifest.permission.STOP_APP_SWITCHES);
10220        }
10221
10222        synchronized(this) {
10223            // Note that we don't execute any pending app switches... we will
10224            // let those wait until either the timeout, or the next start
10225            // activity request.
10226            mAppSwitchesAllowedTime = 0;
10227        }
10228    }
10229
10230    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10231            int callingPid, int callingUid, String name) {
10232        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10233            return true;
10234        }
10235
10236        int perm = checkComponentPermission(
10237                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10238                sourceUid, -1, true);
10239        if (perm == PackageManager.PERMISSION_GRANTED) {
10240            return true;
10241        }
10242
10243        // If the actual IPC caller is different from the logical source, then
10244        // also see if they are allowed to control app switches.
10245        if (callingUid != -1 && callingUid != sourceUid) {
10246            perm = checkComponentPermission(
10247                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10248                    callingUid, -1, true);
10249            if (perm == PackageManager.PERMISSION_GRANTED) {
10250                return true;
10251            }
10252        }
10253
10254        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10255        return false;
10256    }
10257
10258    public void setDebugApp(String packageName, boolean waitForDebugger,
10259            boolean persistent) {
10260        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10261                "setDebugApp()");
10262
10263        long ident = Binder.clearCallingIdentity();
10264        try {
10265            // Note that this is not really thread safe if there are multiple
10266            // callers into it at the same time, but that's not a situation we
10267            // care about.
10268            if (persistent) {
10269                final ContentResolver resolver = mContext.getContentResolver();
10270                Settings.Global.putString(
10271                    resolver, Settings.Global.DEBUG_APP,
10272                    packageName);
10273                Settings.Global.putInt(
10274                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10275                    waitForDebugger ? 1 : 0);
10276            }
10277
10278            synchronized (this) {
10279                if (!persistent) {
10280                    mOrigDebugApp = mDebugApp;
10281                    mOrigWaitForDebugger = mWaitForDebugger;
10282                }
10283                mDebugApp = packageName;
10284                mWaitForDebugger = waitForDebugger;
10285                mDebugTransient = !persistent;
10286                if (packageName != null) {
10287                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10288                            false, UserHandle.USER_ALL, "set debug app");
10289                }
10290            }
10291        } finally {
10292            Binder.restoreCallingIdentity(ident);
10293        }
10294    }
10295
10296    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10297        synchronized (this) {
10298            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10299            if (!isDebuggable) {
10300                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10301                    throw new SecurityException("Process not debuggable: " + app.packageName);
10302                }
10303            }
10304
10305            mOpenGlTraceApp = processName;
10306        }
10307    }
10308
10309    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10310        synchronized (this) {
10311            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10312            if (!isDebuggable) {
10313                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10314                    throw new SecurityException("Process not debuggable: " + app.packageName);
10315                }
10316            }
10317            mProfileApp = processName;
10318            mProfileFile = profilerInfo.profileFile;
10319            if (mProfileFd != null) {
10320                try {
10321                    mProfileFd.close();
10322                } catch (IOException e) {
10323                }
10324                mProfileFd = null;
10325            }
10326            mProfileFd = profilerInfo.profileFd;
10327            mSamplingInterval = profilerInfo.samplingInterval;
10328            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10329            mProfileType = 0;
10330        }
10331    }
10332
10333    @Override
10334    public void setAlwaysFinish(boolean enabled) {
10335        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10336                "setAlwaysFinish()");
10337
10338        Settings.Global.putInt(
10339                mContext.getContentResolver(),
10340                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10341
10342        synchronized (this) {
10343            mAlwaysFinishActivities = enabled;
10344        }
10345    }
10346
10347    @Override
10348    public void setActivityController(IActivityController controller) {
10349        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10350                "setActivityController()");
10351        synchronized (this) {
10352            mController = controller;
10353            Watchdog.getInstance().setActivityController(controller);
10354        }
10355    }
10356
10357    @Override
10358    public void setUserIsMonkey(boolean userIsMonkey) {
10359        synchronized (this) {
10360            synchronized (mPidsSelfLocked) {
10361                final int callingPid = Binder.getCallingPid();
10362                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10363                if (precessRecord == null) {
10364                    throw new SecurityException("Unknown process: " + callingPid);
10365                }
10366                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10367                    throw new SecurityException("Only an instrumentation process "
10368                            + "with a UiAutomation can call setUserIsMonkey");
10369                }
10370            }
10371            mUserIsMonkey = userIsMonkey;
10372        }
10373    }
10374
10375    @Override
10376    public boolean isUserAMonkey() {
10377        synchronized (this) {
10378            // If there is a controller also implies the user is a monkey.
10379            return (mUserIsMonkey || mController != null);
10380        }
10381    }
10382
10383    public void requestBugReport() {
10384        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10385        SystemProperties.set("ctl.start", "bugreport");
10386    }
10387
10388    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10389        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10390    }
10391
10392    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10393        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10394            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10395        }
10396        return KEY_DISPATCHING_TIMEOUT;
10397    }
10398
10399    @Override
10400    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10401        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10402                != PackageManager.PERMISSION_GRANTED) {
10403            throw new SecurityException("Requires permission "
10404                    + android.Manifest.permission.FILTER_EVENTS);
10405        }
10406        ProcessRecord proc;
10407        long timeout;
10408        synchronized (this) {
10409            synchronized (mPidsSelfLocked) {
10410                proc = mPidsSelfLocked.get(pid);
10411            }
10412            timeout = getInputDispatchingTimeoutLocked(proc);
10413        }
10414
10415        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10416            return -1;
10417        }
10418
10419        return timeout;
10420    }
10421
10422    /**
10423     * Handle input dispatching timeouts.
10424     * Returns whether input dispatching should be aborted or not.
10425     */
10426    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10427            final ActivityRecord activity, final ActivityRecord parent,
10428            final boolean aboveSystem, String reason) {
10429        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10430                != PackageManager.PERMISSION_GRANTED) {
10431            throw new SecurityException("Requires permission "
10432                    + android.Manifest.permission.FILTER_EVENTS);
10433        }
10434
10435        final String annotation;
10436        if (reason == null) {
10437            annotation = "Input dispatching timed out";
10438        } else {
10439            annotation = "Input dispatching timed out (" + reason + ")";
10440        }
10441
10442        if (proc != null) {
10443            synchronized (this) {
10444                if (proc.debugging) {
10445                    return false;
10446                }
10447
10448                if (mDidDexOpt) {
10449                    // Give more time since we were dexopting.
10450                    mDidDexOpt = false;
10451                    return false;
10452                }
10453
10454                if (proc.instrumentationClass != null) {
10455                    Bundle info = new Bundle();
10456                    info.putString("shortMsg", "keyDispatchingTimedOut");
10457                    info.putString("longMsg", annotation);
10458                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10459                    return true;
10460                }
10461            }
10462            mHandler.post(new Runnable() {
10463                @Override
10464                public void run() {
10465                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10466                }
10467            });
10468        }
10469
10470        return true;
10471    }
10472
10473    public Bundle getAssistContextExtras(int requestType) {
10474        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10475                UserHandle.getCallingUserId());
10476        if (pae == null) {
10477            return null;
10478        }
10479        synchronized (pae) {
10480            while (!pae.haveResult) {
10481                try {
10482                    pae.wait();
10483                } catch (InterruptedException e) {
10484                }
10485            }
10486            if (pae.result != null) {
10487                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10488            }
10489        }
10490        synchronized (this) {
10491            mPendingAssistExtras.remove(pae);
10492            mHandler.removeCallbacks(pae);
10493        }
10494        return pae.extras;
10495    }
10496
10497    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10498            int userHandle) {
10499        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10500                "getAssistContextExtras()");
10501        PendingAssistExtras pae;
10502        Bundle extras = new Bundle();
10503        synchronized (this) {
10504            ActivityRecord activity = getFocusedStack().mResumedActivity;
10505            if (activity == null) {
10506                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10507                return null;
10508            }
10509            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10510            if (activity.app == null || activity.app.thread == null) {
10511                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10512                return null;
10513            }
10514            if (activity.app.pid == Binder.getCallingPid()) {
10515                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10516                return null;
10517            }
10518            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10519            try {
10520                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10521                        requestType);
10522                mPendingAssistExtras.add(pae);
10523                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10524            } catch (RemoteException e) {
10525                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10526                return null;
10527            }
10528            return pae;
10529        }
10530    }
10531
10532    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10533        PendingAssistExtras pae = (PendingAssistExtras)token;
10534        synchronized (pae) {
10535            pae.result = extras;
10536            pae.haveResult = true;
10537            pae.notifyAll();
10538            if (pae.intent == null) {
10539                // Caller is just waiting for the result.
10540                return;
10541            }
10542        }
10543
10544        // We are now ready to launch the assist activity.
10545        synchronized (this) {
10546            boolean exists = mPendingAssistExtras.remove(pae);
10547            mHandler.removeCallbacks(pae);
10548            if (!exists) {
10549                // Timed out.
10550                return;
10551            }
10552        }
10553        pae.intent.replaceExtras(extras);
10554        if (pae.hint != null) {
10555            pae.intent.putExtra(pae.hint, true);
10556        }
10557        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10558                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10559                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10560        closeSystemDialogs("assist");
10561        try {
10562            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10563        } catch (ActivityNotFoundException e) {
10564            Slog.w(TAG, "No activity to handle assist action.", e);
10565        }
10566    }
10567
10568    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10569        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10570    }
10571
10572    public void registerProcessObserver(IProcessObserver observer) {
10573        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10574                "registerProcessObserver()");
10575        synchronized (this) {
10576            mProcessObservers.register(observer);
10577        }
10578    }
10579
10580    @Override
10581    public void unregisterProcessObserver(IProcessObserver observer) {
10582        synchronized (this) {
10583            mProcessObservers.unregister(observer);
10584        }
10585    }
10586
10587    @Override
10588    public boolean convertFromTranslucent(IBinder token) {
10589        final long origId = Binder.clearCallingIdentity();
10590        try {
10591            synchronized (this) {
10592                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10593                if (r == null) {
10594                    return false;
10595                }
10596                final boolean translucentChanged = r.changeWindowTranslucency(true);
10597                if (translucentChanged) {
10598                    r.task.stack.releaseBackgroundResources();
10599                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10600                }
10601                mWindowManager.setAppFullscreen(token, true);
10602                return translucentChanged;
10603            }
10604        } finally {
10605            Binder.restoreCallingIdentity(origId);
10606        }
10607    }
10608
10609    @Override
10610    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10611        final long origId = Binder.clearCallingIdentity();
10612        try {
10613            synchronized (this) {
10614                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10615                if (r == null) {
10616                    return false;
10617                }
10618                int index = r.task.mActivities.lastIndexOf(r);
10619                if (index > 0) {
10620                    ActivityRecord under = r.task.mActivities.get(index - 1);
10621                    under.returningOptions = options;
10622                }
10623                final boolean translucentChanged = r.changeWindowTranslucency(false);
10624                if (translucentChanged) {
10625                    r.task.stack.convertToTranslucent(r);
10626                }
10627                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10628                mWindowManager.setAppFullscreen(token, false);
10629                return translucentChanged;
10630            }
10631        } finally {
10632            Binder.restoreCallingIdentity(origId);
10633        }
10634    }
10635
10636    @Override
10637    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10638        final long origId = Binder.clearCallingIdentity();
10639        try {
10640            synchronized (this) {
10641                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10642                if (r != null) {
10643                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10644                }
10645            }
10646            return false;
10647        } finally {
10648            Binder.restoreCallingIdentity(origId);
10649        }
10650    }
10651
10652    @Override
10653    public boolean isBackgroundVisibleBehind(IBinder token) {
10654        final long origId = Binder.clearCallingIdentity();
10655        try {
10656            synchronized (this) {
10657                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10658                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10659                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10660                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10661                return visible;
10662            }
10663        } finally {
10664            Binder.restoreCallingIdentity(origId);
10665        }
10666    }
10667
10668    @Override
10669    public ActivityOptions getActivityOptions(IBinder token) {
10670        final long origId = Binder.clearCallingIdentity();
10671        try {
10672            synchronized (this) {
10673                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10674                if (r != null) {
10675                    final ActivityOptions activityOptions = r.pendingOptions;
10676                    r.pendingOptions = null;
10677                    return activityOptions;
10678                }
10679                return null;
10680            }
10681        } finally {
10682            Binder.restoreCallingIdentity(origId);
10683        }
10684    }
10685
10686    @Override
10687    public void setImmersive(IBinder token, boolean immersive) {
10688        synchronized(this) {
10689            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10690            if (r == null) {
10691                throw new IllegalArgumentException();
10692            }
10693            r.immersive = immersive;
10694
10695            // update associated state if we're frontmost
10696            if (r == mFocusedActivity) {
10697                if (DEBUG_IMMERSIVE) {
10698                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10699                }
10700                applyUpdateLockStateLocked(r);
10701            }
10702        }
10703    }
10704
10705    @Override
10706    public boolean isImmersive(IBinder token) {
10707        synchronized (this) {
10708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10709            if (r == null) {
10710                throw new IllegalArgumentException();
10711            }
10712            return r.immersive;
10713        }
10714    }
10715
10716    public boolean isTopActivityImmersive() {
10717        enforceNotIsolatedCaller("startActivity");
10718        synchronized (this) {
10719            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10720            return (r != null) ? r.immersive : false;
10721        }
10722    }
10723
10724    @Override
10725    public boolean isTopOfTask(IBinder token) {
10726        synchronized (this) {
10727            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10728            if (r == null) {
10729                throw new IllegalArgumentException();
10730            }
10731            return r.task.getTopActivity() == r;
10732        }
10733    }
10734
10735    public final void enterSafeMode() {
10736        synchronized(this) {
10737            // It only makes sense to do this before the system is ready
10738            // and started launching other packages.
10739            if (!mSystemReady) {
10740                try {
10741                    AppGlobals.getPackageManager().enterSafeMode();
10742                } catch (RemoteException e) {
10743                }
10744            }
10745
10746            mSafeMode = true;
10747        }
10748    }
10749
10750    public final void showSafeModeOverlay() {
10751        View v = LayoutInflater.from(mContext).inflate(
10752                com.android.internal.R.layout.safe_mode, null);
10753        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10754        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10755        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10756        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10757        lp.gravity = Gravity.BOTTOM | Gravity.START;
10758        lp.format = v.getBackground().getOpacity();
10759        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10760                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10761        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10762        ((WindowManager)mContext.getSystemService(
10763                Context.WINDOW_SERVICE)).addView(v, lp);
10764    }
10765
10766    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10767        if (!(sender instanceof PendingIntentRecord)) {
10768            return;
10769        }
10770        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10771        synchronized (stats) {
10772            if (mBatteryStatsService.isOnBattery()) {
10773                mBatteryStatsService.enforceCallingPermission();
10774                PendingIntentRecord rec = (PendingIntentRecord)sender;
10775                int MY_UID = Binder.getCallingUid();
10776                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10777                BatteryStatsImpl.Uid.Pkg pkg =
10778                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10779                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10780                pkg.incWakeupsLocked();
10781            }
10782        }
10783    }
10784
10785    public boolean killPids(int[] pids, String pReason, boolean secure) {
10786        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10787            throw new SecurityException("killPids only available to the system");
10788        }
10789        String reason = (pReason == null) ? "Unknown" : pReason;
10790        // XXX Note: don't acquire main activity lock here, because the window
10791        // manager calls in with its locks held.
10792
10793        boolean killed = false;
10794        synchronized (mPidsSelfLocked) {
10795            int[] types = new int[pids.length];
10796            int worstType = 0;
10797            for (int i=0; i<pids.length; i++) {
10798                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10799                if (proc != null) {
10800                    int type = proc.setAdj;
10801                    types[i] = type;
10802                    if (type > worstType) {
10803                        worstType = type;
10804                    }
10805                }
10806            }
10807
10808            // If the worst oom_adj is somewhere in the cached proc LRU range,
10809            // then constrain it so we will kill all cached procs.
10810            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10811                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10812                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10813            }
10814
10815            // If this is not a secure call, don't let it kill processes that
10816            // are important.
10817            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10818                worstType = ProcessList.SERVICE_ADJ;
10819            }
10820
10821            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10822            for (int i=0; i<pids.length; i++) {
10823                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10824                if (proc == null) {
10825                    continue;
10826                }
10827                int adj = proc.setAdj;
10828                if (adj >= worstType && !proc.killedByAm) {
10829                    proc.kill(reason, true);
10830                    killed = true;
10831                }
10832            }
10833        }
10834        return killed;
10835    }
10836
10837    @Override
10838    public void killUid(int uid, String reason) {
10839        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10840            throw new SecurityException("killUid only available to the system");
10841        }
10842        synchronized (this) {
10843            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10844                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10845                    reason != null ? reason : "kill uid");
10846        }
10847    }
10848
10849    @Override
10850    public boolean killProcessesBelowForeground(String reason) {
10851        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10852            throw new SecurityException("killProcessesBelowForeground() only available to system");
10853        }
10854
10855        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10856    }
10857
10858    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10859        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10860            throw new SecurityException("killProcessesBelowAdj() only available to system");
10861        }
10862
10863        boolean killed = false;
10864        synchronized (mPidsSelfLocked) {
10865            final int size = mPidsSelfLocked.size();
10866            for (int i = 0; i < size; i++) {
10867                final int pid = mPidsSelfLocked.keyAt(i);
10868                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10869                if (proc == null) continue;
10870
10871                final int adj = proc.setAdj;
10872                if (adj > belowAdj && !proc.killedByAm) {
10873                    proc.kill(reason, true);
10874                    killed = true;
10875                }
10876            }
10877        }
10878        return killed;
10879    }
10880
10881    @Override
10882    public void hang(final IBinder who, boolean allowRestart) {
10883        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10884                != PackageManager.PERMISSION_GRANTED) {
10885            throw new SecurityException("Requires permission "
10886                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10887        }
10888
10889        final IBinder.DeathRecipient death = new DeathRecipient() {
10890            @Override
10891            public void binderDied() {
10892                synchronized (this) {
10893                    notifyAll();
10894                }
10895            }
10896        };
10897
10898        try {
10899            who.linkToDeath(death, 0);
10900        } catch (RemoteException e) {
10901            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10902            return;
10903        }
10904
10905        synchronized (this) {
10906            Watchdog.getInstance().setAllowRestart(allowRestart);
10907            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10908            synchronized (death) {
10909                while (who.isBinderAlive()) {
10910                    try {
10911                        death.wait();
10912                    } catch (InterruptedException e) {
10913                    }
10914                }
10915            }
10916            Watchdog.getInstance().setAllowRestart(true);
10917        }
10918    }
10919
10920    @Override
10921    public void restart() {
10922        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10923                != PackageManager.PERMISSION_GRANTED) {
10924            throw new SecurityException("Requires permission "
10925                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10926        }
10927
10928        Log.i(TAG, "Sending shutdown broadcast...");
10929
10930        BroadcastReceiver br = new BroadcastReceiver() {
10931            @Override public void onReceive(Context context, Intent intent) {
10932                // Now the broadcast is done, finish up the low-level shutdown.
10933                Log.i(TAG, "Shutting down activity manager...");
10934                shutdown(10000);
10935                Log.i(TAG, "Shutdown complete, restarting!");
10936                Process.killProcess(Process.myPid());
10937                System.exit(10);
10938            }
10939        };
10940
10941        // First send the high-level shut down broadcast.
10942        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10943        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10944        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10945        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10946        mContext.sendOrderedBroadcastAsUser(intent,
10947                UserHandle.ALL, null, br, mHandler, 0, null, null);
10948        */
10949        br.onReceive(mContext, intent);
10950    }
10951
10952    private long getLowRamTimeSinceIdle(long now) {
10953        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10954    }
10955
10956    @Override
10957    public void performIdleMaintenance() {
10958        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10959                != PackageManager.PERMISSION_GRANTED) {
10960            throw new SecurityException("Requires permission "
10961                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10962        }
10963
10964        synchronized (this) {
10965            final long now = SystemClock.uptimeMillis();
10966            final long timeSinceLastIdle = now - mLastIdleTime;
10967            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10968            mLastIdleTime = now;
10969            mLowRamTimeSinceLastIdle = 0;
10970            if (mLowRamStartTime != 0) {
10971                mLowRamStartTime = now;
10972            }
10973
10974            StringBuilder sb = new StringBuilder(128);
10975            sb.append("Idle maintenance over ");
10976            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10977            sb.append(" low RAM for ");
10978            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10979            Slog.i(TAG, sb.toString());
10980
10981            // If at least 1/3 of our time since the last idle period has been spent
10982            // with RAM low, then we want to kill processes.
10983            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10984
10985            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10986                ProcessRecord proc = mLruProcesses.get(i);
10987                if (proc.notCachedSinceIdle) {
10988                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10989                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10990                        if (doKilling && proc.initialIdlePss != 0
10991                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10992                            proc.kill("idle maint (pss " + proc.lastPss
10993                                    + " from " + proc.initialIdlePss + ")", true);
10994                        }
10995                    }
10996                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10997                    proc.notCachedSinceIdle = true;
10998                    proc.initialIdlePss = 0;
10999                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11000                            isSleeping(), now);
11001                }
11002            }
11003
11004            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11005            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11006        }
11007    }
11008
11009    private void retrieveSettings() {
11010        final ContentResolver resolver = mContext.getContentResolver();
11011        String debugApp = Settings.Global.getString(
11012            resolver, Settings.Global.DEBUG_APP);
11013        boolean waitForDebugger = Settings.Global.getInt(
11014            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11015        boolean alwaysFinishActivities = Settings.Global.getInt(
11016            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11017        boolean forceRtl = Settings.Global.getInt(
11018                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11019        // Transfer any global setting for forcing RTL layout, into a System Property
11020        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11021
11022        Configuration configuration = new Configuration();
11023        Settings.System.getConfiguration(resolver, configuration);
11024        if (forceRtl) {
11025            // This will take care of setting the correct layout direction flags
11026            configuration.setLayoutDirection(configuration.locale);
11027        }
11028
11029        synchronized (this) {
11030            mDebugApp = mOrigDebugApp = debugApp;
11031            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11032            mAlwaysFinishActivities = alwaysFinishActivities;
11033            // This happens before any activities are started, so we can
11034            // change mConfiguration in-place.
11035            updateConfigurationLocked(configuration, null, false, true);
11036            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11037        }
11038    }
11039
11040    /** Loads resources after the current configuration has been set. */
11041    private void loadResourcesOnSystemReady() {
11042        final Resources res = mContext.getResources();
11043        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11044        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11045        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11046    }
11047
11048    public boolean testIsSystemReady() {
11049        // no need to synchronize(this) just to read & return the value
11050        return mSystemReady;
11051    }
11052
11053    private static File getCalledPreBootReceiversFile() {
11054        File dataDir = Environment.getDataDirectory();
11055        File systemDir = new File(dataDir, "system");
11056        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11057        return fname;
11058    }
11059
11060    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11061        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11062        File file = getCalledPreBootReceiversFile();
11063        FileInputStream fis = null;
11064        try {
11065            fis = new FileInputStream(file);
11066            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11067            int fvers = dis.readInt();
11068            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11069                String vers = dis.readUTF();
11070                String codename = dis.readUTF();
11071                String build = dis.readUTF();
11072                if (android.os.Build.VERSION.RELEASE.equals(vers)
11073                        && android.os.Build.VERSION.CODENAME.equals(codename)
11074                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11075                    int num = dis.readInt();
11076                    while (num > 0) {
11077                        num--;
11078                        String pkg = dis.readUTF();
11079                        String cls = dis.readUTF();
11080                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11081                    }
11082                }
11083            }
11084        } catch (FileNotFoundException e) {
11085        } catch (IOException e) {
11086            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11087        } finally {
11088            if (fis != null) {
11089                try {
11090                    fis.close();
11091                } catch (IOException e) {
11092                }
11093            }
11094        }
11095        return lastDoneReceivers;
11096    }
11097
11098    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11099        File file = getCalledPreBootReceiversFile();
11100        FileOutputStream fos = null;
11101        DataOutputStream dos = null;
11102        try {
11103            fos = new FileOutputStream(file);
11104            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11105            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11106            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11107            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11108            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11109            dos.writeInt(list.size());
11110            for (int i=0; i<list.size(); i++) {
11111                dos.writeUTF(list.get(i).getPackageName());
11112                dos.writeUTF(list.get(i).getClassName());
11113            }
11114        } catch (IOException e) {
11115            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11116            file.delete();
11117        } finally {
11118            FileUtils.sync(fos);
11119            if (dos != null) {
11120                try {
11121                    dos.close();
11122                } catch (IOException e) {
11123                    // TODO Auto-generated catch block
11124                    e.printStackTrace();
11125                }
11126            }
11127        }
11128    }
11129
11130    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11131            ArrayList<ComponentName> doneReceivers, int userId) {
11132        boolean waitingUpdate = false;
11133        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11134        List<ResolveInfo> ris = null;
11135        try {
11136            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11137                    intent, null, 0, userId);
11138        } catch (RemoteException e) {
11139        }
11140        if (ris != null) {
11141            for (int i=ris.size()-1; i>=0; i--) {
11142                if ((ris.get(i).activityInfo.applicationInfo.flags
11143                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11144                    ris.remove(i);
11145                }
11146            }
11147            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11148
11149            // For User 0, load the version number. When delivering to a new user, deliver
11150            // to all receivers.
11151            if (userId == UserHandle.USER_OWNER) {
11152                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11153                for (int i=0; i<ris.size(); i++) {
11154                    ActivityInfo ai = ris.get(i).activityInfo;
11155                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11156                    if (lastDoneReceivers.contains(comp)) {
11157                        // We already did the pre boot receiver for this app with the current
11158                        // platform version, so don't do it again...
11159                        ris.remove(i);
11160                        i--;
11161                        // ...however, do keep it as one that has been done, so we don't
11162                        // forget about it when rewriting the file of last done receivers.
11163                        doneReceivers.add(comp);
11164                    }
11165                }
11166            }
11167
11168            // If primary user, send broadcast to all available users, else just to userId
11169            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11170                    : new int[] { userId };
11171            for (int i = 0; i < ris.size(); i++) {
11172                ActivityInfo ai = ris.get(i).activityInfo;
11173                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11174                doneReceivers.add(comp);
11175                intent.setComponent(comp);
11176                for (int j=0; j<users.length; j++) {
11177                    IIntentReceiver finisher = null;
11178                    // On last receiver and user, set up a completion callback
11179                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11180                        finisher = new IIntentReceiver.Stub() {
11181                            public void performReceive(Intent intent, int resultCode,
11182                                    String data, Bundle extras, boolean ordered,
11183                                    boolean sticky, int sendingUser) {
11184                                // The raw IIntentReceiver interface is called
11185                                // with the AM lock held, so redispatch to
11186                                // execute our code without the lock.
11187                                mHandler.post(onFinishCallback);
11188                            }
11189                        };
11190                    }
11191                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11192                            + " for user " + users[j]);
11193                    broadcastIntentLocked(null, null, intent, null, finisher,
11194                            0, null, null, null, AppOpsManager.OP_NONE,
11195                            true, false, MY_PID, Process.SYSTEM_UID,
11196                            users[j]);
11197                    if (finisher != null) {
11198                        waitingUpdate = true;
11199                    }
11200                }
11201            }
11202        }
11203
11204        return waitingUpdate;
11205    }
11206
11207    public void systemReady(final Runnable goingCallback) {
11208        synchronized(this) {
11209            if (mSystemReady) {
11210                // If we're done calling all the receivers, run the next "boot phase" passed in
11211                // by the SystemServer
11212                if (goingCallback != null) {
11213                    goingCallback.run();
11214                }
11215                return;
11216            }
11217
11218            // Make sure we have the current profile info, since it is needed for
11219            // security checks.
11220            updateCurrentProfileIdsLocked();
11221
11222            if (mRecentTasks == null) {
11223                mRecentTasks = mTaskPersister.restoreTasksLocked();
11224                if (!mRecentTasks.isEmpty()) {
11225                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11226                }
11227                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11228                mTaskPersister.startPersisting();
11229            }
11230
11231            // Check to see if there are any update receivers to run.
11232            if (!mDidUpdate) {
11233                if (mWaitingUpdate) {
11234                    return;
11235                }
11236                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11237                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11238                    public void run() {
11239                        synchronized (ActivityManagerService.this) {
11240                            mDidUpdate = true;
11241                        }
11242                        writeLastDonePreBootReceivers(doneReceivers);
11243                        showBootMessage(mContext.getText(
11244                                R.string.android_upgrading_complete),
11245                                false);
11246                        systemReady(goingCallback);
11247                    }
11248                }, doneReceivers, UserHandle.USER_OWNER);
11249
11250                if (mWaitingUpdate) {
11251                    return;
11252                }
11253                mDidUpdate = true;
11254            }
11255
11256            mAppOpsService.systemReady();
11257            mSystemReady = true;
11258        }
11259
11260        ArrayList<ProcessRecord> procsToKill = null;
11261        synchronized(mPidsSelfLocked) {
11262            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11263                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11264                if (!isAllowedWhileBooting(proc.info)){
11265                    if (procsToKill == null) {
11266                        procsToKill = new ArrayList<ProcessRecord>();
11267                    }
11268                    procsToKill.add(proc);
11269                }
11270            }
11271        }
11272
11273        synchronized(this) {
11274            if (procsToKill != null) {
11275                for (int i=procsToKill.size()-1; i>=0; i--) {
11276                    ProcessRecord proc = procsToKill.get(i);
11277                    Slog.i(TAG, "Removing system update proc: " + proc);
11278                    removeProcessLocked(proc, true, false, "system update done");
11279                }
11280            }
11281
11282            // Now that we have cleaned up any update processes, we
11283            // are ready to start launching real processes and know that
11284            // we won't trample on them any more.
11285            mProcessesReady = true;
11286        }
11287
11288        Slog.i(TAG, "System now ready");
11289        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11290            SystemClock.uptimeMillis());
11291
11292        synchronized(this) {
11293            // Make sure we have no pre-ready processes sitting around.
11294
11295            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11296                ResolveInfo ri = mContext.getPackageManager()
11297                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11298                                STOCK_PM_FLAGS);
11299                CharSequence errorMsg = null;
11300                if (ri != null) {
11301                    ActivityInfo ai = ri.activityInfo;
11302                    ApplicationInfo app = ai.applicationInfo;
11303                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11304                        mTopAction = Intent.ACTION_FACTORY_TEST;
11305                        mTopData = null;
11306                        mTopComponent = new ComponentName(app.packageName,
11307                                ai.name);
11308                    } else {
11309                        errorMsg = mContext.getResources().getText(
11310                                com.android.internal.R.string.factorytest_not_system);
11311                    }
11312                } else {
11313                    errorMsg = mContext.getResources().getText(
11314                            com.android.internal.R.string.factorytest_no_action);
11315                }
11316                if (errorMsg != null) {
11317                    mTopAction = null;
11318                    mTopData = null;
11319                    mTopComponent = null;
11320                    Message msg = Message.obtain();
11321                    msg.what = SHOW_FACTORY_ERROR_MSG;
11322                    msg.getData().putCharSequence("msg", errorMsg);
11323                    mHandler.sendMessage(msg);
11324                }
11325            }
11326        }
11327
11328        retrieveSettings();
11329        loadResourcesOnSystemReady();
11330
11331        synchronized (this) {
11332            readGrantedUriPermissionsLocked();
11333        }
11334
11335        if (goingCallback != null) goingCallback.run();
11336
11337        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11338                Integer.toString(mCurrentUserId), mCurrentUserId);
11339        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11340                Integer.toString(mCurrentUserId), mCurrentUserId);
11341        mSystemServiceManager.startUser(mCurrentUserId);
11342
11343        synchronized (this) {
11344            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11345                try {
11346                    List apps = AppGlobals.getPackageManager().
11347                        getPersistentApplications(STOCK_PM_FLAGS);
11348                    if (apps != null) {
11349                        int N = apps.size();
11350                        int i;
11351                        for (i=0; i<N; i++) {
11352                            ApplicationInfo info
11353                                = (ApplicationInfo)apps.get(i);
11354                            if (info != null &&
11355                                    !info.packageName.equals("android")) {
11356                                addAppLocked(info, false, null /* ABI override */);
11357                            }
11358                        }
11359                    }
11360                } catch (RemoteException ex) {
11361                    // pm is in same process, this will never happen.
11362                }
11363            }
11364
11365            // Start up initial activity.
11366            mBooting = true;
11367            startHomeActivityLocked(mCurrentUserId);
11368
11369            try {
11370                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11371                    Message msg = Message.obtain();
11372                    msg.what = SHOW_UID_ERROR_MSG;
11373                    mHandler.sendMessage(msg);
11374                }
11375            } catch (RemoteException e) {
11376            }
11377
11378            long ident = Binder.clearCallingIdentity();
11379            try {
11380                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11381                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11382                        | Intent.FLAG_RECEIVER_FOREGROUND);
11383                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11384                broadcastIntentLocked(null, null, intent,
11385                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11386                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11387                intent = new Intent(Intent.ACTION_USER_STARTING);
11388                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11389                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11390                broadcastIntentLocked(null, null, intent,
11391                        null, new IIntentReceiver.Stub() {
11392                            @Override
11393                            public void performReceive(Intent intent, int resultCode, String data,
11394                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11395                                    throws RemoteException {
11396                            }
11397                        }, 0, null, null,
11398                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11399                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11400            } catch (Throwable t) {
11401                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11402            } finally {
11403                Binder.restoreCallingIdentity(ident);
11404            }
11405            mStackSupervisor.resumeTopActivitiesLocked();
11406            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11407        }
11408    }
11409
11410    private boolean makeAppCrashingLocked(ProcessRecord app,
11411            String shortMsg, String longMsg, String stackTrace) {
11412        app.crashing = true;
11413        app.crashingReport = generateProcessError(app,
11414                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11415        startAppProblemLocked(app);
11416        app.stopFreezingAllLocked();
11417        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11418    }
11419
11420    private void makeAppNotRespondingLocked(ProcessRecord app,
11421            String activity, String shortMsg, String longMsg) {
11422        app.notResponding = true;
11423        app.notRespondingReport = generateProcessError(app,
11424                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11425                activity, shortMsg, longMsg, null);
11426        startAppProblemLocked(app);
11427        app.stopFreezingAllLocked();
11428    }
11429
11430    /**
11431     * Generate a process error record, suitable for attachment to a ProcessRecord.
11432     *
11433     * @param app The ProcessRecord in which the error occurred.
11434     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11435     *                      ActivityManager.AppErrorStateInfo
11436     * @param activity The activity associated with the crash, if known.
11437     * @param shortMsg Short message describing the crash.
11438     * @param longMsg Long message describing the crash.
11439     * @param stackTrace Full crash stack trace, may be null.
11440     *
11441     * @return Returns a fully-formed AppErrorStateInfo record.
11442     */
11443    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11444            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11445        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11446
11447        report.condition = condition;
11448        report.processName = app.processName;
11449        report.pid = app.pid;
11450        report.uid = app.info.uid;
11451        report.tag = activity;
11452        report.shortMsg = shortMsg;
11453        report.longMsg = longMsg;
11454        report.stackTrace = stackTrace;
11455
11456        return report;
11457    }
11458
11459    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11460        synchronized (this) {
11461            app.crashing = false;
11462            app.crashingReport = null;
11463            app.notResponding = false;
11464            app.notRespondingReport = null;
11465            if (app.anrDialog == fromDialog) {
11466                app.anrDialog = null;
11467            }
11468            if (app.waitDialog == fromDialog) {
11469                app.waitDialog = null;
11470            }
11471            if (app.pid > 0 && app.pid != MY_PID) {
11472                handleAppCrashLocked(app, null, null, null);
11473                app.kill("user request after error", true);
11474            }
11475        }
11476    }
11477
11478    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11479            String stackTrace) {
11480        long now = SystemClock.uptimeMillis();
11481
11482        Long crashTime;
11483        if (!app.isolated) {
11484            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11485        } else {
11486            crashTime = null;
11487        }
11488        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11489            // This process loses!
11490            Slog.w(TAG, "Process " + app.info.processName
11491                    + " has crashed too many times: killing!");
11492            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11493                    app.userId, app.info.processName, app.uid);
11494            mStackSupervisor.handleAppCrashLocked(app);
11495            if (!app.persistent) {
11496                // We don't want to start this process again until the user
11497                // explicitly does so...  but for persistent process, we really
11498                // need to keep it running.  If a persistent process is actually
11499                // repeatedly crashing, then badness for everyone.
11500                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11501                        app.info.processName);
11502                if (!app.isolated) {
11503                    // XXX We don't have a way to mark isolated processes
11504                    // as bad, since they don't have a peristent identity.
11505                    mBadProcesses.put(app.info.processName, app.uid,
11506                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11507                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11508                }
11509                app.bad = true;
11510                app.removed = true;
11511                // Don't let services in this process be restarted and potentially
11512                // annoy the user repeatedly.  Unless it is persistent, since those
11513                // processes run critical code.
11514                removeProcessLocked(app, false, false, "crash");
11515                mStackSupervisor.resumeTopActivitiesLocked();
11516                return false;
11517            }
11518            mStackSupervisor.resumeTopActivitiesLocked();
11519        } else {
11520            mStackSupervisor.finishTopRunningActivityLocked(app);
11521        }
11522
11523        // Bump up the crash count of any services currently running in the proc.
11524        for (int i=app.services.size()-1; i>=0; i--) {
11525            // Any services running in the application need to be placed
11526            // back in the pending list.
11527            ServiceRecord sr = app.services.valueAt(i);
11528            sr.crashCount++;
11529        }
11530
11531        // If the crashing process is what we consider to be the "home process" and it has been
11532        // replaced by a third-party app, clear the package preferred activities from packages
11533        // with a home activity running in the process to prevent a repeatedly crashing app
11534        // from blocking the user to manually clear the list.
11535        final ArrayList<ActivityRecord> activities = app.activities;
11536        if (app == mHomeProcess && activities.size() > 0
11537                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11538            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11539                final ActivityRecord r = activities.get(activityNdx);
11540                if (r.isHomeActivity()) {
11541                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11542                    try {
11543                        ActivityThread.getPackageManager()
11544                                .clearPackagePreferredActivities(r.packageName);
11545                    } catch (RemoteException c) {
11546                        // pm is in same process, this will never happen.
11547                    }
11548                }
11549            }
11550        }
11551
11552        if (!app.isolated) {
11553            // XXX Can't keep track of crash times for isolated processes,
11554            // because they don't have a perisistent identity.
11555            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11556        }
11557
11558        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11559        return true;
11560    }
11561
11562    void startAppProblemLocked(ProcessRecord app) {
11563        // If this app is not running under the current user, then we
11564        // can't give it a report button because that would require
11565        // launching the report UI under a different user.
11566        app.errorReportReceiver = null;
11567
11568        for (int userId : mCurrentProfileIds) {
11569            if (app.userId == userId) {
11570                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11571                        mContext, app.info.packageName, app.info.flags);
11572            }
11573        }
11574        skipCurrentReceiverLocked(app);
11575    }
11576
11577    void skipCurrentReceiverLocked(ProcessRecord app) {
11578        for (BroadcastQueue queue : mBroadcastQueues) {
11579            queue.skipCurrentReceiverLocked(app);
11580        }
11581    }
11582
11583    /**
11584     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11585     * The application process will exit immediately after this call returns.
11586     * @param app object of the crashing app, null for the system server
11587     * @param crashInfo describing the exception
11588     */
11589    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11590        ProcessRecord r = findAppProcess(app, "Crash");
11591        final String processName = app == null ? "system_server"
11592                : (r == null ? "unknown" : r.processName);
11593
11594        handleApplicationCrashInner("crash", r, processName, crashInfo);
11595    }
11596
11597    /* Native crash reporting uses this inner version because it needs to be somewhat
11598     * decoupled from the AM-managed cleanup lifecycle
11599     */
11600    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11601            ApplicationErrorReport.CrashInfo crashInfo) {
11602        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11603                UserHandle.getUserId(Binder.getCallingUid()), processName,
11604                r == null ? -1 : r.info.flags,
11605                crashInfo.exceptionClassName,
11606                crashInfo.exceptionMessage,
11607                crashInfo.throwFileName,
11608                crashInfo.throwLineNumber);
11609
11610        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11611
11612        crashApplication(r, crashInfo);
11613    }
11614
11615    public void handleApplicationStrictModeViolation(
11616            IBinder app,
11617            int violationMask,
11618            StrictMode.ViolationInfo info) {
11619        ProcessRecord r = findAppProcess(app, "StrictMode");
11620        if (r == null) {
11621            return;
11622        }
11623
11624        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11625            Integer stackFingerprint = info.hashCode();
11626            boolean logIt = true;
11627            synchronized (mAlreadyLoggedViolatedStacks) {
11628                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11629                    logIt = false;
11630                    // TODO: sub-sample into EventLog for these, with
11631                    // the info.durationMillis?  Then we'd get
11632                    // the relative pain numbers, without logging all
11633                    // the stack traces repeatedly.  We'd want to do
11634                    // likewise in the client code, which also does
11635                    // dup suppression, before the Binder call.
11636                } else {
11637                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11638                        mAlreadyLoggedViolatedStacks.clear();
11639                    }
11640                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11641                }
11642            }
11643            if (logIt) {
11644                logStrictModeViolationToDropBox(r, info);
11645            }
11646        }
11647
11648        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11649            AppErrorResult result = new AppErrorResult();
11650            synchronized (this) {
11651                final long origId = Binder.clearCallingIdentity();
11652
11653                Message msg = Message.obtain();
11654                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11655                HashMap<String, Object> data = new HashMap<String, Object>();
11656                data.put("result", result);
11657                data.put("app", r);
11658                data.put("violationMask", violationMask);
11659                data.put("info", info);
11660                msg.obj = data;
11661                mHandler.sendMessage(msg);
11662
11663                Binder.restoreCallingIdentity(origId);
11664            }
11665            int res = result.get();
11666            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11667        }
11668    }
11669
11670    // Depending on the policy in effect, there could be a bunch of
11671    // these in quick succession so we try to batch these together to
11672    // minimize disk writes, number of dropbox entries, and maximize
11673    // compression, by having more fewer, larger records.
11674    private void logStrictModeViolationToDropBox(
11675            ProcessRecord process,
11676            StrictMode.ViolationInfo info) {
11677        if (info == null) {
11678            return;
11679        }
11680        final boolean isSystemApp = process == null ||
11681                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11682                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11683        final String processName = process == null ? "unknown" : process.processName;
11684        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11685        final DropBoxManager dbox = (DropBoxManager)
11686                mContext.getSystemService(Context.DROPBOX_SERVICE);
11687
11688        // Exit early if the dropbox isn't configured to accept this report type.
11689        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11690
11691        boolean bufferWasEmpty;
11692        boolean needsFlush;
11693        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11694        synchronized (sb) {
11695            bufferWasEmpty = sb.length() == 0;
11696            appendDropBoxProcessHeaders(process, processName, sb);
11697            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11698            sb.append("System-App: ").append(isSystemApp).append("\n");
11699            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11700            if (info.violationNumThisLoop != 0) {
11701                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11702            }
11703            if (info.numAnimationsRunning != 0) {
11704                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11705            }
11706            if (info.broadcastIntentAction != null) {
11707                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11708            }
11709            if (info.durationMillis != -1) {
11710                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11711            }
11712            if (info.numInstances != -1) {
11713                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11714            }
11715            if (info.tags != null) {
11716                for (String tag : info.tags) {
11717                    sb.append("Span-Tag: ").append(tag).append("\n");
11718                }
11719            }
11720            sb.append("\n");
11721            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11722                sb.append(info.crashInfo.stackTrace);
11723            }
11724            sb.append("\n");
11725
11726            // Only buffer up to ~64k.  Various logging bits truncate
11727            // things at 128k.
11728            needsFlush = (sb.length() > 64 * 1024);
11729        }
11730
11731        // Flush immediately if the buffer's grown too large, or this
11732        // is a non-system app.  Non-system apps are isolated with a
11733        // different tag & policy and not batched.
11734        //
11735        // Batching is useful during internal testing with
11736        // StrictMode settings turned up high.  Without batching,
11737        // thousands of separate files could be created on boot.
11738        if (!isSystemApp || needsFlush) {
11739            new Thread("Error dump: " + dropboxTag) {
11740                @Override
11741                public void run() {
11742                    String report;
11743                    synchronized (sb) {
11744                        report = sb.toString();
11745                        sb.delete(0, sb.length());
11746                        sb.trimToSize();
11747                    }
11748                    if (report.length() != 0) {
11749                        dbox.addText(dropboxTag, report);
11750                    }
11751                }
11752            }.start();
11753            return;
11754        }
11755
11756        // System app batching:
11757        if (!bufferWasEmpty) {
11758            // An existing dropbox-writing thread is outstanding, so
11759            // we don't need to start it up.  The existing thread will
11760            // catch the buffer appends we just did.
11761            return;
11762        }
11763
11764        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11765        // (After this point, we shouldn't access AMS internal data structures.)
11766        new Thread("Error dump: " + dropboxTag) {
11767            @Override
11768            public void run() {
11769                // 5 second sleep to let stacks arrive and be batched together
11770                try {
11771                    Thread.sleep(5000);  // 5 seconds
11772                } catch (InterruptedException e) {}
11773
11774                String errorReport;
11775                synchronized (mStrictModeBuffer) {
11776                    errorReport = mStrictModeBuffer.toString();
11777                    if (errorReport.length() == 0) {
11778                        return;
11779                    }
11780                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11781                    mStrictModeBuffer.trimToSize();
11782                }
11783                dbox.addText(dropboxTag, errorReport);
11784            }
11785        }.start();
11786    }
11787
11788    /**
11789     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11790     * @param app object of the crashing app, null for the system server
11791     * @param tag reported by the caller
11792     * @param system whether this wtf is coming from the system
11793     * @param crashInfo describing the context of the error
11794     * @return true if the process should exit immediately (WTF is fatal)
11795     */
11796    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11797            final ApplicationErrorReport.CrashInfo crashInfo) {
11798        final int callingUid = Binder.getCallingUid();
11799        final int callingPid = Binder.getCallingPid();
11800
11801        if (system) {
11802            // If this is coming from the system, we could very well have low-level
11803            // system locks held, so we want to do this all asynchronously.  And we
11804            // never want this to become fatal, so there is that too.
11805            mHandler.post(new Runnable() {
11806                @Override public void run() {
11807                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11808                }
11809            });
11810            return false;
11811        }
11812
11813        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11814                crashInfo);
11815
11816        if (r != null && r.pid != Process.myPid() &&
11817                Settings.Global.getInt(mContext.getContentResolver(),
11818                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11819            crashApplication(r, crashInfo);
11820            return true;
11821        } else {
11822            return false;
11823        }
11824    }
11825
11826    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11827            final ApplicationErrorReport.CrashInfo crashInfo) {
11828        final ProcessRecord r = findAppProcess(app, "WTF");
11829        final String processName = app == null ? "system_server"
11830                : (r == null ? "unknown" : r.processName);
11831
11832        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11833                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11834
11835        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11836
11837        return r;
11838    }
11839
11840    /**
11841     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11842     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11843     */
11844    private ProcessRecord findAppProcess(IBinder app, String reason) {
11845        if (app == null) {
11846            return null;
11847        }
11848
11849        synchronized (this) {
11850            final int NP = mProcessNames.getMap().size();
11851            for (int ip=0; ip<NP; ip++) {
11852                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11853                final int NA = apps.size();
11854                for (int ia=0; ia<NA; ia++) {
11855                    ProcessRecord p = apps.valueAt(ia);
11856                    if (p.thread != null && p.thread.asBinder() == app) {
11857                        return p;
11858                    }
11859                }
11860            }
11861
11862            Slog.w(TAG, "Can't find mystery application for " + reason
11863                    + " from pid=" + Binder.getCallingPid()
11864                    + " uid=" + Binder.getCallingUid() + ": " + app);
11865            return null;
11866        }
11867    }
11868
11869    /**
11870     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11871     * to append various headers to the dropbox log text.
11872     */
11873    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11874            StringBuilder sb) {
11875        // Watchdog thread ends up invoking this function (with
11876        // a null ProcessRecord) to add the stack file to dropbox.
11877        // Do not acquire a lock on this (am) in such cases, as it
11878        // could cause a potential deadlock, if and when watchdog
11879        // is invoked due to unavailability of lock on am and it
11880        // would prevent watchdog from killing system_server.
11881        if (process == null) {
11882            sb.append("Process: ").append(processName).append("\n");
11883            return;
11884        }
11885        // Note: ProcessRecord 'process' is guarded by the service
11886        // instance.  (notably process.pkgList, which could otherwise change
11887        // concurrently during execution of this method)
11888        synchronized (this) {
11889            sb.append("Process: ").append(processName).append("\n");
11890            int flags = process.info.flags;
11891            IPackageManager pm = AppGlobals.getPackageManager();
11892            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11893            for (int ip=0; ip<process.pkgList.size(); ip++) {
11894                String pkg = process.pkgList.keyAt(ip);
11895                sb.append("Package: ").append(pkg);
11896                try {
11897                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11898                    if (pi != null) {
11899                        sb.append(" v").append(pi.versionCode);
11900                        if (pi.versionName != null) {
11901                            sb.append(" (").append(pi.versionName).append(")");
11902                        }
11903                    }
11904                } catch (RemoteException e) {
11905                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11906                }
11907                sb.append("\n");
11908            }
11909        }
11910    }
11911
11912    private static String processClass(ProcessRecord process) {
11913        if (process == null || process.pid == MY_PID) {
11914            return "system_server";
11915        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11916            return "system_app";
11917        } else {
11918            return "data_app";
11919        }
11920    }
11921
11922    /**
11923     * Write a description of an error (crash, WTF, ANR) to the drop box.
11924     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11925     * @param process which caused the error, null means the system server
11926     * @param activity which triggered the error, null if unknown
11927     * @param parent activity related to the error, null if unknown
11928     * @param subject line related to the error, null if absent
11929     * @param report in long form describing the error, null if absent
11930     * @param logFile to include in the report, null if none
11931     * @param crashInfo giving an application stack trace, null if absent
11932     */
11933    public void addErrorToDropBox(String eventType,
11934            ProcessRecord process, String processName, ActivityRecord activity,
11935            ActivityRecord parent, String subject,
11936            final String report, final File logFile,
11937            final ApplicationErrorReport.CrashInfo crashInfo) {
11938        // NOTE -- this must never acquire the ActivityManagerService lock,
11939        // otherwise the watchdog may be prevented from resetting the system.
11940
11941        final String dropboxTag = processClass(process) + "_" + eventType;
11942        final DropBoxManager dbox = (DropBoxManager)
11943                mContext.getSystemService(Context.DROPBOX_SERVICE);
11944
11945        // Exit early if the dropbox isn't configured to accept this report type.
11946        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11947
11948        final StringBuilder sb = new StringBuilder(1024);
11949        appendDropBoxProcessHeaders(process, processName, sb);
11950        if (activity != null) {
11951            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11952        }
11953        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11954            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11955        }
11956        if (parent != null && parent != activity) {
11957            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11958        }
11959        if (subject != null) {
11960            sb.append("Subject: ").append(subject).append("\n");
11961        }
11962        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11963        if (Debug.isDebuggerConnected()) {
11964            sb.append("Debugger: Connected\n");
11965        }
11966        sb.append("\n");
11967
11968        // Do the rest in a worker thread to avoid blocking the caller on I/O
11969        // (After this point, we shouldn't access AMS internal data structures.)
11970        Thread worker = new Thread("Error dump: " + dropboxTag) {
11971            @Override
11972            public void run() {
11973                if (report != null) {
11974                    sb.append(report);
11975                }
11976                if (logFile != null) {
11977                    try {
11978                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11979                                    "\n\n[[TRUNCATED]]"));
11980                    } catch (IOException e) {
11981                        Slog.e(TAG, "Error reading " + logFile, e);
11982                    }
11983                }
11984                if (crashInfo != null && crashInfo.stackTrace != null) {
11985                    sb.append(crashInfo.stackTrace);
11986                }
11987
11988                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11989                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11990                if (lines > 0) {
11991                    sb.append("\n");
11992
11993                    // Merge several logcat streams, and take the last N lines
11994                    InputStreamReader input = null;
11995                    try {
11996                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11997                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11998                                "-b", "crash",
11999                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12000
12001                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12002                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12003                        input = new InputStreamReader(logcat.getInputStream());
12004
12005                        int num;
12006                        char[] buf = new char[8192];
12007                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12008                    } catch (IOException e) {
12009                        Slog.e(TAG, "Error running logcat", e);
12010                    } finally {
12011                        if (input != null) try { input.close(); } catch (IOException e) {}
12012                    }
12013                }
12014
12015                dbox.addText(dropboxTag, sb.toString());
12016            }
12017        };
12018
12019        if (process == null) {
12020            // If process is null, we are being called from some internal code
12021            // and may be about to die -- run this synchronously.
12022            worker.run();
12023        } else {
12024            worker.start();
12025        }
12026    }
12027
12028    /**
12029     * Bring up the "unexpected error" dialog box for a crashing app.
12030     * Deal with edge cases (intercepts from instrumented applications,
12031     * ActivityController, error intent receivers, that sort of thing).
12032     * @param r the application crashing
12033     * @param crashInfo describing the failure
12034     */
12035    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12036        long timeMillis = System.currentTimeMillis();
12037        String shortMsg = crashInfo.exceptionClassName;
12038        String longMsg = crashInfo.exceptionMessage;
12039        String stackTrace = crashInfo.stackTrace;
12040        if (shortMsg != null && longMsg != null) {
12041            longMsg = shortMsg + ": " + longMsg;
12042        } else if (shortMsg != null) {
12043            longMsg = shortMsg;
12044        }
12045
12046        AppErrorResult result = new AppErrorResult();
12047        synchronized (this) {
12048            if (mController != null) {
12049                try {
12050                    String name = r != null ? r.processName : null;
12051                    int pid = r != null ? r.pid : Binder.getCallingPid();
12052                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12053                    if (!mController.appCrashed(name, pid,
12054                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12055                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12056                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12057                            Slog.w(TAG, "Skip killing native crashed app " + name
12058                                    + "(" + pid + ") during testing");
12059                        } else {
12060                            Slog.w(TAG, "Force-killing crashed app " + name
12061                                    + " at watcher's request");
12062                            if (r != null) {
12063                                r.kill("crash", true);
12064                            } else {
12065                                // Huh.
12066                                Process.killProcess(pid);
12067                                Process.killProcessGroup(uid, pid);
12068                            }
12069                        }
12070                        return;
12071                    }
12072                } catch (RemoteException e) {
12073                    mController = null;
12074                    Watchdog.getInstance().setActivityController(null);
12075                }
12076            }
12077
12078            final long origId = Binder.clearCallingIdentity();
12079
12080            // If this process is running instrumentation, finish it.
12081            if (r != null && r.instrumentationClass != null) {
12082                Slog.w(TAG, "Error in app " + r.processName
12083                      + " running instrumentation " + r.instrumentationClass + ":");
12084                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12085                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12086                Bundle info = new Bundle();
12087                info.putString("shortMsg", shortMsg);
12088                info.putString("longMsg", longMsg);
12089                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12090                Binder.restoreCallingIdentity(origId);
12091                return;
12092            }
12093
12094            // If we can't identify the process or it's already exceeded its crash quota,
12095            // quit right away without showing a crash dialog.
12096            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12097                Binder.restoreCallingIdentity(origId);
12098                return;
12099            }
12100
12101            Message msg = Message.obtain();
12102            msg.what = SHOW_ERROR_MSG;
12103            HashMap data = new HashMap();
12104            data.put("result", result);
12105            data.put("app", r);
12106            msg.obj = data;
12107            mHandler.sendMessage(msg);
12108
12109            Binder.restoreCallingIdentity(origId);
12110        }
12111
12112        int res = result.get();
12113
12114        Intent appErrorIntent = null;
12115        synchronized (this) {
12116            if (r != null && !r.isolated) {
12117                // XXX Can't keep track of crash time for isolated processes,
12118                // since they don't have a persistent identity.
12119                mProcessCrashTimes.put(r.info.processName, r.uid,
12120                        SystemClock.uptimeMillis());
12121            }
12122            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12123                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12124            }
12125        }
12126
12127        if (appErrorIntent != null) {
12128            try {
12129                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12130            } catch (ActivityNotFoundException e) {
12131                Slog.w(TAG, "bug report receiver dissappeared", e);
12132            }
12133        }
12134    }
12135
12136    Intent createAppErrorIntentLocked(ProcessRecord r,
12137            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12138        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12139        if (report == null) {
12140            return null;
12141        }
12142        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12143        result.setComponent(r.errorReportReceiver);
12144        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12145        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12146        return result;
12147    }
12148
12149    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12150            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12151        if (r.errorReportReceiver == null) {
12152            return null;
12153        }
12154
12155        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12156            return null;
12157        }
12158
12159        ApplicationErrorReport report = new ApplicationErrorReport();
12160        report.packageName = r.info.packageName;
12161        report.installerPackageName = r.errorReportReceiver.getPackageName();
12162        report.processName = r.processName;
12163        report.time = timeMillis;
12164        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12165
12166        if (r.crashing || r.forceCrashReport) {
12167            report.type = ApplicationErrorReport.TYPE_CRASH;
12168            report.crashInfo = crashInfo;
12169        } else if (r.notResponding) {
12170            report.type = ApplicationErrorReport.TYPE_ANR;
12171            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12172
12173            report.anrInfo.activity = r.notRespondingReport.tag;
12174            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12175            report.anrInfo.info = r.notRespondingReport.longMsg;
12176        }
12177
12178        return report;
12179    }
12180
12181    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12182        enforceNotIsolatedCaller("getProcessesInErrorState");
12183        // assume our apps are happy - lazy create the list
12184        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12185
12186        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12187                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12188        int userId = UserHandle.getUserId(Binder.getCallingUid());
12189
12190        synchronized (this) {
12191
12192            // iterate across all processes
12193            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12194                ProcessRecord app = mLruProcesses.get(i);
12195                if (!allUsers && app.userId != userId) {
12196                    continue;
12197                }
12198                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12199                    // This one's in trouble, so we'll generate a report for it
12200                    // crashes are higher priority (in case there's a crash *and* an anr)
12201                    ActivityManager.ProcessErrorStateInfo report = null;
12202                    if (app.crashing) {
12203                        report = app.crashingReport;
12204                    } else if (app.notResponding) {
12205                        report = app.notRespondingReport;
12206                    }
12207
12208                    if (report != null) {
12209                        if (errList == null) {
12210                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12211                        }
12212                        errList.add(report);
12213                    } else {
12214                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12215                                " crashing = " + app.crashing +
12216                                " notResponding = " + app.notResponding);
12217                    }
12218                }
12219            }
12220        }
12221
12222        return errList;
12223    }
12224
12225    static int procStateToImportance(int procState, int memAdj,
12226            ActivityManager.RunningAppProcessInfo currApp) {
12227        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12228        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12229            currApp.lru = memAdj;
12230        } else {
12231            currApp.lru = 0;
12232        }
12233        return imp;
12234    }
12235
12236    private void fillInProcMemInfo(ProcessRecord app,
12237            ActivityManager.RunningAppProcessInfo outInfo) {
12238        outInfo.pid = app.pid;
12239        outInfo.uid = app.info.uid;
12240        if (mHeavyWeightProcess == app) {
12241            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12242        }
12243        if (app.persistent) {
12244            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12245        }
12246        if (app.activities.size() > 0) {
12247            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12248        }
12249        outInfo.lastTrimLevel = app.trimMemoryLevel;
12250        int adj = app.curAdj;
12251        int procState = app.curProcState;
12252        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12253        outInfo.importanceReasonCode = app.adjTypeCode;
12254        outInfo.processState = app.curProcState;
12255    }
12256
12257    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12258        enforceNotIsolatedCaller("getRunningAppProcesses");
12259        // Lazy instantiation of list
12260        List<ActivityManager.RunningAppProcessInfo> runList = null;
12261        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12262                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12263        int userId = UserHandle.getUserId(Binder.getCallingUid());
12264        synchronized (this) {
12265            // Iterate across all processes
12266            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12267                ProcessRecord app = mLruProcesses.get(i);
12268                if (!allUsers && app.userId != userId) {
12269                    continue;
12270                }
12271                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12272                    // Generate process state info for running application
12273                    ActivityManager.RunningAppProcessInfo currApp =
12274                        new ActivityManager.RunningAppProcessInfo(app.processName,
12275                                app.pid, app.getPackageList());
12276                    fillInProcMemInfo(app, currApp);
12277                    if (app.adjSource instanceof ProcessRecord) {
12278                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12279                        currApp.importanceReasonImportance =
12280                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12281                                        app.adjSourceProcState);
12282                    } else if (app.adjSource instanceof ActivityRecord) {
12283                        ActivityRecord r = (ActivityRecord)app.adjSource;
12284                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12285                    }
12286                    if (app.adjTarget instanceof ComponentName) {
12287                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12288                    }
12289                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12290                    //        + " lru=" + currApp.lru);
12291                    if (runList == null) {
12292                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12293                    }
12294                    runList.add(currApp);
12295                }
12296            }
12297        }
12298        return runList;
12299    }
12300
12301    public List<ApplicationInfo> getRunningExternalApplications() {
12302        enforceNotIsolatedCaller("getRunningExternalApplications");
12303        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12304        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12305        if (runningApps != null && runningApps.size() > 0) {
12306            Set<String> extList = new HashSet<String>();
12307            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12308                if (app.pkgList != null) {
12309                    for (String pkg : app.pkgList) {
12310                        extList.add(pkg);
12311                    }
12312                }
12313            }
12314            IPackageManager pm = AppGlobals.getPackageManager();
12315            for (String pkg : extList) {
12316                try {
12317                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12318                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12319                        retList.add(info);
12320                    }
12321                } catch (RemoteException e) {
12322                }
12323            }
12324        }
12325        return retList;
12326    }
12327
12328    @Override
12329    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12330        enforceNotIsolatedCaller("getMyMemoryState");
12331        synchronized (this) {
12332            ProcessRecord proc;
12333            synchronized (mPidsSelfLocked) {
12334                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12335            }
12336            fillInProcMemInfo(proc, outInfo);
12337        }
12338    }
12339
12340    @Override
12341    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12342        if (checkCallingPermission(android.Manifest.permission.DUMP)
12343                != PackageManager.PERMISSION_GRANTED) {
12344            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12345                    + Binder.getCallingPid()
12346                    + ", uid=" + Binder.getCallingUid()
12347                    + " without permission "
12348                    + android.Manifest.permission.DUMP);
12349            return;
12350        }
12351
12352        boolean dumpAll = false;
12353        boolean dumpClient = false;
12354        String dumpPackage = null;
12355
12356        int opti = 0;
12357        while (opti < args.length) {
12358            String opt = args[opti];
12359            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12360                break;
12361            }
12362            opti++;
12363            if ("-a".equals(opt)) {
12364                dumpAll = true;
12365            } else if ("-c".equals(opt)) {
12366                dumpClient = true;
12367            } else if ("-h".equals(opt)) {
12368                pw.println("Activity manager dump options:");
12369                pw.println("  [-a] [-c] [-h] [cmd] ...");
12370                pw.println("  cmd may be one of:");
12371                pw.println("    a[ctivities]: activity stack state");
12372                pw.println("    r[recents]: recent activities state");
12373                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12374                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12375                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12376                pw.println("    o[om]: out of memory management");
12377                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12378                pw.println("    provider [COMP_SPEC]: provider client-side state");
12379                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12380                pw.println("    service [COMP_SPEC]: service client-side state");
12381                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12382                pw.println("    all: dump all activities");
12383                pw.println("    top: dump the top activity");
12384                pw.println("    write: write all pending state to storage");
12385                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12386                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12387                pw.println("    a partial substring in a component name, a");
12388                pw.println("    hex object identifier.");
12389                pw.println("  -a: include all available server state.");
12390                pw.println("  -c: include client state.");
12391                return;
12392            } else {
12393                pw.println("Unknown argument: " + opt + "; use -h for help");
12394            }
12395        }
12396
12397        long origId = Binder.clearCallingIdentity();
12398        boolean more = false;
12399        // Is the caller requesting to dump a particular piece of data?
12400        if (opti < args.length) {
12401            String cmd = args[opti];
12402            opti++;
12403            if ("activities".equals(cmd) || "a".equals(cmd)) {
12404                synchronized (this) {
12405                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12406                }
12407            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12408                synchronized (this) {
12409                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12410                }
12411            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12412                String[] newArgs;
12413                String name;
12414                if (opti >= args.length) {
12415                    name = null;
12416                    newArgs = EMPTY_STRING_ARRAY;
12417                } else {
12418                    name = args[opti];
12419                    opti++;
12420                    newArgs = new String[args.length - opti];
12421                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12422                            args.length - opti);
12423                }
12424                synchronized (this) {
12425                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12426                }
12427            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12428                String[] newArgs;
12429                String name;
12430                if (opti >= args.length) {
12431                    name = null;
12432                    newArgs = EMPTY_STRING_ARRAY;
12433                } else {
12434                    name = args[opti];
12435                    opti++;
12436                    newArgs = new String[args.length - opti];
12437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12438                            args.length - opti);
12439                }
12440                synchronized (this) {
12441                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12442                }
12443            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12444                String[] newArgs;
12445                String name;
12446                if (opti >= args.length) {
12447                    name = null;
12448                    newArgs = EMPTY_STRING_ARRAY;
12449                } else {
12450                    name = args[opti];
12451                    opti++;
12452                    newArgs = new String[args.length - opti];
12453                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12454                            args.length - opti);
12455                }
12456                synchronized (this) {
12457                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12458                }
12459            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12460                synchronized (this) {
12461                    dumpOomLocked(fd, pw, args, opti, true);
12462                }
12463            } else if ("provider".equals(cmd)) {
12464                String[] newArgs;
12465                String name;
12466                if (opti >= args.length) {
12467                    name = null;
12468                    newArgs = EMPTY_STRING_ARRAY;
12469                } else {
12470                    name = args[opti];
12471                    opti++;
12472                    newArgs = new String[args.length - opti];
12473                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12474                }
12475                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12476                    pw.println("No providers match: " + name);
12477                    pw.println("Use -h for help.");
12478                }
12479            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12480                synchronized (this) {
12481                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12482                }
12483            } else if ("service".equals(cmd)) {
12484                String[] newArgs;
12485                String name;
12486                if (opti >= args.length) {
12487                    name = null;
12488                    newArgs = EMPTY_STRING_ARRAY;
12489                } else {
12490                    name = args[opti];
12491                    opti++;
12492                    newArgs = new String[args.length - opti];
12493                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12494                            args.length - opti);
12495                }
12496                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12497                    pw.println("No services match: " + name);
12498                    pw.println("Use -h for help.");
12499                }
12500            } else if ("package".equals(cmd)) {
12501                String[] newArgs;
12502                if (opti >= args.length) {
12503                    pw.println("package: no package name specified");
12504                    pw.println("Use -h for help.");
12505                } else {
12506                    dumpPackage = args[opti];
12507                    opti++;
12508                    newArgs = new String[args.length - opti];
12509                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12510                            args.length - opti);
12511                    args = newArgs;
12512                    opti = 0;
12513                    more = true;
12514                }
12515            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12516                synchronized (this) {
12517                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12518                }
12519            } else if ("write".equals(cmd)) {
12520                mTaskPersister.flush();
12521                pw.println("All tasks persisted.");
12522                return;
12523            } else {
12524                // Dumping a single activity?
12525                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12526                    pw.println("Bad activity command, or no activities match: " + cmd);
12527                    pw.println("Use -h for help.");
12528                }
12529            }
12530            if (!more) {
12531                Binder.restoreCallingIdentity(origId);
12532                return;
12533            }
12534        }
12535
12536        // No piece of data specified, dump everything.
12537        synchronized (this) {
12538            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12539            pw.println();
12540            if (dumpAll) {
12541                pw.println("-------------------------------------------------------------------------------");
12542            }
12543            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12544            pw.println();
12545            if (dumpAll) {
12546                pw.println("-------------------------------------------------------------------------------");
12547            }
12548            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12549            pw.println();
12550            if (dumpAll) {
12551                pw.println("-------------------------------------------------------------------------------");
12552            }
12553            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12554            pw.println();
12555            if (dumpAll) {
12556                pw.println("-------------------------------------------------------------------------------");
12557            }
12558            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12559            pw.println();
12560            if (dumpAll) {
12561                pw.println("-------------------------------------------------------------------------------");
12562            }
12563            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12564            pw.println();
12565            if (dumpAll) {
12566                pw.println("-------------------------------------------------------------------------------");
12567            }
12568            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12569        }
12570        Binder.restoreCallingIdentity(origId);
12571    }
12572
12573    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12574            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12575        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12576
12577        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12578                dumpPackage);
12579        boolean needSep = printedAnything;
12580
12581        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12582                dumpPackage, needSep, "  mFocusedActivity: ");
12583        if (printed) {
12584            printedAnything = true;
12585            needSep = false;
12586        }
12587
12588        if (dumpPackage == null) {
12589            if (needSep) {
12590                pw.println();
12591            }
12592            needSep = true;
12593            printedAnything = true;
12594            mStackSupervisor.dump(pw, "  ");
12595        }
12596
12597        if (!printedAnything) {
12598            pw.println("  (nothing)");
12599        }
12600    }
12601
12602    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12603            int opti, boolean dumpAll, String dumpPackage) {
12604        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12605
12606        boolean printedAnything = false;
12607
12608        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12609            boolean printedHeader = false;
12610
12611            final int N = mRecentTasks.size();
12612            for (int i=0; i<N; i++) {
12613                TaskRecord tr = mRecentTasks.get(i);
12614                if (dumpPackage != null) {
12615                    if (tr.realActivity == null ||
12616                            !dumpPackage.equals(tr.realActivity)) {
12617                        continue;
12618                    }
12619                }
12620                if (!printedHeader) {
12621                    pw.println("  Recent tasks:");
12622                    printedHeader = true;
12623                    printedAnything = true;
12624                }
12625                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12626                        pw.println(tr);
12627                if (dumpAll) {
12628                    mRecentTasks.get(i).dump(pw, "    ");
12629                }
12630            }
12631        }
12632
12633        if (!printedAnything) {
12634            pw.println("  (nothing)");
12635        }
12636    }
12637
12638    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12639            int opti, boolean dumpAll, String dumpPackage) {
12640        boolean needSep = false;
12641        boolean printedAnything = false;
12642        int numPers = 0;
12643
12644        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12645
12646        if (dumpAll) {
12647            final int NP = mProcessNames.getMap().size();
12648            for (int ip=0; ip<NP; ip++) {
12649                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12650                final int NA = procs.size();
12651                for (int ia=0; ia<NA; ia++) {
12652                    ProcessRecord r = procs.valueAt(ia);
12653                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12654                        continue;
12655                    }
12656                    if (!needSep) {
12657                        pw.println("  All known processes:");
12658                        needSep = true;
12659                        printedAnything = true;
12660                    }
12661                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12662                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12663                        pw.print(" "); pw.println(r);
12664                    r.dump(pw, "    ");
12665                    if (r.persistent) {
12666                        numPers++;
12667                    }
12668                }
12669            }
12670        }
12671
12672        if (mIsolatedProcesses.size() > 0) {
12673            boolean printed = false;
12674            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12675                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12676                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12677                    continue;
12678                }
12679                if (!printed) {
12680                    if (needSep) {
12681                        pw.println();
12682                    }
12683                    pw.println("  Isolated process list (sorted by uid):");
12684                    printedAnything = true;
12685                    printed = true;
12686                    needSep = true;
12687                }
12688                pw.println(String.format("%sIsolated #%2d: %s",
12689                        "    ", i, r.toString()));
12690            }
12691        }
12692
12693        if (mLruProcesses.size() > 0) {
12694            if (needSep) {
12695                pw.println();
12696            }
12697            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12698                    pw.print(" total, non-act at ");
12699                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12700                    pw.print(", non-svc at ");
12701                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12702                    pw.println("):");
12703            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12704            needSep = true;
12705            printedAnything = true;
12706        }
12707
12708        if (dumpAll || dumpPackage != null) {
12709            synchronized (mPidsSelfLocked) {
12710                boolean printed = false;
12711                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12712                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12713                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12714                        continue;
12715                    }
12716                    if (!printed) {
12717                        if (needSep) pw.println();
12718                        needSep = true;
12719                        pw.println("  PID mappings:");
12720                        printed = true;
12721                        printedAnything = true;
12722                    }
12723                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12724                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12725                }
12726            }
12727        }
12728
12729        if (mForegroundProcesses.size() > 0) {
12730            synchronized (mPidsSelfLocked) {
12731                boolean printed = false;
12732                for (int i=0; i<mForegroundProcesses.size(); i++) {
12733                    ProcessRecord r = mPidsSelfLocked.get(
12734                            mForegroundProcesses.valueAt(i).pid);
12735                    if (dumpPackage != null && (r == null
12736                            || !r.pkgList.containsKey(dumpPackage))) {
12737                        continue;
12738                    }
12739                    if (!printed) {
12740                        if (needSep) pw.println();
12741                        needSep = true;
12742                        pw.println("  Foreground Processes:");
12743                        printed = true;
12744                        printedAnything = true;
12745                    }
12746                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12747                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12748                }
12749            }
12750        }
12751
12752        if (mPersistentStartingProcesses.size() > 0) {
12753            if (needSep) pw.println();
12754            needSep = true;
12755            printedAnything = true;
12756            pw.println("  Persisent processes that are starting:");
12757            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12758                    "Starting Norm", "Restarting PERS", dumpPackage);
12759        }
12760
12761        if (mRemovedProcesses.size() > 0) {
12762            if (needSep) pw.println();
12763            needSep = true;
12764            printedAnything = true;
12765            pw.println("  Processes that are being removed:");
12766            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12767                    "Removed Norm", "Removed PERS", dumpPackage);
12768        }
12769
12770        if (mProcessesOnHold.size() > 0) {
12771            if (needSep) pw.println();
12772            needSep = true;
12773            printedAnything = true;
12774            pw.println("  Processes that are on old until the system is ready:");
12775            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12776                    "OnHold Norm", "OnHold PERS", dumpPackage);
12777        }
12778
12779        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12780
12781        if (mProcessCrashTimes.getMap().size() > 0) {
12782            boolean printed = false;
12783            long now = SystemClock.uptimeMillis();
12784            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12785            final int NP = pmap.size();
12786            for (int ip=0; ip<NP; ip++) {
12787                String pname = pmap.keyAt(ip);
12788                SparseArray<Long> uids = pmap.valueAt(ip);
12789                final int N = uids.size();
12790                for (int i=0; i<N; i++) {
12791                    int puid = uids.keyAt(i);
12792                    ProcessRecord r = mProcessNames.get(pname, puid);
12793                    if (dumpPackage != null && (r == null
12794                            || !r.pkgList.containsKey(dumpPackage))) {
12795                        continue;
12796                    }
12797                    if (!printed) {
12798                        if (needSep) pw.println();
12799                        needSep = true;
12800                        pw.println("  Time since processes crashed:");
12801                        printed = true;
12802                        printedAnything = true;
12803                    }
12804                    pw.print("    Process "); pw.print(pname);
12805                            pw.print(" uid "); pw.print(puid);
12806                            pw.print(": last crashed ");
12807                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12808                            pw.println(" ago");
12809                }
12810            }
12811        }
12812
12813        if (mBadProcesses.getMap().size() > 0) {
12814            boolean printed = false;
12815            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12816            final int NP = pmap.size();
12817            for (int ip=0; ip<NP; ip++) {
12818                String pname = pmap.keyAt(ip);
12819                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12820                final int N = uids.size();
12821                for (int i=0; i<N; i++) {
12822                    int puid = uids.keyAt(i);
12823                    ProcessRecord r = mProcessNames.get(pname, puid);
12824                    if (dumpPackage != null && (r == null
12825                            || !r.pkgList.containsKey(dumpPackage))) {
12826                        continue;
12827                    }
12828                    if (!printed) {
12829                        if (needSep) pw.println();
12830                        needSep = true;
12831                        pw.println("  Bad processes:");
12832                        printedAnything = true;
12833                    }
12834                    BadProcessInfo info = uids.valueAt(i);
12835                    pw.print("    Bad process "); pw.print(pname);
12836                            pw.print(" uid "); pw.print(puid);
12837                            pw.print(": crashed at time "); pw.println(info.time);
12838                    if (info.shortMsg != null) {
12839                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12840                    }
12841                    if (info.longMsg != null) {
12842                        pw.print("      Long msg: "); pw.println(info.longMsg);
12843                    }
12844                    if (info.stack != null) {
12845                        pw.println("      Stack:");
12846                        int lastPos = 0;
12847                        for (int pos=0; pos<info.stack.length(); pos++) {
12848                            if (info.stack.charAt(pos) == '\n') {
12849                                pw.print("        ");
12850                                pw.write(info.stack, lastPos, pos-lastPos);
12851                                pw.println();
12852                                lastPos = pos+1;
12853                            }
12854                        }
12855                        if (lastPos < info.stack.length()) {
12856                            pw.print("        ");
12857                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12858                            pw.println();
12859                        }
12860                    }
12861                }
12862            }
12863        }
12864
12865        if (dumpPackage == null) {
12866            pw.println();
12867            needSep = false;
12868            pw.println("  mStartedUsers:");
12869            for (int i=0; i<mStartedUsers.size(); i++) {
12870                UserStartedState uss = mStartedUsers.valueAt(i);
12871                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12872                        pw.print(": "); uss.dump("", pw);
12873            }
12874            pw.print("  mStartedUserArray: [");
12875            for (int i=0; i<mStartedUserArray.length; i++) {
12876                if (i > 0) pw.print(", ");
12877                pw.print(mStartedUserArray[i]);
12878            }
12879            pw.println("]");
12880            pw.print("  mUserLru: [");
12881            for (int i=0; i<mUserLru.size(); i++) {
12882                if (i > 0) pw.print(", ");
12883                pw.print(mUserLru.get(i));
12884            }
12885            pw.println("]");
12886            if (dumpAll) {
12887                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12888            }
12889            synchronized (mUserProfileGroupIdsSelfLocked) {
12890                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12891                    pw.println("  mUserProfileGroupIds:");
12892                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12893                        pw.print("    User #");
12894                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12895                        pw.print(" -> profile #");
12896                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12897                    }
12898                }
12899            }
12900        }
12901        if (mHomeProcess != null && (dumpPackage == null
12902                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12903            if (needSep) {
12904                pw.println();
12905                needSep = false;
12906            }
12907            pw.println("  mHomeProcess: " + mHomeProcess);
12908        }
12909        if (mPreviousProcess != null && (dumpPackage == null
12910                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12911            if (needSep) {
12912                pw.println();
12913                needSep = false;
12914            }
12915            pw.println("  mPreviousProcess: " + mPreviousProcess);
12916        }
12917        if (dumpAll) {
12918            StringBuilder sb = new StringBuilder(128);
12919            sb.append("  mPreviousProcessVisibleTime: ");
12920            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12921            pw.println(sb);
12922        }
12923        if (mHeavyWeightProcess != null && (dumpPackage == null
12924                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12925            if (needSep) {
12926                pw.println();
12927                needSep = false;
12928            }
12929            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12930        }
12931        if (dumpPackage == null) {
12932            pw.println("  mConfiguration: " + mConfiguration);
12933        }
12934        if (dumpAll) {
12935            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12936            if (mCompatModePackages.getPackages().size() > 0) {
12937                boolean printed = false;
12938                for (Map.Entry<String, Integer> entry
12939                        : mCompatModePackages.getPackages().entrySet()) {
12940                    String pkg = entry.getKey();
12941                    int mode = entry.getValue();
12942                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12943                        continue;
12944                    }
12945                    if (!printed) {
12946                        pw.println("  mScreenCompatPackages:");
12947                        printed = true;
12948                    }
12949                    pw.print("    "); pw.print(pkg); pw.print(": ");
12950                            pw.print(mode); pw.println();
12951                }
12952            }
12953        }
12954        if (dumpPackage == null) {
12955            pw.println("  mWakefulness="
12956                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12957            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown=" + mLockScreenShown);
12958            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12959        }
12960        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12961                || mOrigWaitForDebugger) {
12962            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12963                    || dumpPackage.equals(mOrigDebugApp)) {
12964                if (needSep) {
12965                    pw.println();
12966                    needSep = false;
12967                }
12968                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12969                        + " mDebugTransient=" + mDebugTransient
12970                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12971            }
12972        }
12973        if (mOpenGlTraceApp != null) {
12974            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12975                if (needSep) {
12976                    pw.println();
12977                    needSep = false;
12978                }
12979                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12980            }
12981        }
12982        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12983                || mProfileFd != null) {
12984            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12985                if (needSep) {
12986                    pw.println();
12987                    needSep = false;
12988                }
12989                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12990                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12991                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12992                        + mAutoStopProfiler);
12993                pw.println("  mProfileType=" + mProfileType);
12994            }
12995        }
12996        if (dumpPackage == null) {
12997            if (mAlwaysFinishActivities || mController != null) {
12998                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12999                        + " mController=" + mController);
13000            }
13001            if (dumpAll) {
13002                pw.println("  Total persistent processes: " + numPers);
13003                pw.println("  mProcessesReady=" + mProcessesReady
13004                        + " mSystemReady=" + mSystemReady
13005                        + " mBooted=" + mBooted
13006                        + " mFactoryTest=" + mFactoryTest);
13007                pw.println("  mBooting=" + mBooting
13008                        + " mCallFinishBooting=" + mCallFinishBooting
13009                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13010                pw.print("  mLastPowerCheckRealtime=");
13011                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13012                        pw.println("");
13013                pw.print("  mLastPowerCheckUptime=");
13014                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13015                        pw.println("");
13016                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13017                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13018                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13019                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13020                        + " (" + mLruProcesses.size() + " total)"
13021                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13022                        + " mNumServiceProcs=" + mNumServiceProcs
13023                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13024                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13025                        + " mLastMemoryLevel" + mLastMemoryLevel
13026                        + " mLastNumProcesses" + mLastNumProcesses);
13027                long now = SystemClock.uptimeMillis();
13028                pw.print("  mLastIdleTime=");
13029                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13030                        pw.print(" mLowRamSinceLastIdle=");
13031                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13032                        pw.println();
13033            }
13034        }
13035
13036        if (!printedAnything) {
13037            pw.println("  (nothing)");
13038        }
13039    }
13040
13041    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13042            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13043        if (mProcessesToGc.size() > 0) {
13044            boolean printed = false;
13045            long now = SystemClock.uptimeMillis();
13046            for (int i=0; i<mProcessesToGc.size(); i++) {
13047                ProcessRecord proc = mProcessesToGc.get(i);
13048                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13049                    continue;
13050                }
13051                if (!printed) {
13052                    if (needSep) pw.println();
13053                    needSep = true;
13054                    pw.println("  Processes that are waiting to GC:");
13055                    printed = true;
13056                }
13057                pw.print("    Process "); pw.println(proc);
13058                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13059                        pw.print(", last gced=");
13060                        pw.print(now-proc.lastRequestedGc);
13061                        pw.print(" ms ago, last lowMem=");
13062                        pw.print(now-proc.lastLowMemory);
13063                        pw.println(" ms ago");
13064
13065            }
13066        }
13067        return needSep;
13068    }
13069
13070    void printOomLevel(PrintWriter pw, String name, int adj) {
13071        pw.print("    ");
13072        if (adj >= 0) {
13073            pw.print(' ');
13074            if (adj < 10) pw.print(' ');
13075        } else {
13076            if (adj > -10) pw.print(' ');
13077        }
13078        pw.print(adj);
13079        pw.print(": ");
13080        pw.print(name);
13081        pw.print(" (");
13082        pw.print(mProcessList.getMemLevel(adj)/1024);
13083        pw.println(" kB)");
13084    }
13085
13086    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13087            int opti, boolean dumpAll) {
13088        boolean needSep = false;
13089
13090        if (mLruProcesses.size() > 0) {
13091            if (needSep) pw.println();
13092            needSep = true;
13093            pw.println("  OOM levels:");
13094            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13095            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13096            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13097            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13098            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13099            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13100            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13101            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13102            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13103            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13104            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13105            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13106            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13107            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13108
13109            if (needSep) pw.println();
13110            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13111                    pw.print(" total, non-act at ");
13112                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13113                    pw.print(", non-svc at ");
13114                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13115                    pw.println("):");
13116            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13117            needSep = true;
13118        }
13119
13120        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13121
13122        pw.println();
13123        pw.println("  mHomeProcess: " + mHomeProcess);
13124        pw.println("  mPreviousProcess: " + mPreviousProcess);
13125        if (mHeavyWeightProcess != null) {
13126            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13127        }
13128
13129        return true;
13130    }
13131
13132    /**
13133     * There are three ways to call this:
13134     *  - no provider specified: dump all the providers
13135     *  - a flattened component name that matched an existing provider was specified as the
13136     *    first arg: dump that one provider
13137     *  - the first arg isn't the flattened component name of an existing provider:
13138     *    dump all providers whose component contains the first arg as a substring
13139     */
13140    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13141            int opti, boolean dumpAll) {
13142        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13143    }
13144
13145    static class ItemMatcher {
13146        ArrayList<ComponentName> components;
13147        ArrayList<String> strings;
13148        ArrayList<Integer> objects;
13149        boolean all;
13150
13151        ItemMatcher() {
13152            all = true;
13153        }
13154
13155        void build(String name) {
13156            ComponentName componentName = ComponentName.unflattenFromString(name);
13157            if (componentName != null) {
13158                if (components == null) {
13159                    components = new ArrayList<ComponentName>();
13160                }
13161                components.add(componentName);
13162                all = false;
13163            } else {
13164                int objectId = 0;
13165                // Not a '/' separated full component name; maybe an object ID?
13166                try {
13167                    objectId = Integer.parseInt(name, 16);
13168                    if (objects == null) {
13169                        objects = new ArrayList<Integer>();
13170                    }
13171                    objects.add(objectId);
13172                    all = false;
13173                } catch (RuntimeException e) {
13174                    // Not an integer; just do string match.
13175                    if (strings == null) {
13176                        strings = new ArrayList<String>();
13177                    }
13178                    strings.add(name);
13179                    all = false;
13180                }
13181            }
13182        }
13183
13184        int build(String[] args, int opti) {
13185            for (; opti<args.length; opti++) {
13186                String name = args[opti];
13187                if ("--".equals(name)) {
13188                    return opti+1;
13189                }
13190                build(name);
13191            }
13192            return opti;
13193        }
13194
13195        boolean match(Object object, ComponentName comp) {
13196            if (all) {
13197                return true;
13198            }
13199            if (components != null) {
13200                for (int i=0; i<components.size(); i++) {
13201                    if (components.get(i).equals(comp)) {
13202                        return true;
13203                    }
13204                }
13205            }
13206            if (objects != null) {
13207                for (int i=0; i<objects.size(); i++) {
13208                    if (System.identityHashCode(object) == objects.get(i)) {
13209                        return true;
13210                    }
13211                }
13212            }
13213            if (strings != null) {
13214                String flat = comp.flattenToString();
13215                for (int i=0; i<strings.size(); i++) {
13216                    if (flat.contains(strings.get(i))) {
13217                        return true;
13218                    }
13219                }
13220            }
13221            return false;
13222        }
13223    }
13224
13225    /**
13226     * There are three things that cmd can be:
13227     *  - a flattened component name that matches an existing activity
13228     *  - the cmd arg isn't the flattened component name of an existing activity:
13229     *    dump all activity whose component contains the cmd as a substring
13230     *  - A hex number of the ActivityRecord object instance.
13231     */
13232    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13233            int opti, boolean dumpAll) {
13234        ArrayList<ActivityRecord> activities;
13235
13236        synchronized (this) {
13237            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13238        }
13239
13240        if (activities.size() <= 0) {
13241            return false;
13242        }
13243
13244        String[] newArgs = new String[args.length - opti];
13245        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13246
13247        TaskRecord lastTask = null;
13248        boolean needSep = false;
13249        for (int i=activities.size()-1; i>=0; i--) {
13250            ActivityRecord r = activities.get(i);
13251            if (needSep) {
13252                pw.println();
13253            }
13254            needSep = true;
13255            synchronized (this) {
13256                if (lastTask != r.task) {
13257                    lastTask = r.task;
13258                    pw.print("TASK "); pw.print(lastTask.affinity);
13259                            pw.print(" id="); pw.println(lastTask.taskId);
13260                    if (dumpAll) {
13261                        lastTask.dump(pw, "  ");
13262                    }
13263                }
13264            }
13265            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13266        }
13267        return true;
13268    }
13269
13270    /**
13271     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13272     * there is a thread associated with the activity.
13273     */
13274    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13275            final ActivityRecord r, String[] args, boolean dumpAll) {
13276        String innerPrefix = prefix + "  ";
13277        synchronized (this) {
13278            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13279                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13280                    pw.print(" pid=");
13281                    if (r.app != null) pw.println(r.app.pid);
13282                    else pw.println("(not running)");
13283            if (dumpAll) {
13284                r.dump(pw, innerPrefix);
13285            }
13286        }
13287        if (r.app != null && r.app.thread != null) {
13288            // flush anything that is already in the PrintWriter since the thread is going
13289            // to write to the file descriptor directly
13290            pw.flush();
13291            try {
13292                TransferPipe tp = new TransferPipe();
13293                try {
13294                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13295                            r.appToken, innerPrefix, args);
13296                    tp.go(fd);
13297                } finally {
13298                    tp.kill();
13299                }
13300            } catch (IOException e) {
13301                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13302            } catch (RemoteException e) {
13303                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13304            }
13305        }
13306    }
13307
13308    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13309            int opti, boolean dumpAll, String dumpPackage) {
13310        boolean needSep = false;
13311        boolean onlyHistory = false;
13312        boolean printedAnything = false;
13313
13314        if ("history".equals(dumpPackage)) {
13315            if (opti < args.length && "-s".equals(args[opti])) {
13316                dumpAll = false;
13317            }
13318            onlyHistory = true;
13319            dumpPackage = null;
13320        }
13321
13322        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13323        if (!onlyHistory && dumpAll) {
13324            if (mRegisteredReceivers.size() > 0) {
13325                boolean printed = false;
13326                Iterator it = mRegisteredReceivers.values().iterator();
13327                while (it.hasNext()) {
13328                    ReceiverList r = (ReceiverList)it.next();
13329                    if (dumpPackage != null && (r.app == null ||
13330                            !dumpPackage.equals(r.app.info.packageName))) {
13331                        continue;
13332                    }
13333                    if (!printed) {
13334                        pw.println("  Registered Receivers:");
13335                        needSep = true;
13336                        printed = true;
13337                        printedAnything = true;
13338                    }
13339                    pw.print("  * "); pw.println(r);
13340                    r.dump(pw, "    ");
13341                }
13342            }
13343
13344            if (mReceiverResolver.dump(pw, needSep ?
13345                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13346                    "    ", dumpPackage, false)) {
13347                needSep = true;
13348                printedAnything = true;
13349            }
13350        }
13351
13352        for (BroadcastQueue q : mBroadcastQueues) {
13353            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13354            printedAnything |= needSep;
13355        }
13356
13357        needSep = true;
13358
13359        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13360            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13361                if (needSep) {
13362                    pw.println();
13363                }
13364                needSep = true;
13365                printedAnything = true;
13366                pw.print("  Sticky broadcasts for user ");
13367                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13368                StringBuilder sb = new StringBuilder(128);
13369                for (Map.Entry<String, ArrayList<Intent>> ent
13370                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13371                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13372                    if (dumpAll) {
13373                        pw.println(":");
13374                        ArrayList<Intent> intents = ent.getValue();
13375                        final int N = intents.size();
13376                        for (int i=0; i<N; i++) {
13377                            sb.setLength(0);
13378                            sb.append("    Intent: ");
13379                            intents.get(i).toShortString(sb, false, true, false, false);
13380                            pw.println(sb.toString());
13381                            Bundle bundle = intents.get(i).getExtras();
13382                            if (bundle != null) {
13383                                pw.print("      ");
13384                                pw.println(bundle.toString());
13385                            }
13386                        }
13387                    } else {
13388                        pw.println("");
13389                    }
13390                }
13391            }
13392        }
13393
13394        if (!onlyHistory && dumpAll) {
13395            pw.println();
13396            for (BroadcastQueue queue : mBroadcastQueues) {
13397                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13398                        + queue.mBroadcastsScheduled);
13399            }
13400            pw.println("  mHandler:");
13401            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13402            needSep = true;
13403            printedAnything = true;
13404        }
13405
13406        if (!printedAnything) {
13407            pw.println("  (nothing)");
13408        }
13409    }
13410
13411    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13412            int opti, boolean dumpAll, String dumpPackage) {
13413        boolean needSep;
13414        boolean printedAnything = false;
13415
13416        ItemMatcher matcher = new ItemMatcher();
13417        matcher.build(args, opti);
13418
13419        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13420
13421        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13422        printedAnything |= needSep;
13423
13424        if (mLaunchingProviders.size() > 0) {
13425            boolean printed = false;
13426            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13427                ContentProviderRecord r = mLaunchingProviders.get(i);
13428                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13429                    continue;
13430                }
13431                if (!printed) {
13432                    if (needSep) pw.println();
13433                    needSep = true;
13434                    pw.println("  Launching content providers:");
13435                    printed = true;
13436                    printedAnything = true;
13437                }
13438                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13439                        pw.println(r);
13440            }
13441        }
13442
13443        if (mGrantedUriPermissions.size() > 0) {
13444            boolean printed = false;
13445            int dumpUid = -2;
13446            if (dumpPackage != null) {
13447                try {
13448                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13449                } catch (NameNotFoundException e) {
13450                    dumpUid = -1;
13451                }
13452            }
13453            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13454                int uid = mGrantedUriPermissions.keyAt(i);
13455                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13456                    continue;
13457                }
13458                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13459                if (!printed) {
13460                    if (needSep) pw.println();
13461                    needSep = true;
13462                    pw.println("  Granted Uri Permissions:");
13463                    printed = true;
13464                    printedAnything = true;
13465                }
13466                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13467                for (UriPermission perm : perms.values()) {
13468                    pw.print("    "); pw.println(perm);
13469                    if (dumpAll) {
13470                        perm.dump(pw, "      ");
13471                    }
13472                }
13473            }
13474        }
13475
13476        if (!printedAnything) {
13477            pw.println("  (nothing)");
13478        }
13479    }
13480
13481    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13482            int opti, boolean dumpAll, String dumpPackage) {
13483        boolean printed = false;
13484
13485        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13486
13487        if (mIntentSenderRecords.size() > 0) {
13488            Iterator<WeakReference<PendingIntentRecord>> it
13489                    = mIntentSenderRecords.values().iterator();
13490            while (it.hasNext()) {
13491                WeakReference<PendingIntentRecord> ref = it.next();
13492                PendingIntentRecord rec = ref != null ? ref.get(): null;
13493                if (dumpPackage != null && (rec == null
13494                        || !dumpPackage.equals(rec.key.packageName))) {
13495                    continue;
13496                }
13497                printed = true;
13498                if (rec != null) {
13499                    pw.print("  * "); pw.println(rec);
13500                    if (dumpAll) {
13501                        rec.dump(pw, "    ");
13502                    }
13503                } else {
13504                    pw.print("  * "); pw.println(ref);
13505                }
13506            }
13507        }
13508
13509        if (!printed) {
13510            pw.println("  (nothing)");
13511        }
13512    }
13513
13514    private static final int dumpProcessList(PrintWriter pw,
13515            ActivityManagerService service, List list,
13516            String prefix, String normalLabel, String persistentLabel,
13517            String dumpPackage) {
13518        int numPers = 0;
13519        final int N = list.size()-1;
13520        for (int i=N; i>=0; i--) {
13521            ProcessRecord r = (ProcessRecord)list.get(i);
13522            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13523                continue;
13524            }
13525            pw.println(String.format("%s%s #%2d: %s",
13526                    prefix, (r.persistent ? persistentLabel : normalLabel),
13527                    i, r.toString()));
13528            if (r.persistent) {
13529                numPers++;
13530            }
13531        }
13532        return numPers;
13533    }
13534
13535    private static final boolean dumpProcessOomList(PrintWriter pw,
13536            ActivityManagerService service, List<ProcessRecord> origList,
13537            String prefix, String normalLabel, String persistentLabel,
13538            boolean inclDetails, String dumpPackage) {
13539
13540        ArrayList<Pair<ProcessRecord, Integer>> list
13541                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13542        for (int i=0; i<origList.size(); i++) {
13543            ProcessRecord r = origList.get(i);
13544            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13545                continue;
13546            }
13547            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13548        }
13549
13550        if (list.size() <= 0) {
13551            return false;
13552        }
13553
13554        Comparator<Pair<ProcessRecord, Integer>> comparator
13555                = new Comparator<Pair<ProcessRecord, Integer>>() {
13556            @Override
13557            public int compare(Pair<ProcessRecord, Integer> object1,
13558                    Pair<ProcessRecord, Integer> object2) {
13559                if (object1.first.setAdj != object2.first.setAdj) {
13560                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13561                }
13562                if (object1.second.intValue() != object2.second.intValue()) {
13563                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13564                }
13565                return 0;
13566            }
13567        };
13568
13569        Collections.sort(list, comparator);
13570
13571        final long curRealtime = SystemClock.elapsedRealtime();
13572        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13573        final long curUptime = SystemClock.uptimeMillis();
13574        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13575
13576        for (int i=list.size()-1; i>=0; i--) {
13577            ProcessRecord r = list.get(i).first;
13578            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13579            char schedGroup;
13580            switch (r.setSchedGroup) {
13581                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13582                    schedGroup = 'B';
13583                    break;
13584                case Process.THREAD_GROUP_DEFAULT:
13585                    schedGroup = 'F';
13586                    break;
13587                default:
13588                    schedGroup = '?';
13589                    break;
13590            }
13591            char foreground;
13592            if (r.foregroundActivities) {
13593                foreground = 'A';
13594            } else if (r.foregroundServices) {
13595                foreground = 'S';
13596            } else {
13597                foreground = ' ';
13598            }
13599            String procState = ProcessList.makeProcStateString(r.curProcState);
13600            pw.print(prefix);
13601            pw.print(r.persistent ? persistentLabel : normalLabel);
13602            pw.print(" #");
13603            int num = (origList.size()-1)-list.get(i).second;
13604            if (num < 10) pw.print(' ');
13605            pw.print(num);
13606            pw.print(": ");
13607            pw.print(oomAdj);
13608            pw.print(' ');
13609            pw.print(schedGroup);
13610            pw.print('/');
13611            pw.print(foreground);
13612            pw.print('/');
13613            pw.print(procState);
13614            pw.print(" trm:");
13615            if (r.trimMemoryLevel < 10) pw.print(' ');
13616            pw.print(r.trimMemoryLevel);
13617            pw.print(' ');
13618            pw.print(r.toShortString());
13619            pw.print(" (");
13620            pw.print(r.adjType);
13621            pw.println(')');
13622            if (r.adjSource != null || r.adjTarget != null) {
13623                pw.print(prefix);
13624                pw.print("    ");
13625                if (r.adjTarget instanceof ComponentName) {
13626                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13627                } else if (r.adjTarget != null) {
13628                    pw.print(r.adjTarget.toString());
13629                } else {
13630                    pw.print("{null}");
13631                }
13632                pw.print("<=");
13633                if (r.adjSource instanceof ProcessRecord) {
13634                    pw.print("Proc{");
13635                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13636                    pw.println("}");
13637                } else if (r.adjSource != null) {
13638                    pw.println(r.adjSource.toString());
13639                } else {
13640                    pw.println("{null}");
13641                }
13642            }
13643            if (inclDetails) {
13644                pw.print(prefix);
13645                pw.print("    ");
13646                pw.print("oom: max="); pw.print(r.maxAdj);
13647                pw.print(" curRaw="); pw.print(r.curRawAdj);
13648                pw.print(" setRaw="); pw.print(r.setRawAdj);
13649                pw.print(" cur="); pw.print(r.curAdj);
13650                pw.print(" set="); pw.println(r.setAdj);
13651                pw.print(prefix);
13652                pw.print("    ");
13653                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13654                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13655                pw.print(" lastPss="); pw.print(r.lastPss);
13656                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13657                pw.print(prefix);
13658                pw.print("    ");
13659                pw.print("cached="); pw.print(r.cached);
13660                pw.print(" empty="); pw.print(r.empty);
13661                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13662
13663                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13664                    if (r.lastWakeTime != 0) {
13665                        long wtime;
13666                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13667                        synchronized (stats) {
13668                            wtime = stats.getProcessWakeTime(r.info.uid,
13669                                    r.pid, curRealtime);
13670                        }
13671                        long timeUsed = wtime - r.lastWakeTime;
13672                        pw.print(prefix);
13673                        pw.print("    ");
13674                        pw.print("keep awake over ");
13675                        TimeUtils.formatDuration(realtimeSince, pw);
13676                        pw.print(" used ");
13677                        TimeUtils.formatDuration(timeUsed, pw);
13678                        pw.print(" (");
13679                        pw.print((timeUsed*100)/realtimeSince);
13680                        pw.println("%)");
13681                    }
13682                    if (r.lastCpuTime != 0) {
13683                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13684                        pw.print(prefix);
13685                        pw.print("    ");
13686                        pw.print("run cpu over ");
13687                        TimeUtils.formatDuration(uptimeSince, pw);
13688                        pw.print(" used ");
13689                        TimeUtils.formatDuration(timeUsed, pw);
13690                        pw.print(" (");
13691                        pw.print((timeUsed*100)/uptimeSince);
13692                        pw.println("%)");
13693                    }
13694                }
13695            }
13696        }
13697        return true;
13698    }
13699
13700    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13701            String[] args) {
13702        ArrayList<ProcessRecord> procs;
13703        synchronized (this) {
13704            if (args != null && args.length > start
13705                    && args[start].charAt(0) != '-') {
13706                procs = new ArrayList<ProcessRecord>();
13707                int pid = -1;
13708                try {
13709                    pid = Integer.parseInt(args[start]);
13710                } catch (NumberFormatException e) {
13711                }
13712                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13713                    ProcessRecord proc = mLruProcesses.get(i);
13714                    if (proc.pid == pid) {
13715                        procs.add(proc);
13716                    } else if (allPkgs && proc.pkgList != null
13717                            && proc.pkgList.containsKey(args[start])) {
13718                        procs.add(proc);
13719                    } else if (proc.processName.equals(args[start])) {
13720                        procs.add(proc);
13721                    }
13722                }
13723                if (procs.size() <= 0) {
13724                    return null;
13725                }
13726            } else {
13727                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13728            }
13729        }
13730        return procs;
13731    }
13732
13733    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13734            PrintWriter pw, String[] args) {
13735        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13736        if (procs == null) {
13737            pw.println("No process found for: " + args[0]);
13738            return;
13739        }
13740
13741        long uptime = SystemClock.uptimeMillis();
13742        long realtime = SystemClock.elapsedRealtime();
13743        pw.println("Applications Graphics Acceleration Info:");
13744        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13745
13746        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13747            ProcessRecord r = procs.get(i);
13748            if (r.thread != null) {
13749                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13750                pw.flush();
13751                try {
13752                    TransferPipe tp = new TransferPipe();
13753                    try {
13754                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13755                        tp.go(fd);
13756                    } finally {
13757                        tp.kill();
13758                    }
13759                } catch (IOException e) {
13760                    pw.println("Failure while dumping the app: " + r);
13761                    pw.flush();
13762                } catch (RemoteException e) {
13763                    pw.println("Got a RemoteException while dumping the app " + r);
13764                    pw.flush();
13765                }
13766            }
13767        }
13768    }
13769
13770    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13771        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13772        if (procs == null) {
13773            pw.println("No process found for: " + args[0]);
13774            return;
13775        }
13776
13777        pw.println("Applications Database Info:");
13778
13779        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13780            ProcessRecord r = procs.get(i);
13781            if (r.thread != null) {
13782                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13783                pw.flush();
13784                try {
13785                    TransferPipe tp = new TransferPipe();
13786                    try {
13787                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13788                        tp.go(fd);
13789                    } finally {
13790                        tp.kill();
13791                    }
13792                } catch (IOException e) {
13793                    pw.println("Failure while dumping the app: " + r);
13794                    pw.flush();
13795                } catch (RemoteException e) {
13796                    pw.println("Got a RemoteException while dumping the app " + r);
13797                    pw.flush();
13798                }
13799            }
13800        }
13801    }
13802
13803    final static class MemItem {
13804        final boolean isProc;
13805        final String label;
13806        final String shortLabel;
13807        final long pss;
13808        final int id;
13809        final boolean hasActivities;
13810        ArrayList<MemItem> subitems;
13811
13812        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13813                boolean _hasActivities) {
13814            isProc = true;
13815            label = _label;
13816            shortLabel = _shortLabel;
13817            pss = _pss;
13818            id = _id;
13819            hasActivities = _hasActivities;
13820        }
13821
13822        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13823            isProc = false;
13824            label = _label;
13825            shortLabel = _shortLabel;
13826            pss = _pss;
13827            id = _id;
13828            hasActivities = false;
13829        }
13830    }
13831
13832    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13833            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13834        if (sort && !isCompact) {
13835            Collections.sort(items, new Comparator<MemItem>() {
13836                @Override
13837                public int compare(MemItem lhs, MemItem rhs) {
13838                    if (lhs.pss < rhs.pss) {
13839                        return 1;
13840                    } else if (lhs.pss > rhs.pss) {
13841                        return -1;
13842                    }
13843                    return 0;
13844                }
13845            });
13846        }
13847
13848        for (int i=0; i<items.size(); i++) {
13849            MemItem mi = items.get(i);
13850            if (!isCompact) {
13851                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13852            } else if (mi.isProc) {
13853                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13854                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13855                pw.println(mi.hasActivities ? ",a" : ",e");
13856            } else {
13857                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13858                pw.println(mi.pss);
13859            }
13860            if (mi.subitems != null) {
13861                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13862                        true, isCompact);
13863            }
13864        }
13865    }
13866
13867    // These are in KB.
13868    static final long[] DUMP_MEM_BUCKETS = new long[] {
13869        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13870        120*1024, 160*1024, 200*1024,
13871        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13872        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13873    };
13874
13875    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13876            boolean stackLike) {
13877        int start = label.lastIndexOf('.');
13878        if (start >= 0) start++;
13879        else start = 0;
13880        int end = label.length();
13881        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13882            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13883                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13884                out.append(bucket);
13885                out.append(stackLike ? "MB." : "MB ");
13886                out.append(label, start, end);
13887                return;
13888            }
13889        }
13890        out.append(memKB/1024);
13891        out.append(stackLike ? "MB." : "MB ");
13892        out.append(label, start, end);
13893    }
13894
13895    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13896            ProcessList.NATIVE_ADJ,
13897            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13898            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13899            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13900            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13901            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13902            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13903    };
13904    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13905            "Native",
13906            "System", "Persistent", "Persistent Service", "Foreground",
13907            "Visible", "Perceptible",
13908            "Heavy Weight", "Backup",
13909            "A Services", "Home",
13910            "Previous", "B Services", "Cached"
13911    };
13912    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13913            "native",
13914            "sys", "pers", "persvc", "fore",
13915            "vis", "percept",
13916            "heavy", "backup",
13917            "servicea", "home",
13918            "prev", "serviceb", "cached"
13919    };
13920
13921    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13922            long realtime, boolean isCheckinRequest, boolean isCompact) {
13923        if (isCheckinRequest || isCompact) {
13924            // short checkin version
13925            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13926        } else {
13927            pw.println("Applications Memory Usage (kB):");
13928            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13929        }
13930    }
13931
13932    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13933            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13934        boolean dumpDetails = false;
13935        boolean dumpFullDetails = false;
13936        boolean dumpDalvik = false;
13937        boolean oomOnly = false;
13938        boolean isCompact = false;
13939        boolean localOnly = false;
13940        boolean packages = false;
13941
13942        int opti = 0;
13943        while (opti < args.length) {
13944            String opt = args[opti];
13945            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13946                break;
13947            }
13948            opti++;
13949            if ("-a".equals(opt)) {
13950                dumpDetails = true;
13951                dumpFullDetails = true;
13952                dumpDalvik = true;
13953            } else if ("-d".equals(opt)) {
13954                dumpDalvik = true;
13955            } else if ("-c".equals(opt)) {
13956                isCompact = true;
13957            } else if ("--oom".equals(opt)) {
13958                oomOnly = true;
13959            } else if ("--local".equals(opt)) {
13960                localOnly = true;
13961            } else if ("--package".equals(opt)) {
13962                packages = true;
13963            } else if ("-h".equals(opt)) {
13964                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13965                pw.println("  -a: include all available information for each process.");
13966                pw.println("  -d: include dalvik details when dumping process details.");
13967                pw.println("  -c: dump in a compact machine-parseable representation.");
13968                pw.println("  --oom: only show processes organized by oom adj.");
13969                pw.println("  --local: only collect details locally, don't call process.");
13970                pw.println("  --package: interpret process arg as package, dumping all");
13971                pw.println("             processes that have loaded that package.");
13972                pw.println("If [process] is specified it can be the name or ");
13973                pw.println("pid of a specific process to dump.");
13974                return;
13975            } else {
13976                pw.println("Unknown argument: " + opt + "; use -h for help");
13977            }
13978        }
13979
13980        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13981        long uptime = SystemClock.uptimeMillis();
13982        long realtime = SystemClock.elapsedRealtime();
13983        final long[] tmpLong = new long[1];
13984
13985        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13986        if (procs == null) {
13987            // No Java processes.  Maybe they want to print a native process.
13988            if (args != null && args.length > opti
13989                    && args[opti].charAt(0) != '-') {
13990                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13991                        = new ArrayList<ProcessCpuTracker.Stats>();
13992                updateCpuStatsNow();
13993                int findPid = -1;
13994                try {
13995                    findPid = Integer.parseInt(args[opti]);
13996                } catch (NumberFormatException e) {
13997                }
13998                synchronized (mProcessCpuTracker) {
13999                    final int N = mProcessCpuTracker.countStats();
14000                    for (int i=0; i<N; i++) {
14001                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14002                        if (st.pid == findPid || (st.baseName != null
14003                                && st.baseName.equals(args[opti]))) {
14004                            nativeProcs.add(st);
14005                        }
14006                    }
14007                }
14008                if (nativeProcs.size() > 0) {
14009                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14010                            isCompact);
14011                    Debug.MemoryInfo mi = null;
14012                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14013                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14014                        final int pid = r.pid;
14015                        if (!isCheckinRequest && dumpDetails) {
14016                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14017                        }
14018                        if (mi == null) {
14019                            mi = new Debug.MemoryInfo();
14020                        }
14021                        if (dumpDetails || (!brief && !oomOnly)) {
14022                            Debug.getMemoryInfo(pid, mi);
14023                        } else {
14024                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14025                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14026                        }
14027                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14028                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14029                        if (isCheckinRequest) {
14030                            pw.println();
14031                        }
14032                    }
14033                    return;
14034                }
14035            }
14036            pw.println("No process found for: " + args[opti]);
14037            return;
14038        }
14039
14040        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14041            dumpDetails = true;
14042        }
14043
14044        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14045
14046        String[] innerArgs = new String[args.length-opti];
14047        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14048
14049        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14050        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14051        long nativePss=0, dalvikPss=0, otherPss=0;
14052        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14053
14054        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14055        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14056                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14057
14058        long totalPss = 0;
14059        long cachedPss = 0;
14060
14061        Debug.MemoryInfo mi = null;
14062        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14063            final ProcessRecord r = procs.get(i);
14064            final IApplicationThread thread;
14065            final int pid;
14066            final int oomAdj;
14067            final boolean hasActivities;
14068            synchronized (this) {
14069                thread = r.thread;
14070                pid = r.pid;
14071                oomAdj = r.getSetAdjWithServices();
14072                hasActivities = r.activities.size() > 0;
14073            }
14074            if (thread != null) {
14075                if (!isCheckinRequest && dumpDetails) {
14076                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14077                }
14078                if (mi == null) {
14079                    mi = new Debug.MemoryInfo();
14080                }
14081                if (dumpDetails || (!brief && !oomOnly)) {
14082                    Debug.getMemoryInfo(pid, mi);
14083                } else {
14084                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14085                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14086                }
14087                if (dumpDetails) {
14088                    if (localOnly) {
14089                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14090                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14091                        if (isCheckinRequest) {
14092                            pw.println();
14093                        }
14094                    } else {
14095                        try {
14096                            pw.flush();
14097                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14098                                    dumpDalvik, innerArgs);
14099                        } catch (RemoteException e) {
14100                            if (!isCheckinRequest) {
14101                                pw.println("Got RemoteException!");
14102                                pw.flush();
14103                            }
14104                        }
14105                    }
14106                }
14107
14108                final long myTotalPss = mi.getTotalPss();
14109                final long myTotalUss = mi.getTotalUss();
14110
14111                synchronized (this) {
14112                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14113                        // Record this for posterity if the process has been stable.
14114                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14115                    }
14116                }
14117
14118                if (!isCheckinRequest && mi != null) {
14119                    totalPss += myTotalPss;
14120                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14121                            (hasActivities ? " / activities)" : ")"),
14122                            r.processName, myTotalPss, pid, hasActivities);
14123                    procMems.add(pssItem);
14124                    procMemsMap.put(pid, pssItem);
14125
14126                    nativePss += mi.nativePss;
14127                    dalvikPss += mi.dalvikPss;
14128                    otherPss += mi.otherPss;
14129                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14130                        long mem = mi.getOtherPss(j);
14131                        miscPss[j] += mem;
14132                        otherPss -= mem;
14133                    }
14134
14135                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14136                        cachedPss += myTotalPss;
14137                    }
14138
14139                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14140                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14141                                || oomIndex == (oomPss.length-1)) {
14142                            oomPss[oomIndex] += myTotalPss;
14143                            if (oomProcs[oomIndex] == null) {
14144                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14145                            }
14146                            oomProcs[oomIndex].add(pssItem);
14147                            break;
14148                        }
14149                    }
14150                }
14151            }
14152        }
14153
14154        long nativeProcTotalPss = 0;
14155
14156        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14157            // If we are showing aggregations, also look for native processes to
14158            // include so that our aggregations are more accurate.
14159            updateCpuStatsNow();
14160            synchronized (mProcessCpuTracker) {
14161                final int N = mProcessCpuTracker.countStats();
14162                for (int i=0; i<N; i++) {
14163                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14164                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14165                        if (mi == null) {
14166                            mi = new Debug.MemoryInfo();
14167                        }
14168                        if (!brief && !oomOnly) {
14169                            Debug.getMemoryInfo(st.pid, mi);
14170                        } else {
14171                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14172                            mi.nativePrivateDirty = (int)tmpLong[0];
14173                        }
14174
14175                        final long myTotalPss = mi.getTotalPss();
14176                        totalPss += myTotalPss;
14177                        nativeProcTotalPss += myTotalPss;
14178
14179                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14180                                st.name, myTotalPss, st.pid, false);
14181                        procMems.add(pssItem);
14182
14183                        nativePss += mi.nativePss;
14184                        dalvikPss += mi.dalvikPss;
14185                        otherPss += mi.otherPss;
14186                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14187                            long mem = mi.getOtherPss(j);
14188                            miscPss[j] += mem;
14189                            otherPss -= mem;
14190                        }
14191                        oomPss[0] += myTotalPss;
14192                        if (oomProcs[0] == null) {
14193                            oomProcs[0] = new ArrayList<MemItem>();
14194                        }
14195                        oomProcs[0].add(pssItem);
14196                    }
14197                }
14198            }
14199
14200            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14201
14202            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14203            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14204            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14205            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14206                String label = Debug.MemoryInfo.getOtherLabel(j);
14207                catMems.add(new MemItem(label, label, miscPss[j], j));
14208            }
14209
14210            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14211            for (int j=0; j<oomPss.length; j++) {
14212                if (oomPss[j] != 0) {
14213                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14214                            : DUMP_MEM_OOM_LABEL[j];
14215                    MemItem item = new MemItem(label, label, oomPss[j],
14216                            DUMP_MEM_OOM_ADJ[j]);
14217                    item.subitems = oomProcs[j];
14218                    oomMems.add(item);
14219                }
14220            }
14221
14222            if (!brief && !oomOnly && !isCompact) {
14223                pw.println();
14224                pw.println("Total PSS by process:");
14225                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14226                pw.println();
14227            }
14228            if (!isCompact) {
14229                pw.println("Total PSS by OOM adjustment:");
14230            }
14231            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14232            if (!brief && !oomOnly) {
14233                PrintWriter out = categoryPw != null ? categoryPw : pw;
14234                if (!isCompact) {
14235                    out.println();
14236                    out.println("Total PSS by category:");
14237                }
14238                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14239            }
14240            if (!isCompact) {
14241                pw.println();
14242            }
14243            MemInfoReader memInfo = new MemInfoReader();
14244            memInfo.readMemInfo();
14245            if (nativeProcTotalPss > 0) {
14246                synchronized (this) {
14247                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14248                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14249                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14250                            nativeProcTotalPss);
14251                }
14252            }
14253            if (!brief) {
14254                if (!isCompact) {
14255                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14256                    pw.print(" kB (status ");
14257                    switch (mLastMemoryLevel) {
14258                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14259                            pw.println("normal)");
14260                            break;
14261                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14262                            pw.println("moderate)");
14263                            break;
14264                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14265                            pw.println("low)");
14266                            break;
14267                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14268                            pw.println("critical)");
14269                            break;
14270                        default:
14271                            pw.print(mLastMemoryLevel);
14272                            pw.println(")");
14273                            break;
14274                    }
14275                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14276                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14277                            pw.print(cachedPss); pw.print(" cached pss + ");
14278                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14279                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14280                } else {
14281                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14282                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14283                            + memInfo.getFreeSizeKb()); pw.print(",");
14284                    pw.println(totalPss - cachedPss);
14285                }
14286            }
14287            if (!isCompact) {
14288                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14289                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14290                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14291                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14292                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14293                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14294                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14295                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14296                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14297                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14298                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14299            }
14300            if (!brief) {
14301                if (memInfo.getZramTotalSizeKb() != 0) {
14302                    if (!isCompact) {
14303                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14304                                pw.print(" kB physical used for ");
14305                                pw.print(memInfo.getSwapTotalSizeKb()
14306                                        - memInfo.getSwapFreeSizeKb());
14307                                pw.print(" kB in swap (");
14308                                pw.print(memInfo.getSwapTotalSizeKb());
14309                                pw.println(" kB total swap)");
14310                    } else {
14311                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14312                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14313                                pw.println(memInfo.getSwapFreeSizeKb());
14314                    }
14315                }
14316                final int[] SINGLE_LONG_FORMAT = new int[] {
14317                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14318                };
14319                long[] longOut = new long[1];
14320                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14321                        SINGLE_LONG_FORMAT, null, longOut, null);
14322                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14323                longOut[0] = 0;
14324                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14325                        SINGLE_LONG_FORMAT, null, longOut, null);
14326                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14327                longOut[0] = 0;
14328                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14329                        SINGLE_LONG_FORMAT, null, longOut, null);
14330                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14331                longOut[0] = 0;
14332                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14333                        SINGLE_LONG_FORMAT, null, longOut, null);
14334                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14335                if (!isCompact) {
14336                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14337                        pw.print("      KSM: "); pw.print(sharing);
14338                                pw.print(" kB saved from shared ");
14339                                pw.print(shared); pw.println(" kB");
14340                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14341                                pw.print(voltile); pw.println(" kB volatile");
14342                    }
14343                    pw.print("   Tuning: ");
14344                    pw.print(ActivityManager.staticGetMemoryClass());
14345                    pw.print(" (large ");
14346                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14347                    pw.print("), oom ");
14348                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14349                    pw.print(" kB");
14350                    pw.print(", restore limit ");
14351                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14352                    pw.print(" kB");
14353                    if (ActivityManager.isLowRamDeviceStatic()) {
14354                        pw.print(" (low-ram)");
14355                    }
14356                    if (ActivityManager.isHighEndGfx()) {
14357                        pw.print(" (high-end-gfx)");
14358                    }
14359                    pw.println();
14360                } else {
14361                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14362                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14363                    pw.println(voltile);
14364                    pw.print("tuning,");
14365                    pw.print(ActivityManager.staticGetMemoryClass());
14366                    pw.print(',');
14367                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14368                    pw.print(',');
14369                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14370                    if (ActivityManager.isLowRamDeviceStatic()) {
14371                        pw.print(",low-ram");
14372                    }
14373                    if (ActivityManager.isHighEndGfx()) {
14374                        pw.print(",high-end-gfx");
14375                    }
14376                    pw.println();
14377                }
14378            }
14379        }
14380    }
14381
14382    /**
14383     * Searches array of arguments for the specified string
14384     * @param args array of argument strings
14385     * @param value value to search for
14386     * @return true if the value is contained in the array
14387     */
14388    private static boolean scanArgs(String[] args, String value) {
14389        if (args != null) {
14390            for (String arg : args) {
14391                if (value.equals(arg)) {
14392                    return true;
14393                }
14394            }
14395        }
14396        return false;
14397    }
14398
14399    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14400            ContentProviderRecord cpr, boolean always) {
14401        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14402
14403        if (!inLaunching || always) {
14404            synchronized (cpr) {
14405                cpr.launchingApp = null;
14406                cpr.notifyAll();
14407            }
14408            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14409            String names[] = cpr.info.authority.split(";");
14410            for (int j = 0; j < names.length; j++) {
14411                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14412            }
14413        }
14414
14415        for (int i=0; i<cpr.connections.size(); i++) {
14416            ContentProviderConnection conn = cpr.connections.get(i);
14417            if (conn.waiting) {
14418                // If this connection is waiting for the provider, then we don't
14419                // need to mess with its process unless we are always removing
14420                // or for some reason the provider is not currently launching.
14421                if (inLaunching && !always) {
14422                    continue;
14423                }
14424            }
14425            ProcessRecord capp = conn.client;
14426            conn.dead = true;
14427            if (conn.stableCount > 0) {
14428                if (!capp.persistent && capp.thread != null
14429                        && capp.pid != 0
14430                        && capp.pid != MY_PID) {
14431                    capp.kill("depends on provider "
14432                            + cpr.name.flattenToShortString()
14433                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14434                }
14435            } else if (capp.thread != null && conn.provider.provider != null) {
14436                try {
14437                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14438                } catch (RemoteException e) {
14439                }
14440                // In the protocol here, we don't expect the client to correctly
14441                // clean up this connection, we'll just remove it.
14442                cpr.connections.remove(i);
14443                conn.client.conProviders.remove(conn);
14444            }
14445        }
14446
14447        if (inLaunching && always) {
14448            mLaunchingProviders.remove(cpr);
14449        }
14450        return inLaunching;
14451    }
14452
14453    /**
14454     * Main code for cleaning up a process when it has gone away.  This is
14455     * called both as a result of the process dying, or directly when stopping
14456     * a process when running in single process mode.
14457     *
14458     * @return Returns true if the given process has been restarted, so the
14459     * app that was passed in must remain on the process lists.
14460     */
14461    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14462            boolean restarting, boolean allowRestart, int index) {
14463        if (index >= 0) {
14464            removeLruProcessLocked(app);
14465            ProcessList.remove(app.pid);
14466        }
14467
14468        mProcessesToGc.remove(app);
14469        mPendingPssProcesses.remove(app);
14470
14471        // Dismiss any open dialogs.
14472        if (app.crashDialog != null && !app.forceCrashReport) {
14473            app.crashDialog.dismiss();
14474            app.crashDialog = null;
14475        }
14476        if (app.anrDialog != null) {
14477            app.anrDialog.dismiss();
14478            app.anrDialog = null;
14479        }
14480        if (app.waitDialog != null) {
14481            app.waitDialog.dismiss();
14482            app.waitDialog = null;
14483        }
14484
14485        app.crashing = false;
14486        app.notResponding = false;
14487
14488        app.resetPackageList(mProcessStats);
14489        app.unlinkDeathRecipient();
14490        app.makeInactive(mProcessStats);
14491        app.waitingToKill = null;
14492        app.forcingToForeground = null;
14493        updateProcessForegroundLocked(app, false, false);
14494        app.foregroundActivities = false;
14495        app.hasShownUi = false;
14496        app.treatLikeActivity = false;
14497        app.hasAboveClient = false;
14498        app.hasClientActivities = false;
14499
14500        mServices.killServicesLocked(app, allowRestart);
14501
14502        boolean restart = false;
14503
14504        // Remove published content providers.
14505        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14506            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14507            final boolean always = app.bad || !allowRestart;
14508            if (removeDyingProviderLocked(app, cpr, always) || always) {
14509                // We left the provider in the launching list, need to
14510                // restart it.
14511                restart = true;
14512            }
14513
14514            cpr.provider = null;
14515            cpr.proc = null;
14516        }
14517        app.pubProviders.clear();
14518
14519        // Take care of any launching providers waiting for this process.
14520        if (checkAppInLaunchingProvidersLocked(app, false)) {
14521            restart = true;
14522        }
14523
14524        // Unregister from connected content providers.
14525        if (!app.conProviders.isEmpty()) {
14526            for (int i=0; i<app.conProviders.size(); i++) {
14527                ContentProviderConnection conn = app.conProviders.get(i);
14528                conn.provider.connections.remove(conn);
14529            }
14530            app.conProviders.clear();
14531        }
14532
14533        // At this point there may be remaining entries in mLaunchingProviders
14534        // where we were the only one waiting, so they are no longer of use.
14535        // Look for these and clean up if found.
14536        // XXX Commented out for now.  Trying to figure out a way to reproduce
14537        // the actual situation to identify what is actually going on.
14538        if (false) {
14539            for (int i=0; i<mLaunchingProviders.size(); i++) {
14540                ContentProviderRecord cpr = (ContentProviderRecord)
14541                        mLaunchingProviders.get(i);
14542                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14543                    synchronized (cpr) {
14544                        cpr.launchingApp = null;
14545                        cpr.notifyAll();
14546                    }
14547                }
14548            }
14549        }
14550
14551        skipCurrentReceiverLocked(app);
14552
14553        // Unregister any receivers.
14554        for (int i=app.receivers.size()-1; i>=0; i--) {
14555            removeReceiverLocked(app.receivers.valueAt(i));
14556        }
14557        app.receivers.clear();
14558
14559        // If the app is undergoing backup, tell the backup manager about it
14560        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14561            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14562                    + mBackupTarget.appInfo + " died during backup");
14563            try {
14564                IBackupManager bm = IBackupManager.Stub.asInterface(
14565                        ServiceManager.getService(Context.BACKUP_SERVICE));
14566                bm.agentDisconnected(app.info.packageName);
14567            } catch (RemoteException e) {
14568                // can't happen; backup manager is local
14569            }
14570        }
14571
14572        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14573            ProcessChangeItem item = mPendingProcessChanges.get(i);
14574            if (item.pid == app.pid) {
14575                mPendingProcessChanges.remove(i);
14576                mAvailProcessChanges.add(item);
14577            }
14578        }
14579        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14580
14581        // If the caller is restarting this app, then leave it in its
14582        // current lists and let the caller take care of it.
14583        if (restarting) {
14584            return false;
14585        }
14586
14587        if (!app.persistent || app.isolated) {
14588            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14589                    "Removing non-persistent process during cleanup: " + app);
14590            mProcessNames.remove(app.processName, app.uid);
14591            mIsolatedProcesses.remove(app.uid);
14592            if (mHeavyWeightProcess == app) {
14593                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14594                        mHeavyWeightProcess.userId, 0));
14595                mHeavyWeightProcess = null;
14596            }
14597        } else if (!app.removed) {
14598            // This app is persistent, so we need to keep its record around.
14599            // If it is not already on the pending app list, add it there
14600            // and start a new process for it.
14601            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14602                mPersistentStartingProcesses.add(app);
14603                restart = true;
14604            }
14605        }
14606        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14607                "Clean-up removing on hold: " + app);
14608        mProcessesOnHold.remove(app);
14609
14610        if (app == mHomeProcess) {
14611            mHomeProcess = null;
14612        }
14613        if (app == mPreviousProcess) {
14614            mPreviousProcess = null;
14615        }
14616
14617        if (restart && !app.isolated) {
14618            // We have components that still need to be running in the
14619            // process, so re-launch it.
14620            if (index < 0) {
14621                ProcessList.remove(app.pid);
14622            }
14623            mProcessNames.put(app.processName, app.uid, app);
14624            startProcessLocked(app, "restart", app.processName);
14625            return true;
14626        } else if (app.pid > 0 && app.pid != MY_PID) {
14627            // Goodbye!
14628            boolean removed;
14629            synchronized (mPidsSelfLocked) {
14630                mPidsSelfLocked.remove(app.pid);
14631                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14632            }
14633            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14634            if (app.isolated) {
14635                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14636            }
14637            app.setPid(0);
14638        }
14639        return false;
14640    }
14641
14642    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14643        // Look through the content providers we are waiting to have launched,
14644        // and if any run in this process then either schedule a restart of
14645        // the process or kill the client waiting for it if this process has
14646        // gone bad.
14647        int NL = mLaunchingProviders.size();
14648        boolean restart = false;
14649        for (int i=0; i<NL; i++) {
14650            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14651            if (cpr.launchingApp == app) {
14652                if (!alwaysBad && !app.bad) {
14653                    restart = true;
14654                } else {
14655                    removeDyingProviderLocked(app, cpr, true);
14656                    // cpr should have been removed from mLaunchingProviders
14657                    NL = mLaunchingProviders.size();
14658                    i--;
14659                }
14660            }
14661        }
14662        return restart;
14663    }
14664
14665    // =========================================================
14666    // SERVICES
14667    // =========================================================
14668
14669    @Override
14670    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14671            int flags) {
14672        enforceNotIsolatedCaller("getServices");
14673        synchronized (this) {
14674            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14675        }
14676    }
14677
14678    @Override
14679    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14680        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14681        synchronized (this) {
14682            return mServices.getRunningServiceControlPanelLocked(name);
14683        }
14684    }
14685
14686    @Override
14687    public ComponentName startService(IApplicationThread caller, Intent service,
14688            String resolvedType, int userId) {
14689        enforceNotIsolatedCaller("startService");
14690        // Refuse possible leaked file descriptors
14691        if (service != null && service.hasFileDescriptors() == true) {
14692            throw new IllegalArgumentException("File descriptors passed in Intent");
14693        }
14694
14695        if (DEBUG_SERVICE)
14696            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14697        synchronized(this) {
14698            final int callingPid = Binder.getCallingPid();
14699            final int callingUid = Binder.getCallingUid();
14700            final long origId = Binder.clearCallingIdentity();
14701            ComponentName res = mServices.startServiceLocked(caller, service,
14702                    resolvedType, callingPid, callingUid, userId);
14703            Binder.restoreCallingIdentity(origId);
14704            return res;
14705        }
14706    }
14707
14708    ComponentName startServiceInPackage(int uid,
14709            Intent service, String resolvedType, int userId) {
14710        synchronized(this) {
14711            if (DEBUG_SERVICE)
14712                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14713            final long origId = Binder.clearCallingIdentity();
14714            ComponentName res = mServices.startServiceLocked(null, service,
14715                    resolvedType, -1, uid, userId);
14716            Binder.restoreCallingIdentity(origId);
14717            return res;
14718        }
14719    }
14720
14721    @Override
14722    public int stopService(IApplicationThread caller, Intent service,
14723            String resolvedType, int userId) {
14724        enforceNotIsolatedCaller("stopService");
14725        // Refuse possible leaked file descriptors
14726        if (service != null && service.hasFileDescriptors() == true) {
14727            throw new IllegalArgumentException("File descriptors passed in Intent");
14728        }
14729
14730        synchronized(this) {
14731            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14732        }
14733    }
14734
14735    @Override
14736    public IBinder peekService(Intent service, String resolvedType) {
14737        enforceNotIsolatedCaller("peekService");
14738        // Refuse possible leaked file descriptors
14739        if (service != null && service.hasFileDescriptors() == true) {
14740            throw new IllegalArgumentException("File descriptors passed in Intent");
14741        }
14742        synchronized(this) {
14743            return mServices.peekServiceLocked(service, resolvedType);
14744        }
14745    }
14746
14747    @Override
14748    public boolean stopServiceToken(ComponentName className, IBinder token,
14749            int startId) {
14750        synchronized(this) {
14751            return mServices.stopServiceTokenLocked(className, token, startId);
14752        }
14753    }
14754
14755    @Override
14756    public void setServiceForeground(ComponentName className, IBinder token,
14757            int id, Notification notification, boolean removeNotification) {
14758        synchronized(this) {
14759            mServices.setServiceForegroundLocked(className, token, id, notification,
14760                    removeNotification);
14761        }
14762    }
14763
14764    @Override
14765    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14766            boolean requireFull, String name, String callerPackage) {
14767        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14768                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14769    }
14770
14771    int unsafeConvertIncomingUser(int userId) {
14772        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14773                ? mCurrentUserId : userId;
14774    }
14775
14776    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14777            int allowMode, String name, String callerPackage) {
14778        final int callingUserId = UserHandle.getUserId(callingUid);
14779        if (callingUserId == userId) {
14780            return userId;
14781        }
14782
14783        // Note that we may be accessing mCurrentUserId outside of a lock...
14784        // shouldn't be a big deal, if this is being called outside
14785        // of a locked context there is intrinsically a race with
14786        // the value the caller will receive and someone else changing it.
14787        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14788        // we will switch to the calling user if access to the current user fails.
14789        int targetUserId = unsafeConvertIncomingUser(userId);
14790
14791        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14792            final boolean allow;
14793            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14794                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14795                // If the caller has this permission, they always pass go.  And collect $200.
14796                allow = true;
14797            } else if (allowMode == ALLOW_FULL_ONLY) {
14798                // We require full access, sucks to be you.
14799                allow = false;
14800            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14801                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14802                // If the caller does not have either permission, they are always doomed.
14803                allow = false;
14804            } else if (allowMode == ALLOW_NON_FULL) {
14805                // We are blanket allowing non-full access, you lucky caller!
14806                allow = true;
14807            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14808                // We may or may not allow this depending on whether the two users are
14809                // in the same profile.
14810                synchronized (mUserProfileGroupIdsSelfLocked) {
14811                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14812                            UserInfo.NO_PROFILE_GROUP_ID);
14813                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14814                            UserInfo.NO_PROFILE_GROUP_ID);
14815                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14816                            && callingProfile == targetProfile;
14817                }
14818            } else {
14819                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14820            }
14821            if (!allow) {
14822                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14823                    // In this case, they would like to just execute as their
14824                    // owner user instead of failing.
14825                    targetUserId = callingUserId;
14826                } else {
14827                    StringBuilder builder = new StringBuilder(128);
14828                    builder.append("Permission Denial: ");
14829                    builder.append(name);
14830                    if (callerPackage != null) {
14831                        builder.append(" from ");
14832                        builder.append(callerPackage);
14833                    }
14834                    builder.append(" asks to run as user ");
14835                    builder.append(userId);
14836                    builder.append(" but is calling from user ");
14837                    builder.append(UserHandle.getUserId(callingUid));
14838                    builder.append("; this requires ");
14839                    builder.append(INTERACT_ACROSS_USERS_FULL);
14840                    if (allowMode != ALLOW_FULL_ONLY) {
14841                        builder.append(" or ");
14842                        builder.append(INTERACT_ACROSS_USERS);
14843                    }
14844                    String msg = builder.toString();
14845                    Slog.w(TAG, msg);
14846                    throw new SecurityException(msg);
14847                }
14848            }
14849        }
14850        if (!allowAll && targetUserId < 0) {
14851            throw new IllegalArgumentException(
14852                    "Call does not support special user #" + targetUserId);
14853        }
14854        // Check shell permission
14855        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14856            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14857                    targetUserId)) {
14858                throw new SecurityException("Shell does not have permission to access user "
14859                        + targetUserId + "\n " + Debug.getCallers(3));
14860            }
14861        }
14862        return targetUserId;
14863    }
14864
14865    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14866            String className, int flags) {
14867        boolean result = false;
14868        // For apps that don't have pre-defined UIDs, check for permission
14869        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14870            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14871                if (ActivityManager.checkUidPermission(
14872                        INTERACT_ACROSS_USERS,
14873                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14874                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14875                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14876                            + " requests FLAG_SINGLE_USER, but app does not hold "
14877                            + INTERACT_ACROSS_USERS;
14878                    Slog.w(TAG, msg);
14879                    throw new SecurityException(msg);
14880                }
14881                // Permission passed
14882                result = true;
14883            }
14884        } else if ("system".equals(componentProcessName)) {
14885            result = true;
14886        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14887            // Phone app and persistent apps are allowed to export singleuser providers.
14888            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14889                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14890        }
14891        if (DEBUG_MU) {
14892            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14893                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14894        }
14895        return result;
14896    }
14897
14898    /**
14899     * Checks to see if the caller is in the same app as the singleton
14900     * component, or the component is in a special app. It allows special apps
14901     * to export singleton components but prevents exporting singleton
14902     * components for regular apps.
14903     */
14904    boolean isValidSingletonCall(int callingUid, int componentUid) {
14905        int componentAppId = UserHandle.getAppId(componentUid);
14906        return UserHandle.isSameApp(callingUid, componentUid)
14907                || componentAppId == Process.SYSTEM_UID
14908                || componentAppId == Process.PHONE_UID
14909                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14910                        == PackageManager.PERMISSION_GRANTED;
14911    }
14912
14913    public int bindService(IApplicationThread caller, IBinder token,
14914            Intent service, String resolvedType,
14915            IServiceConnection connection, int flags, int userId) {
14916        enforceNotIsolatedCaller("bindService");
14917
14918        // Refuse possible leaked file descriptors
14919        if (service != null && service.hasFileDescriptors() == true) {
14920            throw new IllegalArgumentException("File descriptors passed in Intent");
14921        }
14922
14923        synchronized(this) {
14924            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14925                    connection, flags, userId);
14926        }
14927    }
14928
14929    public boolean unbindService(IServiceConnection connection) {
14930        synchronized (this) {
14931            return mServices.unbindServiceLocked(connection);
14932        }
14933    }
14934
14935    public void publishService(IBinder token, Intent intent, IBinder service) {
14936        // Refuse possible leaked file descriptors
14937        if (intent != null && intent.hasFileDescriptors() == true) {
14938            throw new IllegalArgumentException("File descriptors passed in Intent");
14939        }
14940
14941        synchronized(this) {
14942            if (!(token instanceof ServiceRecord)) {
14943                throw new IllegalArgumentException("Invalid service token");
14944            }
14945            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14946        }
14947    }
14948
14949    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14950        // Refuse possible leaked file descriptors
14951        if (intent != null && intent.hasFileDescriptors() == true) {
14952            throw new IllegalArgumentException("File descriptors passed in Intent");
14953        }
14954
14955        synchronized(this) {
14956            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14957        }
14958    }
14959
14960    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14961        synchronized(this) {
14962            if (!(token instanceof ServiceRecord)) {
14963                throw new IllegalArgumentException("Invalid service token");
14964            }
14965            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14966        }
14967    }
14968
14969    // =========================================================
14970    // BACKUP AND RESTORE
14971    // =========================================================
14972
14973    // Cause the target app to be launched if necessary and its backup agent
14974    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14975    // activity manager to announce its creation.
14976    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14977        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14978        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14979
14980        synchronized(this) {
14981            // !!! TODO: currently no check here that we're already bound
14982            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14983            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14984            synchronized (stats) {
14985                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14986            }
14987
14988            // Backup agent is now in use, its package can't be stopped.
14989            try {
14990                AppGlobals.getPackageManager().setPackageStoppedState(
14991                        app.packageName, false, UserHandle.getUserId(app.uid));
14992            } catch (RemoteException e) {
14993            } catch (IllegalArgumentException e) {
14994                Slog.w(TAG, "Failed trying to unstop package "
14995                        + app.packageName + ": " + e);
14996            }
14997
14998            BackupRecord r = new BackupRecord(ss, app, backupMode);
14999            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15000                    ? new ComponentName(app.packageName, app.backupAgentName)
15001                    : new ComponentName("android", "FullBackupAgent");
15002            // startProcessLocked() returns existing proc's record if it's already running
15003            ProcessRecord proc = startProcessLocked(app.processName, app,
15004                    false, 0, "backup", hostingName, false, false, false);
15005            if (proc == null) {
15006                Slog.e(TAG, "Unable to start backup agent process " + r);
15007                return false;
15008            }
15009
15010            r.app = proc;
15011            mBackupTarget = r;
15012            mBackupAppName = app.packageName;
15013
15014            // Try not to kill the process during backup
15015            updateOomAdjLocked(proc);
15016
15017            // If the process is already attached, schedule the creation of the backup agent now.
15018            // If it is not yet live, this will be done when it attaches to the framework.
15019            if (proc.thread != null) {
15020                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15021                try {
15022                    proc.thread.scheduleCreateBackupAgent(app,
15023                            compatibilityInfoForPackageLocked(app), backupMode);
15024                } catch (RemoteException e) {
15025                    // Will time out on the backup manager side
15026                }
15027            } else {
15028                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15029            }
15030            // Invariants: at this point, the target app process exists and the application
15031            // is either already running or in the process of coming up.  mBackupTarget and
15032            // mBackupAppName describe the app, so that when it binds back to the AM we
15033            // know that it's scheduled for a backup-agent operation.
15034        }
15035
15036        return true;
15037    }
15038
15039    @Override
15040    public void clearPendingBackup() {
15041        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15042        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15043
15044        synchronized (this) {
15045            mBackupTarget = null;
15046            mBackupAppName = null;
15047        }
15048    }
15049
15050    // A backup agent has just come up
15051    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15052        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15053                + " = " + agent);
15054
15055        synchronized(this) {
15056            if (!agentPackageName.equals(mBackupAppName)) {
15057                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15058                return;
15059            }
15060        }
15061
15062        long oldIdent = Binder.clearCallingIdentity();
15063        try {
15064            IBackupManager bm = IBackupManager.Stub.asInterface(
15065                    ServiceManager.getService(Context.BACKUP_SERVICE));
15066            bm.agentConnected(agentPackageName, agent);
15067        } catch (RemoteException e) {
15068            // can't happen; the backup manager service is local
15069        } catch (Exception e) {
15070            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15071            e.printStackTrace();
15072        } finally {
15073            Binder.restoreCallingIdentity(oldIdent);
15074        }
15075    }
15076
15077    // done with this agent
15078    public void unbindBackupAgent(ApplicationInfo appInfo) {
15079        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15080        if (appInfo == null) {
15081            Slog.w(TAG, "unbind backup agent for null app");
15082            return;
15083        }
15084
15085        synchronized(this) {
15086            try {
15087                if (mBackupAppName == null) {
15088                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15089                    return;
15090                }
15091
15092                if (!mBackupAppName.equals(appInfo.packageName)) {
15093                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15094                    return;
15095                }
15096
15097                // Not backing this app up any more; reset its OOM adjustment
15098                final ProcessRecord proc = mBackupTarget.app;
15099                updateOomAdjLocked(proc);
15100
15101                // If the app crashed during backup, 'thread' will be null here
15102                if (proc.thread != null) {
15103                    try {
15104                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15105                                compatibilityInfoForPackageLocked(appInfo));
15106                    } catch (Exception e) {
15107                        Slog.e(TAG, "Exception when unbinding backup agent:");
15108                        e.printStackTrace();
15109                    }
15110                }
15111            } finally {
15112                mBackupTarget = null;
15113                mBackupAppName = null;
15114            }
15115        }
15116    }
15117    // =========================================================
15118    // BROADCASTS
15119    // =========================================================
15120
15121    private final List getStickiesLocked(String action, IntentFilter filter,
15122            List cur, int userId) {
15123        final ContentResolver resolver = mContext.getContentResolver();
15124        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15125        if (stickies == null) {
15126            return cur;
15127        }
15128        final ArrayList<Intent> list = stickies.get(action);
15129        if (list == null) {
15130            return cur;
15131        }
15132        int N = list.size();
15133        for (int i=0; i<N; i++) {
15134            Intent intent = list.get(i);
15135            if (filter.match(resolver, intent, true, TAG) >= 0) {
15136                if (cur == null) {
15137                    cur = new ArrayList<Intent>();
15138                }
15139                cur.add(intent);
15140            }
15141        }
15142        return cur;
15143    }
15144
15145    boolean isPendingBroadcastProcessLocked(int pid) {
15146        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15147                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15148    }
15149
15150    void skipPendingBroadcastLocked(int pid) {
15151            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15152            for (BroadcastQueue queue : mBroadcastQueues) {
15153                queue.skipPendingBroadcastLocked(pid);
15154            }
15155    }
15156
15157    // The app just attached; send any pending broadcasts that it should receive
15158    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15159        boolean didSomething = false;
15160        for (BroadcastQueue queue : mBroadcastQueues) {
15161            didSomething |= queue.sendPendingBroadcastsLocked(app);
15162        }
15163        return didSomething;
15164    }
15165
15166    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15167            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15168        enforceNotIsolatedCaller("registerReceiver");
15169        int callingUid;
15170        int callingPid;
15171        synchronized(this) {
15172            ProcessRecord callerApp = null;
15173            if (caller != null) {
15174                callerApp = getRecordForAppLocked(caller);
15175                if (callerApp == null) {
15176                    throw new SecurityException(
15177                            "Unable to find app for caller " + caller
15178                            + " (pid=" + Binder.getCallingPid()
15179                            + ") when registering receiver " + receiver);
15180                }
15181                if (callerApp.info.uid != Process.SYSTEM_UID &&
15182                        !callerApp.pkgList.containsKey(callerPackage) &&
15183                        !"android".equals(callerPackage)) {
15184                    throw new SecurityException("Given caller package " + callerPackage
15185                            + " is not running in process " + callerApp);
15186                }
15187                callingUid = callerApp.info.uid;
15188                callingPid = callerApp.pid;
15189            } else {
15190                callerPackage = null;
15191                callingUid = Binder.getCallingUid();
15192                callingPid = Binder.getCallingPid();
15193            }
15194
15195            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15196                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15197
15198            List allSticky = null;
15199
15200            // Look for any matching sticky broadcasts...
15201            Iterator actions = filter.actionsIterator();
15202            if (actions != null) {
15203                while (actions.hasNext()) {
15204                    String action = (String)actions.next();
15205                    allSticky = getStickiesLocked(action, filter, allSticky,
15206                            UserHandle.USER_ALL);
15207                    allSticky = getStickiesLocked(action, filter, allSticky,
15208                            UserHandle.getUserId(callingUid));
15209                }
15210            } else {
15211                allSticky = getStickiesLocked(null, filter, allSticky,
15212                        UserHandle.USER_ALL);
15213                allSticky = getStickiesLocked(null, filter, allSticky,
15214                        UserHandle.getUserId(callingUid));
15215            }
15216
15217            // The first sticky in the list is returned directly back to
15218            // the client.
15219            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15220
15221            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15222                    + ": " + sticky);
15223
15224            if (receiver == null) {
15225                return sticky;
15226            }
15227
15228            ReceiverList rl
15229                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15230            if (rl == null) {
15231                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15232                        userId, receiver);
15233                if (rl.app != null) {
15234                    rl.app.receivers.add(rl);
15235                } else {
15236                    try {
15237                        receiver.asBinder().linkToDeath(rl, 0);
15238                    } catch (RemoteException e) {
15239                        return sticky;
15240                    }
15241                    rl.linkedToDeath = true;
15242                }
15243                mRegisteredReceivers.put(receiver.asBinder(), rl);
15244            } else if (rl.uid != callingUid) {
15245                throw new IllegalArgumentException(
15246                        "Receiver requested to register for uid " + callingUid
15247                        + " was previously registered for uid " + rl.uid);
15248            } else if (rl.pid != callingPid) {
15249                throw new IllegalArgumentException(
15250                        "Receiver requested to register for pid " + callingPid
15251                        + " was previously registered for pid " + rl.pid);
15252            } else if (rl.userId != userId) {
15253                throw new IllegalArgumentException(
15254                        "Receiver requested to register for user " + userId
15255                        + " was previously registered for user " + rl.userId);
15256            }
15257            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15258                    permission, callingUid, userId);
15259            rl.add(bf);
15260            if (!bf.debugCheck()) {
15261                Slog.w(TAG, "==> For Dynamic broadast");
15262            }
15263            mReceiverResolver.addFilter(bf);
15264
15265            // Enqueue broadcasts for all existing stickies that match
15266            // this filter.
15267            if (allSticky != null) {
15268                ArrayList receivers = new ArrayList();
15269                receivers.add(bf);
15270
15271                int N = allSticky.size();
15272                for (int i=0; i<N; i++) {
15273                    Intent intent = (Intent)allSticky.get(i);
15274                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15275                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15276                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15277                            null, null, false, true, true, -1);
15278                    queue.enqueueParallelBroadcastLocked(r);
15279                    queue.scheduleBroadcastsLocked();
15280                }
15281            }
15282
15283            return sticky;
15284        }
15285    }
15286
15287    public void unregisterReceiver(IIntentReceiver receiver) {
15288        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15289
15290        final long origId = Binder.clearCallingIdentity();
15291        try {
15292            boolean doTrim = false;
15293
15294            synchronized(this) {
15295                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15296                if (rl != null) {
15297                    if (rl.curBroadcast != null) {
15298                        BroadcastRecord r = rl.curBroadcast;
15299                        final boolean doNext = finishReceiverLocked(
15300                                receiver.asBinder(), r.resultCode, r.resultData,
15301                                r.resultExtras, r.resultAbort);
15302                        if (doNext) {
15303                            doTrim = true;
15304                            r.queue.processNextBroadcast(false);
15305                        }
15306                    }
15307
15308                    if (rl.app != null) {
15309                        rl.app.receivers.remove(rl);
15310                    }
15311                    removeReceiverLocked(rl);
15312                    if (rl.linkedToDeath) {
15313                        rl.linkedToDeath = false;
15314                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15315                    }
15316                }
15317            }
15318
15319            // If we actually concluded any broadcasts, we might now be able
15320            // to trim the recipients' apps from our working set
15321            if (doTrim) {
15322                trimApplications();
15323                return;
15324            }
15325
15326        } finally {
15327            Binder.restoreCallingIdentity(origId);
15328        }
15329    }
15330
15331    void removeReceiverLocked(ReceiverList rl) {
15332        mRegisteredReceivers.remove(rl.receiver.asBinder());
15333        int N = rl.size();
15334        for (int i=0; i<N; i++) {
15335            mReceiverResolver.removeFilter(rl.get(i));
15336        }
15337    }
15338
15339    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15340        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15341            ProcessRecord r = mLruProcesses.get(i);
15342            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15343                try {
15344                    r.thread.dispatchPackageBroadcast(cmd, packages);
15345                } catch (RemoteException ex) {
15346                }
15347            }
15348        }
15349    }
15350
15351    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15352            int callingUid, int[] users) {
15353        List<ResolveInfo> receivers = null;
15354        try {
15355            HashSet<ComponentName> singleUserReceivers = null;
15356            boolean scannedFirstReceivers = false;
15357            for (int user : users) {
15358                // Skip users that have Shell restrictions
15359                if (callingUid == Process.SHELL_UID
15360                        && getUserManagerLocked().hasUserRestriction(
15361                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15362                    continue;
15363                }
15364                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15365                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15366                if (user != 0 && newReceivers != null) {
15367                    // If this is not the primary user, we need to check for
15368                    // any receivers that should be filtered out.
15369                    for (int i=0; i<newReceivers.size(); i++) {
15370                        ResolveInfo ri = newReceivers.get(i);
15371                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15372                            newReceivers.remove(i);
15373                            i--;
15374                        }
15375                    }
15376                }
15377                if (newReceivers != null && newReceivers.size() == 0) {
15378                    newReceivers = null;
15379                }
15380                if (receivers == null) {
15381                    receivers = newReceivers;
15382                } else if (newReceivers != null) {
15383                    // We need to concatenate the additional receivers
15384                    // found with what we have do far.  This would be easy,
15385                    // but we also need to de-dup any receivers that are
15386                    // singleUser.
15387                    if (!scannedFirstReceivers) {
15388                        // Collect any single user receivers we had already retrieved.
15389                        scannedFirstReceivers = true;
15390                        for (int i=0; i<receivers.size(); i++) {
15391                            ResolveInfo ri = receivers.get(i);
15392                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15393                                ComponentName cn = new ComponentName(
15394                                        ri.activityInfo.packageName, ri.activityInfo.name);
15395                                if (singleUserReceivers == null) {
15396                                    singleUserReceivers = new HashSet<ComponentName>();
15397                                }
15398                                singleUserReceivers.add(cn);
15399                            }
15400                        }
15401                    }
15402                    // Add the new results to the existing results, tracking
15403                    // and de-dupping single user receivers.
15404                    for (int i=0; i<newReceivers.size(); i++) {
15405                        ResolveInfo ri = newReceivers.get(i);
15406                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15407                            ComponentName cn = new ComponentName(
15408                                    ri.activityInfo.packageName, ri.activityInfo.name);
15409                            if (singleUserReceivers == null) {
15410                                singleUserReceivers = new HashSet<ComponentName>();
15411                            }
15412                            if (!singleUserReceivers.contains(cn)) {
15413                                singleUserReceivers.add(cn);
15414                                receivers.add(ri);
15415                            }
15416                        } else {
15417                            receivers.add(ri);
15418                        }
15419                    }
15420                }
15421            }
15422        } catch (RemoteException ex) {
15423            // pm is in same process, this will never happen.
15424        }
15425        return receivers;
15426    }
15427
15428    private final int broadcastIntentLocked(ProcessRecord callerApp,
15429            String callerPackage, Intent intent, String resolvedType,
15430            IIntentReceiver resultTo, int resultCode, String resultData,
15431            Bundle map, String requiredPermission, int appOp,
15432            boolean ordered, boolean sticky, int callingPid, int callingUid,
15433            int userId) {
15434        intent = new Intent(intent);
15435
15436        // By default broadcasts do not go to stopped apps.
15437        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15438
15439        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15440            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15441            + " ordered=" + ordered + " userid=" + userId);
15442        if ((resultTo != null) && !ordered) {
15443            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15444        }
15445
15446        userId = handleIncomingUser(callingPid, callingUid, userId,
15447                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15448
15449        // Make sure that the user who is receiving this broadcast is started.
15450        // If not, we will just skip it.
15451
15452        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15453            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15454                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15455                Slog.w(TAG, "Skipping broadcast of " + intent
15456                        + ": user " + userId + " is stopped");
15457                return ActivityManager.BROADCAST_SUCCESS;
15458            }
15459        }
15460
15461        /*
15462         * Prevent non-system code (defined here to be non-persistent
15463         * processes) from sending protected broadcasts.
15464         */
15465        int callingAppId = UserHandle.getAppId(callingUid);
15466        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15467            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15468            || callingAppId == Process.NFC_UID || callingUid == 0) {
15469            // Always okay.
15470        } else if (callerApp == null || !callerApp.persistent) {
15471            try {
15472                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15473                        intent.getAction())) {
15474                    String msg = "Permission Denial: not allowed to send broadcast "
15475                            + intent.getAction() + " from pid="
15476                            + callingPid + ", uid=" + callingUid;
15477                    Slog.w(TAG, msg);
15478                    throw new SecurityException(msg);
15479                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15480                    // Special case for compatibility: we don't want apps to send this,
15481                    // but historically it has not been protected and apps may be using it
15482                    // to poke their own app widget.  So, instead of making it protected,
15483                    // just limit it to the caller.
15484                    if (callerApp == null) {
15485                        String msg = "Permission Denial: not allowed to send broadcast "
15486                                + intent.getAction() + " from unknown caller.";
15487                        Slog.w(TAG, msg);
15488                        throw new SecurityException(msg);
15489                    } else if (intent.getComponent() != null) {
15490                        // They are good enough to send to an explicit component...  verify
15491                        // it is being sent to the calling app.
15492                        if (!intent.getComponent().getPackageName().equals(
15493                                callerApp.info.packageName)) {
15494                            String msg = "Permission Denial: not allowed to send broadcast "
15495                                    + intent.getAction() + " to "
15496                                    + intent.getComponent().getPackageName() + " from "
15497                                    + callerApp.info.packageName;
15498                            Slog.w(TAG, msg);
15499                            throw new SecurityException(msg);
15500                        }
15501                    } else {
15502                        // Limit broadcast to their own package.
15503                        intent.setPackage(callerApp.info.packageName);
15504                    }
15505                }
15506            } catch (RemoteException e) {
15507                Slog.w(TAG, "Remote exception", e);
15508                return ActivityManager.BROADCAST_SUCCESS;
15509            }
15510        }
15511
15512        // Handle special intents: if this broadcast is from the package
15513        // manager about a package being removed, we need to remove all of
15514        // its activities from the history stack.
15515        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15516                intent.getAction());
15517        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15518                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15519                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15520                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15521                || uidRemoved) {
15522            if (checkComponentPermission(
15523                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15524                    callingPid, callingUid, -1, true)
15525                    == PackageManager.PERMISSION_GRANTED) {
15526                if (uidRemoved) {
15527                    final Bundle intentExtras = intent.getExtras();
15528                    final int uid = intentExtras != null
15529                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15530                    if (uid >= 0) {
15531                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15532                        synchronized (bs) {
15533                            bs.removeUidStatsLocked(uid);
15534                        }
15535                        mAppOpsService.uidRemoved(uid);
15536                    }
15537                } else {
15538                    // If resources are unavailable just force stop all
15539                    // those packages and flush the attribute cache as well.
15540                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15541                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15542                        if (list != null && (list.length > 0)) {
15543                            for (String pkg : list) {
15544                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15545                                        "storage unmount");
15546                            }
15547                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15548                            sendPackageBroadcastLocked(
15549                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15550                        }
15551                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15552                            intent.getAction())) {
15553                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15554                    } else {
15555                        Uri data = intent.getData();
15556                        String ssp;
15557                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15558                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15559                                    intent.getAction());
15560                            boolean fullUninstall = removed &&
15561                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15562                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15563                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15564                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15565                                        false, fullUninstall, userId,
15566                                        removed ? "pkg removed" : "pkg changed");
15567                            }
15568                            if (removed) {
15569                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15570                                        new String[] {ssp}, userId);
15571                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15572                                    mAppOpsService.packageRemoved(
15573                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15574
15575                                    // Remove all permissions granted from/to this package
15576                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15577                                }
15578                            }
15579                        }
15580                    }
15581                }
15582            } else {
15583                String msg = "Permission Denial: " + intent.getAction()
15584                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15585                        + ", uid=" + callingUid + ")"
15586                        + " requires "
15587                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15588                Slog.w(TAG, msg);
15589                throw new SecurityException(msg);
15590            }
15591
15592        // Special case for adding a package: by default turn on compatibility
15593        // mode.
15594        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15595            Uri data = intent.getData();
15596            String ssp;
15597            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15598                mCompatModePackages.handlePackageAddedLocked(ssp,
15599                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15600            }
15601        }
15602
15603        /*
15604         * If this is the time zone changed action, queue up a message that will reset the timezone
15605         * of all currently running processes. This message will get queued up before the broadcast
15606         * happens.
15607         */
15608        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15609            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15610        }
15611
15612        /*
15613         * If the user set the time, let all running processes know.
15614         */
15615        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15616            final int is24Hour = intent.getBooleanExtra(
15617                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15618            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15619            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15620            synchronized (stats) {
15621                stats.noteCurrentTimeChangedLocked();
15622            }
15623        }
15624
15625        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15626            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15627        }
15628
15629        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15630            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15631            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15632        }
15633
15634        // Add to the sticky list if requested.
15635        if (sticky) {
15636            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15637                    callingPid, callingUid)
15638                    != PackageManager.PERMISSION_GRANTED) {
15639                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15640                        + callingPid + ", uid=" + callingUid
15641                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15642                Slog.w(TAG, msg);
15643                throw new SecurityException(msg);
15644            }
15645            if (requiredPermission != null) {
15646                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15647                        + " and enforce permission " + requiredPermission);
15648                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15649            }
15650            if (intent.getComponent() != null) {
15651                throw new SecurityException(
15652                        "Sticky broadcasts can't target a specific component");
15653            }
15654            // We use userId directly here, since the "all" target is maintained
15655            // as a separate set of sticky broadcasts.
15656            if (userId != UserHandle.USER_ALL) {
15657                // But first, if this is not a broadcast to all users, then
15658                // make sure it doesn't conflict with an existing broadcast to
15659                // all users.
15660                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15661                        UserHandle.USER_ALL);
15662                if (stickies != null) {
15663                    ArrayList<Intent> list = stickies.get(intent.getAction());
15664                    if (list != null) {
15665                        int N = list.size();
15666                        int i;
15667                        for (i=0; i<N; i++) {
15668                            if (intent.filterEquals(list.get(i))) {
15669                                throw new IllegalArgumentException(
15670                                        "Sticky broadcast " + intent + " for user "
15671                                        + userId + " conflicts with existing global broadcast");
15672                            }
15673                        }
15674                    }
15675                }
15676            }
15677            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15678            if (stickies == null) {
15679                stickies = new ArrayMap<String, ArrayList<Intent>>();
15680                mStickyBroadcasts.put(userId, stickies);
15681            }
15682            ArrayList<Intent> list = stickies.get(intent.getAction());
15683            if (list == null) {
15684                list = new ArrayList<Intent>();
15685                stickies.put(intent.getAction(), list);
15686            }
15687            int N = list.size();
15688            int i;
15689            for (i=0; i<N; i++) {
15690                if (intent.filterEquals(list.get(i))) {
15691                    // This sticky already exists, replace it.
15692                    list.set(i, new Intent(intent));
15693                    break;
15694                }
15695            }
15696            if (i >= N) {
15697                list.add(new Intent(intent));
15698            }
15699        }
15700
15701        int[] users;
15702        if (userId == UserHandle.USER_ALL) {
15703            // Caller wants broadcast to go to all started users.
15704            users = mStartedUserArray;
15705        } else {
15706            // Caller wants broadcast to go to one specific user.
15707            users = new int[] {userId};
15708        }
15709
15710        // Figure out who all will receive this broadcast.
15711        List receivers = null;
15712        List<BroadcastFilter> registeredReceivers = null;
15713        // Need to resolve the intent to interested receivers...
15714        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15715                 == 0) {
15716            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15717        }
15718        if (intent.getComponent() == null) {
15719            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15720                // Query one target user at a time, excluding shell-restricted users
15721                UserManagerService ums = getUserManagerLocked();
15722                for (int i = 0; i < users.length; i++) {
15723                    if (ums.hasUserRestriction(
15724                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15725                        continue;
15726                    }
15727                    List<BroadcastFilter> registeredReceiversForUser =
15728                            mReceiverResolver.queryIntent(intent,
15729                                    resolvedType, false, users[i]);
15730                    if (registeredReceivers == null) {
15731                        registeredReceivers = registeredReceiversForUser;
15732                    } else if (registeredReceiversForUser != null) {
15733                        registeredReceivers.addAll(registeredReceiversForUser);
15734                    }
15735                }
15736            } else {
15737                registeredReceivers = mReceiverResolver.queryIntent(intent,
15738                        resolvedType, false, userId);
15739            }
15740        }
15741
15742        final boolean replacePending =
15743                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15744
15745        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15746                + " replacePending=" + replacePending);
15747
15748        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15749        if (!ordered && NR > 0) {
15750            // If we are not serializing this broadcast, then send the
15751            // registered receivers separately so they don't wait for the
15752            // components to be launched.
15753            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15754            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15755                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15756                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15757                    ordered, sticky, false, userId);
15758            if (DEBUG_BROADCAST) Slog.v(
15759                    TAG, "Enqueueing parallel broadcast " + r);
15760            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15761            if (!replaced) {
15762                queue.enqueueParallelBroadcastLocked(r);
15763                queue.scheduleBroadcastsLocked();
15764            }
15765            registeredReceivers = null;
15766            NR = 0;
15767        }
15768
15769        // Merge into one list.
15770        int ir = 0;
15771        if (receivers != null) {
15772            // A special case for PACKAGE_ADDED: do not allow the package
15773            // being added to see this broadcast.  This prevents them from
15774            // using this as a back door to get run as soon as they are
15775            // installed.  Maybe in the future we want to have a special install
15776            // broadcast or such for apps, but we'd like to deliberately make
15777            // this decision.
15778            String skipPackages[] = null;
15779            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15780                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15781                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15782                Uri data = intent.getData();
15783                if (data != null) {
15784                    String pkgName = data.getSchemeSpecificPart();
15785                    if (pkgName != null) {
15786                        skipPackages = new String[] { pkgName };
15787                    }
15788                }
15789            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15790                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15791            }
15792            if (skipPackages != null && (skipPackages.length > 0)) {
15793                for (String skipPackage : skipPackages) {
15794                    if (skipPackage != null) {
15795                        int NT = receivers.size();
15796                        for (int it=0; it<NT; it++) {
15797                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15798                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15799                                receivers.remove(it);
15800                                it--;
15801                                NT--;
15802                            }
15803                        }
15804                    }
15805                }
15806            }
15807
15808            int NT = receivers != null ? receivers.size() : 0;
15809            int it = 0;
15810            ResolveInfo curt = null;
15811            BroadcastFilter curr = null;
15812            while (it < NT && ir < NR) {
15813                if (curt == null) {
15814                    curt = (ResolveInfo)receivers.get(it);
15815                }
15816                if (curr == null) {
15817                    curr = registeredReceivers.get(ir);
15818                }
15819                if (curr.getPriority() >= curt.priority) {
15820                    // Insert this broadcast record into the final list.
15821                    receivers.add(it, curr);
15822                    ir++;
15823                    curr = null;
15824                    it++;
15825                    NT++;
15826                } else {
15827                    // Skip to the next ResolveInfo in the final list.
15828                    it++;
15829                    curt = null;
15830                }
15831            }
15832        }
15833        while (ir < NR) {
15834            if (receivers == null) {
15835                receivers = new ArrayList();
15836            }
15837            receivers.add(registeredReceivers.get(ir));
15838            ir++;
15839        }
15840
15841        if ((receivers != null && receivers.size() > 0)
15842                || resultTo != null) {
15843            BroadcastQueue queue = broadcastQueueForIntent(intent);
15844            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15845                    callerPackage, callingPid, callingUid, resolvedType,
15846                    requiredPermission, appOp, receivers, resultTo, resultCode,
15847                    resultData, map, ordered, sticky, false, userId);
15848            if (DEBUG_BROADCAST) Slog.v(
15849                    TAG, "Enqueueing ordered broadcast " + r
15850                    + ": prev had " + queue.mOrderedBroadcasts.size());
15851            if (DEBUG_BROADCAST) {
15852                int seq = r.intent.getIntExtra("seq", -1);
15853                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15854            }
15855            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15856            if (!replaced) {
15857                queue.enqueueOrderedBroadcastLocked(r);
15858                queue.scheduleBroadcastsLocked();
15859            }
15860        }
15861
15862        return ActivityManager.BROADCAST_SUCCESS;
15863    }
15864
15865    final Intent verifyBroadcastLocked(Intent intent) {
15866        // Refuse possible leaked file descriptors
15867        if (intent != null && intent.hasFileDescriptors() == true) {
15868            throw new IllegalArgumentException("File descriptors passed in Intent");
15869        }
15870
15871        int flags = intent.getFlags();
15872
15873        if (!mProcessesReady) {
15874            // if the caller really truly claims to know what they're doing, go
15875            // ahead and allow the broadcast without launching any receivers
15876            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15877                intent = new Intent(intent);
15878                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15879            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15880                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15881                        + " before boot completion");
15882                throw new IllegalStateException("Cannot broadcast before boot completed");
15883            }
15884        }
15885
15886        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15887            throw new IllegalArgumentException(
15888                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15889        }
15890
15891        return intent;
15892    }
15893
15894    public final int broadcastIntent(IApplicationThread caller,
15895            Intent intent, String resolvedType, IIntentReceiver resultTo,
15896            int resultCode, String resultData, Bundle map,
15897            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15898        enforceNotIsolatedCaller("broadcastIntent");
15899        synchronized(this) {
15900            intent = verifyBroadcastLocked(intent);
15901
15902            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15903            final int callingPid = Binder.getCallingPid();
15904            final int callingUid = Binder.getCallingUid();
15905            final long origId = Binder.clearCallingIdentity();
15906            int res = broadcastIntentLocked(callerApp,
15907                    callerApp != null ? callerApp.info.packageName : null,
15908                    intent, resolvedType, resultTo,
15909                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15910                    callingPid, callingUid, userId);
15911            Binder.restoreCallingIdentity(origId);
15912            return res;
15913        }
15914    }
15915
15916    int broadcastIntentInPackage(String packageName, int uid,
15917            Intent intent, String resolvedType, IIntentReceiver resultTo,
15918            int resultCode, String resultData, Bundle map,
15919            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15920        synchronized(this) {
15921            intent = verifyBroadcastLocked(intent);
15922
15923            final long origId = Binder.clearCallingIdentity();
15924            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15925                    resultTo, resultCode, resultData, map, requiredPermission,
15926                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15927            Binder.restoreCallingIdentity(origId);
15928            return res;
15929        }
15930    }
15931
15932    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15933        // Refuse possible leaked file descriptors
15934        if (intent != null && intent.hasFileDescriptors() == true) {
15935            throw new IllegalArgumentException("File descriptors passed in Intent");
15936        }
15937
15938        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15939                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15940
15941        synchronized(this) {
15942            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15943                    != PackageManager.PERMISSION_GRANTED) {
15944                String msg = "Permission Denial: unbroadcastIntent() from pid="
15945                        + Binder.getCallingPid()
15946                        + ", uid=" + Binder.getCallingUid()
15947                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15948                Slog.w(TAG, msg);
15949                throw new SecurityException(msg);
15950            }
15951            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15952            if (stickies != null) {
15953                ArrayList<Intent> list = stickies.get(intent.getAction());
15954                if (list != null) {
15955                    int N = list.size();
15956                    int i;
15957                    for (i=0; i<N; i++) {
15958                        if (intent.filterEquals(list.get(i))) {
15959                            list.remove(i);
15960                            break;
15961                        }
15962                    }
15963                    if (list.size() <= 0) {
15964                        stickies.remove(intent.getAction());
15965                    }
15966                }
15967                if (stickies.size() <= 0) {
15968                    mStickyBroadcasts.remove(userId);
15969                }
15970            }
15971        }
15972    }
15973
15974    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15975            String resultData, Bundle resultExtras, boolean resultAbort) {
15976        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15977        if (r == null) {
15978            Slog.w(TAG, "finishReceiver called but not found on queue");
15979            return false;
15980        }
15981
15982        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15983    }
15984
15985    void backgroundServicesFinishedLocked(int userId) {
15986        for (BroadcastQueue queue : mBroadcastQueues) {
15987            queue.backgroundServicesFinishedLocked(userId);
15988        }
15989    }
15990
15991    public void finishReceiver(IBinder who, int resultCode, String resultData,
15992            Bundle resultExtras, boolean resultAbort) {
15993        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15994
15995        // Refuse possible leaked file descriptors
15996        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15997            throw new IllegalArgumentException("File descriptors passed in Bundle");
15998        }
15999
16000        final long origId = Binder.clearCallingIdentity();
16001        try {
16002            boolean doNext = false;
16003            BroadcastRecord r;
16004
16005            synchronized(this) {
16006                r = broadcastRecordForReceiverLocked(who);
16007                if (r != null) {
16008                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16009                        resultData, resultExtras, resultAbort, true);
16010                }
16011            }
16012
16013            if (doNext) {
16014                r.queue.processNextBroadcast(false);
16015            }
16016            trimApplications();
16017        } finally {
16018            Binder.restoreCallingIdentity(origId);
16019        }
16020    }
16021
16022    // =========================================================
16023    // INSTRUMENTATION
16024    // =========================================================
16025
16026    public boolean startInstrumentation(ComponentName className,
16027            String profileFile, int flags, Bundle arguments,
16028            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16029            int userId, String abiOverride) {
16030        enforceNotIsolatedCaller("startInstrumentation");
16031        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16032                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16033        // Refuse possible leaked file descriptors
16034        if (arguments != null && arguments.hasFileDescriptors()) {
16035            throw new IllegalArgumentException("File descriptors passed in Bundle");
16036        }
16037
16038        synchronized(this) {
16039            InstrumentationInfo ii = null;
16040            ApplicationInfo ai = null;
16041            try {
16042                ii = mContext.getPackageManager().getInstrumentationInfo(
16043                    className, STOCK_PM_FLAGS);
16044                ai = AppGlobals.getPackageManager().getApplicationInfo(
16045                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16046            } catch (PackageManager.NameNotFoundException e) {
16047            } catch (RemoteException e) {
16048            }
16049            if (ii == null) {
16050                reportStartInstrumentationFailure(watcher, className,
16051                        "Unable to find instrumentation info for: " + className);
16052                return false;
16053            }
16054            if (ai == null) {
16055                reportStartInstrumentationFailure(watcher, className,
16056                        "Unable to find instrumentation target package: " + ii.targetPackage);
16057                return false;
16058            }
16059
16060            int match = mContext.getPackageManager().checkSignatures(
16061                    ii.targetPackage, ii.packageName);
16062            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16063                String msg = "Permission Denial: starting instrumentation "
16064                        + className + " from pid="
16065                        + Binder.getCallingPid()
16066                        + ", uid=" + Binder.getCallingPid()
16067                        + " not allowed because package " + ii.packageName
16068                        + " does not have a signature matching the target "
16069                        + ii.targetPackage;
16070                reportStartInstrumentationFailure(watcher, className, msg);
16071                throw new SecurityException(msg);
16072            }
16073
16074            final long origId = Binder.clearCallingIdentity();
16075            // Instrumentation can kill and relaunch even persistent processes
16076            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16077                    "start instr");
16078            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16079            app.instrumentationClass = className;
16080            app.instrumentationInfo = ai;
16081            app.instrumentationProfileFile = profileFile;
16082            app.instrumentationArguments = arguments;
16083            app.instrumentationWatcher = watcher;
16084            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16085            app.instrumentationResultClass = className;
16086            Binder.restoreCallingIdentity(origId);
16087        }
16088
16089        return true;
16090    }
16091
16092    /**
16093     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16094     * error to the logs, but if somebody is watching, send the report there too.  This enables
16095     * the "am" command to report errors with more information.
16096     *
16097     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16098     * @param cn The component name of the instrumentation.
16099     * @param report The error report.
16100     */
16101    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16102            ComponentName cn, String report) {
16103        Slog.w(TAG, report);
16104        try {
16105            if (watcher != null) {
16106                Bundle results = new Bundle();
16107                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16108                results.putString("Error", report);
16109                watcher.instrumentationStatus(cn, -1, results);
16110            }
16111        } catch (RemoteException e) {
16112            Slog.w(TAG, e);
16113        }
16114    }
16115
16116    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16117        if (app.instrumentationWatcher != null) {
16118            try {
16119                // NOTE:  IInstrumentationWatcher *must* be oneway here
16120                app.instrumentationWatcher.instrumentationFinished(
16121                    app.instrumentationClass,
16122                    resultCode,
16123                    results);
16124            } catch (RemoteException e) {
16125            }
16126        }
16127        if (app.instrumentationUiAutomationConnection != null) {
16128            try {
16129                app.instrumentationUiAutomationConnection.shutdown();
16130            } catch (RemoteException re) {
16131                /* ignore */
16132            }
16133            // Only a UiAutomation can set this flag and now that
16134            // it is finished we make sure it is reset to its default.
16135            mUserIsMonkey = false;
16136        }
16137        app.instrumentationWatcher = null;
16138        app.instrumentationUiAutomationConnection = null;
16139        app.instrumentationClass = null;
16140        app.instrumentationInfo = null;
16141        app.instrumentationProfileFile = null;
16142        app.instrumentationArguments = null;
16143
16144        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16145                "finished inst");
16146    }
16147
16148    public void finishInstrumentation(IApplicationThread target,
16149            int resultCode, Bundle results) {
16150        int userId = UserHandle.getCallingUserId();
16151        // Refuse possible leaked file descriptors
16152        if (results != null && results.hasFileDescriptors()) {
16153            throw new IllegalArgumentException("File descriptors passed in Intent");
16154        }
16155
16156        synchronized(this) {
16157            ProcessRecord app = getRecordForAppLocked(target);
16158            if (app == null) {
16159                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16160                return;
16161            }
16162            final long origId = Binder.clearCallingIdentity();
16163            finishInstrumentationLocked(app, resultCode, results);
16164            Binder.restoreCallingIdentity(origId);
16165        }
16166    }
16167
16168    // =========================================================
16169    // CONFIGURATION
16170    // =========================================================
16171
16172    public ConfigurationInfo getDeviceConfigurationInfo() {
16173        ConfigurationInfo config = new ConfigurationInfo();
16174        synchronized (this) {
16175            config.reqTouchScreen = mConfiguration.touchscreen;
16176            config.reqKeyboardType = mConfiguration.keyboard;
16177            config.reqNavigation = mConfiguration.navigation;
16178            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16179                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16180                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16181            }
16182            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16183                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16184                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16185            }
16186            config.reqGlEsVersion = GL_ES_VERSION;
16187        }
16188        return config;
16189    }
16190
16191    ActivityStack getFocusedStack() {
16192        return mStackSupervisor.getFocusedStack();
16193    }
16194
16195    public Configuration getConfiguration() {
16196        Configuration ci;
16197        synchronized(this) {
16198            ci = new Configuration(mConfiguration);
16199        }
16200        return ci;
16201    }
16202
16203    public void updatePersistentConfiguration(Configuration values) {
16204        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16205                "updateConfiguration()");
16206        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16207                "updateConfiguration()");
16208        if (values == null) {
16209            throw new NullPointerException("Configuration must not be null");
16210        }
16211
16212        synchronized(this) {
16213            final long origId = Binder.clearCallingIdentity();
16214            updateConfigurationLocked(values, null, true, false);
16215            Binder.restoreCallingIdentity(origId);
16216        }
16217    }
16218
16219    public void updateConfiguration(Configuration values) {
16220        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16221                "updateConfiguration()");
16222
16223        synchronized(this) {
16224            if (values == null && mWindowManager != null) {
16225                // sentinel: fetch the current configuration from the window manager
16226                values = mWindowManager.computeNewConfiguration();
16227            }
16228
16229            if (mWindowManager != null) {
16230                mProcessList.applyDisplaySize(mWindowManager);
16231            }
16232
16233            final long origId = Binder.clearCallingIdentity();
16234            if (values != null) {
16235                Settings.System.clearConfiguration(values);
16236            }
16237            updateConfigurationLocked(values, null, false, false);
16238            Binder.restoreCallingIdentity(origId);
16239        }
16240    }
16241
16242    /**
16243     * Do either or both things: (1) change the current configuration, and (2)
16244     * make sure the given activity is running with the (now) current
16245     * configuration.  Returns true if the activity has been left running, or
16246     * false if <var>starting</var> is being destroyed to match the new
16247     * configuration.
16248     * @param persistent TODO
16249     */
16250    boolean updateConfigurationLocked(Configuration values,
16251            ActivityRecord starting, boolean persistent, boolean initLocale) {
16252        int changes = 0;
16253
16254        if (values != null) {
16255            Configuration newConfig = new Configuration(mConfiguration);
16256            changes = newConfig.updateFrom(values);
16257            if (changes != 0) {
16258                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16259                    Slog.i(TAG, "Updating configuration to: " + values);
16260                }
16261
16262                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16263
16264                if (values.locale != null && !initLocale) {
16265                    saveLocaleLocked(values.locale,
16266                                     !values.locale.equals(mConfiguration.locale),
16267                                     values.userSetLocale);
16268                }
16269
16270                mConfigurationSeq++;
16271                if (mConfigurationSeq <= 0) {
16272                    mConfigurationSeq = 1;
16273                }
16274                newConfig.seq = mConfigurationSeq;
16275                mConfiguration = newConfig;
16276                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16277                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16278                //mUsageStatsService.noteStartConfig(newConfig);
16279
16280                final Configuration configCopy = new Configuration(mConfiguration);
16281
16282                // TODO: If our config changes, should we auto dismiss any currently
16283                // showing dialogs?
16284                mShowDialogs = shouldShowDialogs(newConfig);
16285
16286                AttributeCache ac = AttributeCache.instance();
16287                if (ac != null) {
16288                    ac.updateConfiguration(configCopy);
16289                }
16290
16291                // Make sure all resources in our process are updated
16292                // right now, so that anyone who is going to retrieve
16293                // resource values after we return will be sure to get
16294                // the new ones.  This is especially important during
16295                // boot, where the first config change needs to guarantee
16296                // all resources have that config before following boot
16297                // code is executed.
16298                mSystemThread.applyConfigurationToResources(configCopy);
16299
16300                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16301                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16302                    msg.obj = new Configuration(configCopy);
16303                    mHandler.sendMessage(msg);
16304                }
16305
16306                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16307                    ProcessRecord app = mLruProcesses.get(i);
16308                    try {
16309                        if (app.thread != null) {
16310                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16311                                    + app.processName + " new config " + mConfiguration);
16312                            app.thread.scheduleConfigurationChanged(configCopy);
16313                        }
16314                    } catch (Exception e) {
16315                    }
16316                }
16317                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16318                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16319                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16320                        | Intent.FLAG_RECEIVER_FOREGROUND);
16321                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16322                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16323                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16324                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16325                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16326                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16327                    broadcastIntentLocked(null, null, intent,
16328                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16329                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16330                }
16331            }
16332        }
16333
16334        boolean kept = true;
16335        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16336        // mainStack is null during startup.
16337        if (mainStack != null) {
16338            if (changes != 0 && starting == null) {
16339                // If the configuration changed, and the caller is not already
16340                // in the process of starting an activity, then find the top
16341                // activity to check if its configuration needs to change.
16342                starting = mainStack.topRunningActivityLocked(null);
16343            }
16344
16345            if (starting != null) {
16346                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16347                // And we need to make sure at this point that all other activities
16348                // are made visible with the correct configuration.
16349                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16350            }
16351        }
16352
16353        if (values != null && mWindowManager != null) {
16354            mWindowManager.setNewConfiguration(mConfiguration);
16355        }
16356
16357        return kept;
16358    }
16359
16360    /**
16361     * Decide based on the configuration whether we should shouw the ANR,
16362     * crash, etc dialogs.  The idea is that if there is no affordnace to
16363     * press the on-screen buttons, we shouldn't show the dialog.
16364     *
16365     * A thought: SystemUI might also want to get told about this, the Power
16366     * dialog / global actions also might want different behaviors.
16367     */
16368    private static final boolean shouldShowDialogs(Configuration config) {
16369        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16370                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16371    }
16372
16373    /**
16374     * Save the locale.  You must be inside a synchronized (this) block.
16375     */
16376    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16377        if(isDiff) {
16378            SystemProperties.set("user.language", l.getLanguage());
16379            SystemProperties.set("user.region", l.getCountry());
16380        }
16381
16382        if(isPersist) {
16383            SystemProperties.set("persist.sys.language", l.getLanguage());
16384            SystemProperties.set("persist.sys.country", l.getCountry());
16385            SystemProperties.set("persist.sys.localevar", l.getVariant());
16386
16387            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16388        }
16389    }
16390
16391    @Override
16392    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16393        synchronized (this) {
16394            ActivityRecord srec = ActivityRecord.forToken(token);
16395            if (srec.task != null && srec.task.stack != null) {
16396                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16397            }
16398        }
16399        return false;
16400    }
16401
16402    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16403            Intent resultData) {
16404
16405        synchronized (this) {
16406            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16407            if (stack != null) {
16408                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16409            }
16410            return false;
16411        }
16412    }
16413
16414    public int getLaunchedFromUid(IBinder activityToken) {
16415        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16416        if (srec == null) {
16417            return -1;
16418        }
16419        return srec.launchedFromUid;
16420    }
16421
16422    public String getLaunchedFromPackage(IBinder activityToken) {
16423        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16424        if (srec == null) {
16425            return null;
16426        }
16427        return srec.launchedFromPackage;
16428    }
16429
16430    // =========================================================
16431    // LIFETIME MANAGEMENT
16432    // =========================================================
16433
16434    // Returns which broadcast queue the app is the current [or imminent] receiver
16435    // on, or 'null' if the app is not an active broadcast recipient.
16436    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16437        BroadcastRecord r = app.curReceiver;
16438        if (r != null) {
16439            return r.queue;
16440        }
16441
16442        // It's not the current receiver, but it might be starting up to become one
16443        synchronized (this) {
16444            for (BroadcastQueue queue : mBroadcastQueues) {
16445                r = queue.mPendingBroadcast;
16446                if (r != null && r.curApp == app) {
16447                    // found it; report which queue it's in
16448                    return queue;
16449                }
16450            }
16451        }
16452
16453        return null;
16454    }
16455
16456    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16457            boolean doingAll, long now) {
16458        if (mAdjSeq == app.adjSeq) {
16459            // This adjustment has already been computed.
16460            return app.curRawAdj;
16461        }
16462
16463        if (app.thread == null) {
16464            app.adjSeq = mAdjSeq;
16465            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16466            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16467            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16468        }
16469
16470        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16471        app.adjSource = null;
16472        app.adjTarget = null;
16473        app.empty = false;
16474        app.cached = false;
16475
16476        final int activitiesSize = app.activities.size();
16477
16478        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16479            // The max adjustment doesn't allow this app to be anything
16480            // below foreground, so it is not worth doing work for it.
16481            app.adjType = "fixed";
16482            app.adjSeq = mAdjSeq;
16483            app.curRawAdj = app.maxAdj;
16484            app.foregroundActivities = false;
16485            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16486            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16487            // System processes can do UI, and when they do we want to have
16488            // them trim their memory after the user leaves the UI.  To
16489            // facilitate this, here we need to determine whether or not it
16490            // is currently showing UI.
16491            app.systemNoUi = true;
16492            if (app == TOP_APP) {
16493                app.systemNoUi = false;
16494            } else if (activitiesSize > 0) {
16495                for (int j = 0; j < activitiesSize; j++) {
16496                    final ActivityRecord r = app.activities.get(j);
16497                    if (r.visible) {
16498                        app.systemNoUi = false;
16499                    }
16500                }
16501            }
16502            if (!app.systemNoUi) {
16503                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16504            }
16505            return (app.curAdj=app.maxAdj);
16506        }
16507
16508        app.systemNoUi = false;
16509
16510        // Determine the importance of the process, starting with most
16511        // important to least, and assign an appropriate OOM adjustment.
16512        int adj;
16513        int schedGroup;
16514        int procState;
16515        boolean foregroundActivities = false;
16516        BroadcastQueue queue;
16517        if (app == TOP_APP) {
16518            // The last app on the list is the foreground app.
16519            adj = ProcessList.FOREGROUND_APP_ADJ;
16520            schedGroup = Process.THREAD_GROUP_DEFAULT;
16521            app.adjType = "top-activity";
16522            foregroundActivities = true;
16523            procState = ActivityManager.PROCESS_STATE_TOP;
16524        } else if (app.instrumentationClass != null) {
16525            // Don't want to kill running instrumentation.
16526            adj = ProcessList.FOREGROUND_APP_ADJ;
16527            schedGroup = Process.THREAD_GROUP_DEFAULT;
16528            app.adjType = "instrumentation";
16529            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16530        } else if ((queue = isReceivingBroadcast(app)) != null) {
16531            // An app that is currently receiving a broadcast also
16532            // counts as being in the foreground for OOM killer purposes.
16533            // It's placed in a sched group based on the nature of the
16534            // broadcast as reflected by which queue it's active in.
16535            adj = ProcessList.FOREGROUND_APP_ADJ;
16536            schedGroup = (queue == mFgBroadcastQueue)
16537                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16538            app.adjType = "broadcast";
16539            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16540        } else if (app.executingServices.size() > 0) {
16541            // An app that is currently executing a service callback also
16542            // counts as being in the foreground.
16543            adj = ProcessList.FOREGROUND_APP_ADJ;
16544            schedGroup = app.execServicesFg ?
16545                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16546            app.adjType = "exec-service";
16547            procState = ActivityManager.PROCESS_STATE_SERVICE;
16548            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16549        } else {
16550            // As far as we know the process is empty.  We may change our mind later.
16551            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16552            // At this point we don't actually know the adjustment.  Use the cached adj
16553            // value that the caller wants us to.
16554            adj = cachedAdj;
16555            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16556            app.cached = true;
16557            app.empty = true;
16558            app.adjType = "cch-empty";
16559        }
16560
16561        // Examine all activities if not already foreground.
16562        if (!foregroundActivities && activitiesSize > 0) {
16563            for (int j = 0; j < activitiesSize; j++) {
16564                final ActivityRecord r = app.activities.get(j);
16565                if (r.app != app) {
16566                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16567                            + app + "?!?");
16568                    continue;
16569                }
16570                if (r.visible) {
16571                    // App has a visible activity; only upgrade adjustment.
16572                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16573                        adj = ProcessList.VISIBLE_APP_ADJ;
16574                        app.adjType = "visible";
16575                    }
16576                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16577                        procState = ActivityManager.PROCESS_STATE_TOP;
16578                    }
16579                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16580                    app.cached = false;
16581                    app.empty = false;
16582                    foregroundActivities = true;
16583                    break;
16584                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16585                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16586                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16587                        app.adjType = "pausing";
16588                    }
16589                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16590                        procState = ActivityManager.PROCESS_STATE_TOP;
16591                    }
16592                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16593                    app.cached = false;
16594                    app.empty = false;
16595                    foregroundActivities = true;
16596                } else if (r.state == ActivityState.STOPPING) {
16597                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16598                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16599                        app.adjType = "stopping";
16600                    }
16601                    // For the process state, we will at this point consider the
16602                    // process to be cached.  It will be cached either as an activity
16603                    // or empty depending on whether the activity is finishing.  We do
16604                    // this so that we can treat the process as cached for purposes of
16605                    // memory trimming (determing current memory level, trim command to
16606                    // send to process) since there can be an arbitrary number of stopping
16607                    // processes and they should soon all go into the cached state.
16608                    if (!r.finishing) {
16609                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16610                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16611                        }
16612                    }
16613                    app.cached = false;
16614                    app.empty = false;
16615                    foregroundActivities = true;
16616                } else {
16617                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16618                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16619                        app.adjType = "cch-act";
16620                    }
16621                }
16622            }
16623        }
16624
16625        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16626            if (app.foregroundServices) {
16627                // The user is aware of this app, so make it visible.
16628                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16629                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16630                app.cached = false;
16631                app.adjType = "fg-service";
16632                schedGroup = Process.THREAD_GROUP_DEFAULT;
16633            } else if (app.forcingToForeground != null) {
16634                // The user is aware of this app, so make it visible.
16635                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16636                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16637                app.cached = false;
16638                app.adjType = "force-fg";
16639                app.adjSource = app.forcingToForeground;
16640                schedGroup = Process.THREAD_GROUP_DEFAULT;
16641            }
16642        }
16643
16644        if (app == mHeavyWeightProcess) {
16645            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16646                // We don't want to kill the current heavy-weight process.
16647                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16648                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16649                app.cached = false;
16650                app.adjType = "heavy";
16651            }
16652            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16653                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16654            }
16655        }
16656
16657        if (app == mHomeProcess) {
16658            if (adj > ProcessList.HOME_APP_ADJ) {
16659                // This process is hosting what we currently consider to be the
16660                // home app, so we don't want to let it go into the background.
16661                adj = ProcessList.HOME_APP_ADJ;
16662                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16663                app.cached = false;
16664                app.adjType = "home";
16665            }
16666            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16667                procState = ActivityManager.PROCESS_STATE_HOME;
16668            }
16669        }
16670
16671        if (app == mPreviousProcess && app.activities.size() > 0) {
16672            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16673                // This was the previous process that showed UI to the user.
16674                // We want to try to keep it around more aggressively, to give
16675                // a good experience around switching between two apps.
16676                adj = ProcessList.PREVIOUS_APP_ADJ;
16677                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16678                app.cached = false;
16679                app.adjType = "previous";
16680            }
16681            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16682                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16683            }
16684        }
16685
16686        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16687                + " reason=" + app.adjType);
16688
16689        // By default, we use the computed adjustment.  It may be changed if
16690        // there are applications dependent on our services or providers, but
16691        // this gives us a baseline and makes sure we don't get into an
16692        // infinite recursion.
16693        app.adjSeq = mAdjSeq;
16694        app.curRawAdj = adj;
16695        app.hasStartedServices = false;
16696
16697        if (mBackupTarget != null && app == mBackupTarget.app) {
16698            // If possible we want to avoid killing apps while they're being backed up
16699            if (adj > ProcessList.BACKUP_APP_ADJ) {
16700                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16701                adj = ProcessList.BACKUP_APP_ADJ;
16702                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16703                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16704                }
16705                app.adjType = "backup";
16706                app.cached = false;
16707            }
16708            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16709                procState = ActivityManager.PROCESS_STATE_BACKUP;
16710            }
16711        }
16712
16713        boolean mayBeTop = false;
16714
16715        for (int is = app.services.size()-1;
16716                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16717                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16718                        || procState > ActivityManager.PROCESS_STATE_TOP);
16719                is--) {
16720            ServiceRecord s = app.services.valueAt(is);
16721            if (s.startRequested) {
16722                app.hasStartedServices = true;
16723                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16724                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16725                }
16726                if (app.hasShownUi && app != mHomeProcess) {
16727                    // If this process has shown some UI, let it immediately
16728                    // go to the LRU list because it may be pretty heavy with
16729                    // UI stuff.  We'll tag it with a label just to help
16730                    // debug and understand what is going on.
16731                    if (adj > ProcessList.SERVICE_ADJ) {
16732                        app.adjType = "cch-started-ui-services";
16733                    }
16734                } else {
16735                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16736                        // This service has seen some activity within
16737                        // recent memory, so we will keep its process ahead
16738                        // of the background processes.
16739                        if (adj > ProcessList.SERVICE_ADJ) {
16740                            adj = ProcessList.SERVICE_ADJ;
16741                            app.adjType = "started-services";
16742                            app.cached = false;
16743                        }
16744                    }
16745                    // If we have let the service slide into the background
16746                    // state, still have some text describing what it is doing
16747                    // even though the service no longer has an impact.
16748                    if (adj > ProcessList.SERVICE_ADJ) {
16749                        app.adjType = "cch-started-services";
16750                    }
16751                }
16752            }
16753            for (int conni = s.connections.size()-1;
16754                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16755                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16756                            || procState > ActivityManager.PROCESS_STATE_TOP);
16757                    conni--) {
16758                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16759                for (int i = 0;
16760                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16761                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16762                                || procState > ActivityManager.PROCESS_STATE_TOP);
16763                        i++) {
16764                    // XXX should compute this based on the max of
16765                    // all connected clients.
16766                    ConnectionRecord cr = clist.get(i);
16767                    if (cr.binding.client == app) {
16768                        // Binding to ourself is not interesting.
16769                        continue;
16770                    }
16771                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16772                        ProcessRecord client = cr.binding.client;
16773                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16774                                TOP_APP, doingAll, now);
16775                        int clientProcState = client.curProcState;
16776                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16777                            // If the other app is cached for any reason, for purposes here
16778                            // we are going to consider it empty.  The specific cached state
16779                            // doesn't propagate except under certain conditions.
16780                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16781                        }
16782                        String adjType = null;
16783                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16784                            // Not doing bind OOM management, so treat
16785                            // this guy more like a started service.
16786                            if (app.hasShownUi && app != mHomeProcess) {
16787                                // If this process has shown some UI, let it immediately
16788                                // go to the LRU list because it may be pretty heavy with
16789                                // UI stuff.  We'll tag it with a label just to help
16790                                // debug and understand what is going on.
16791                                if (adj > clientAdj) {
16792                                    adjType = "cch-bound-ui-services";
16793                                }
16794                                app.cached = false;
16795                                clientAdj = adj;
16796                                clientProcState = procState;
16797                            } else {
16798                                if (now >= (s.lastActivity
16799                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16800                                    // This service has not seen activity within
16801                                    // recent memory, so allow it to drop to the
16802                                    // LRU list if there is no other reason to keep
16803                                    // it around.  We'll also tag it with a label just
16804                                    // to help debug and undertand what is going on.
16805                                    if (adj > clientAdj) {
16806                                        adjType = "cch-bound-services";
16807                                    }
16808                                    clientAdj = adj;
16809                                }
16810                            }
16811                        }
16812                        if (adj > clientAdj) {
16813                            // If this process has recently shown UI, and
16814                            // the process that is binding to it is less
16815                            // important than being visible, then we don't
16816                            // care about the binding as much as we care
16817                            // about letting this process get into the LRU
16818                            // list to be killed and restarted if needed for
16819                            // memory.
16820                            if (app.hasShownUi && app != mHomeProcess
16821                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16822                                adjType = "cch-bound-ui-services";
16823                            } else {
16824                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16825                                        |Context.BIND_IMPORTANT)) != 0) {
16826                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16827                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16828                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16829                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16830                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16831                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16832                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16833                                    adj = clientAdj;
16834                                } else {
16835                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16836                                        adj = ProcessList.VISIBLE_APP_ADJ;
16837                                    }
16838                                }
16839                                if (!client.cached) {
16840                                    app.cached = false;
16841                                }
16842                                adjType = "service";
16843                            }
16844                        }
16845                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16846                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16847                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16848                            }
16849                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16850                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16851                                    // Special handling of clients who are in the top state.
16852                                    // We *may* want to consider this process to be in the
16853                                    // top state as well, but only if there is not another
16854                                    // reason for it to be running.  Being on the top is a
16855                                    // special state, meaning you are specifically running
16856                                    // for the current top app.  If the process is already
16857                                    // running in the background for some other reason, it
16858                                    // is more important to continue considering it to be
16859                                    // in the background state.
16860                                    mayBeTop = true;
16861                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16862                                } else {
16863                                    // Special handling for above-top states (persistent
16864                                    // processes).  These should not bring the current process
16865                                    // into the top state, since they are not on top.  Instead
16866                                    // give them the best state after that.
16867                                    clientProcState =
16868                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16869                                }
16870                            }
16871                        } else {
16872                            if (clientProcState <
16873                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16874                                clientProcState =
16875                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16876                            }
16877                        }
16878                        if (procState > clientProcState) {
16879                            procState = clientProcState;
16880                        }
16881                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16882                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16883                            app.pendingUiClean = true;
16884                        }
16885                        if (adjType != null) {
16886                            app.adjType = adjType;
16887                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16888                                    .REASON_SERVICE_IN_USE;
16889                            app.adjSource = cr.binding.client;
16890                            app.adjSourceProcState = clientProcState;
16891                            app.adjTarget = s.name;
16892                        }
16893                    }
16894                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16895                        app.treatLikeActivity = true;
16896                    }
16897                    final ActivityRecord a = cr.activity;
16898                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16899                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16900                                (a.visible || a.state == ActivityState.RESUMED
16901                                 || a.state == ActivityState.PAUSING)) {
16902                            adj = ProcessList.FOREGROUND_APP_ADJ;
16903                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16904                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16905                            }
16906                            app.cached = false;
16907                            app.adjType = "service";
16908                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16909                                    .REASON_SERVICE_IN_USE;
16910                            app.adjSource = a;
16911                            app.adjSourceProcState = procState;
16912                            app.adjTarget = s.name;
16913                        }
16914                    }
16915                }
16916            }
16917        }
16918
16919        for (int provi = app.pubProviders.size()-1;
16920                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16921                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16922                        || procState > ActivityManager.PROCESS_STATE_TOP);
16923                provi--) {
16924            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16925            for (int i = cpr.connections.size()-1;
16926                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16927                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16928                            || procState > ActivityManager.PROCESS_STATE_TOP);
16929                    i--) {
16930                ContentProviderConnection conn = cpr.connections.get(i);
16931                ProcessRecord client = conn.client;
16932                if (client == app) {
16933                    // Being our own client is not interesting.
16934                    continue;
16935                }
16936                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16937                int clientProcState = client.curProcState;
16938                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16939                    // If the other app is cached for any reason, for purposes here
16940                    // we are going to consider it empty.
16941                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16942                }
16943                if (adj > clientAdj) {
16944                    if (app.hasShownUi && app != mHomeProcess
16945                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16946                        app.adjType = "cch-ui-provider";
16947                    } else {
16948                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16949                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16950                        app.adjType = "provider";
16951                    }
16952                    app.cached &= client.cached;
16953                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16954                            .REASON_PROVIDER_IN_USE;
16955                    app.adjSource = client;
16956                    app.adjSourceProcState = clientProcState;
16957                    app.adjTarget = cpr.name;
16958                }
16959                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16960                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16961                        // Special handling of clients who are in the top state.
16962                        // We *may* want to consider this process to be in the
16963                        // top state as well, but only if there is not another
16964                        // reason for it to be running.  Being on the top is a
16965                        // special state, meaning you are specifically running
16966                        // for the current top app.  If the process is already
16967                        // running in the background for some other reason, it
16968                        // is more important to continue considering it to be
16969                        // in the background state.
16970                        mayBeTop = true;
16971                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16972                    } else {
16973                        // Special handling for above-top states (persistent
16974                        // processes).  These should not bring the current process
16975                        // into the top state, since they are not on top.  Instead
16976                        // give them the best state after that.
16977                        clientProcState =
16978                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16979                    }
16980                }
16981                if (procState > clientProcState) {
16982                    procState = clientProcState;
16983                }
16984                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16985                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16986                }
16987            }
16988            // If the provider has external (non-framework) process
16989            // dependencies, ensure that its adjustment is at least
16990            // FOREGROUND_APP_ADJ.
16991            if (cpr.hasExternalProcessHandles()) {
16992                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16993                    adj = ProcessList.FOREGROUND_APP_ADJ;
16994                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16995                    app.cached = false;
16996                    app.adjType = "provider";
16997                    app.adjTarget = cpr.name;
16998                }
16999                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17000                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17001                }
17002            }
17003        }
17004
17005        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17006            // A client of one of our services or providers is in the top state.  We
17007            // *may* want to be in the top state, but not if we are already running in
17008            // the background for some other reason.  For the decision here, we are going
17009            // to pick out a few specific states that we want to remain in when a client
17010            // is top (states that tend to be longer-term) and otherwise allow it to go
17011            // to the top state.
17012            switch (procState) {
17013                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17014                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17015                case ActivityManager.PROCESS_STATE_SERVICE:
17016                    // These all are longer-term states, so pull them up to the top
17017                    // of the background states, but not all the way to the top state.
17018                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17019                    break;
17020                default:
17021                    // Otherwise, top is a better choice, so take it.
17022                    procState = ActivityManager.PROCESS_STATE_TOP;
17023                    break;
17024            }
17025        }
17026
17027        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17028            if (app.hasClientActivities) {
17029                // This is a cached process, but with client activities.  Mark it so.
17030                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17031                app.adjType = "cch-client-act";
17032            } else if (app.treatLikeActivity) {
17033                // This is a cached process, but somebody wants us to treat it like it has
17034                // an activity, okay!
17035                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17036                app.adjType = "cch-as-act";
17037            }
17038        }
17039
17040        if (adj == ProcessList.SERVICE_ADJ) {
17041            if (doingAll) {
17042                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17043                mNewNumServiceProcs++;
17044                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17045                if (!app.serviceb) {
17046                    // This service isn't far enough down on the LRU list to
17047                    // normally be a B service, but if we are low on RAM and it
17048                    // is large we want to force it down since we would prefer to
17049                    // keep launcher over it.
17050                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17051                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17052                        app.serviceHighRam = true;
17053                        app.serviceb = true;
17054                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17055                    } else {
17056                        mNewNumAServiceProcs++;
17057                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17058                    }
17059                } else {
17060                    app.serviceHighRam = false;
17061                }
17062            }
17063            if (app.serviceb) {
17064                adj = ProcessList.SERVICE_B_ADJ;
17065            }
17066        }
17067
17068        app.curRawAdj = adj;
17069
17070        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17071        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17072        if (adj > app.maxAdj) {
17073            adj = app.maxAdj;
17074            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17075                schedGroup = Process.THREAD_GROUP_DEFAULT;
17076            }
17077        }
17078
17079        // Do final modification to adj.  Everything we do between here and applying
17080        // the final setAdj must be done in this function, because we will also use
17081        // it when computing the final cached adj later.  Note that we don't need to
17082        // worry about this for max adj above, since max adj will always be used to
17083        // keep it out of the cached vaues.
17084        app.curAdj = app.modifyRawOomAdj(adj);
17085        app.curSchedGroup = schedGroup;
17086        app.curProcState = procState;
17087        app.foregroundActivities = foregroundActivities;
17088
17089        return app.curRawAdj;
17090    }
17091
17092    /**
17093     * Schedule PSS collection of a process.
17094     */
17095    void requestPssLocked(ProcessRecord proc, int procState) {
17096        if (mPendingPssProcesses.contains(proc)) {
17097            return;
17098        }
17099        if (mPendingPssProcesses.size() == 0) {
17100            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17101        }
17102        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17103        proc.pssProcState = procState;
17104        mPendingPssProcesses.add(proc);
17105    }
17106
17107    /**
17108     * Schedule PSS collection of all processes.
17109     */
17110    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17111        if (!always) {
17112            if (now < (mLastFullPssTime +
17113                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17114                return;
17115            }
17116        }
17117        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17118        mLastFullPssTime = now;
17119        mFullPssPending = true;
17120        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17121        mPendingPssProcesses.clear();
17122        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17123            ProcessRecord app = mLruProcesses.get(i);
17124            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17125                app.pssProcState = app.setProcState;
17126                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17127                        isSleeping(), now);
17128                mPendingPssProcesses.add(app);
17129            }
17130        }
17131        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17132    }
17133
17134    /**
17135     * Ask a given process to GC right now.
17136     */
17137    final void performAppGcLocked(ProcessRecord app) {
17138        try {
17139            app.lastRequestedGc = SystemClock.uptimeMillis();
17140            if (app.thread != null) {
17141                if (app.reportLowMemory) {
17142                    app.reportLowMemory = false;
17143                    app.thread.scheduleLowMemory();
17144                } else {
17145                    app.thread.processInBackground();
17146                }
17147            }
17148        } catch (Exception e) {
17149            // whatever.
17150        }
17151    }
17152
17153    /**
17154     * Returns true if things are idle enough to perform GCs.
17155     */
17156    private final boolean canGcNowLocked() {
17157        boolean processingBroadcasts = false;
17158        for (BroadcastQueue q : mBroadcastQueues) {
17159            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17160                processingBroadcasts = true;
17161            }
17162        }
17163        return !processingBroadcasts
17164                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17165    }
17166
17167    /**
17168     * Perform GCs on all processes that are waiting for it, but only
17169     * if things are idle.
17170     */
17171    final void performAppGcsLocked() {
17172        final int N = mProcessesToGc.size();
17173        if (N <= 0) {
17174            return;
17175        }
17176        if (canGcNowLocked()) {
17177            while (mProcessesToGc.size() > 0) {
17178                ProcessRecord proc = mProcessesToGc.remove(0);
17179                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17180                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17181                            <= SystemClock.uptimeMillis()) {
17182                        // To avoid spamming the system, we will GC processes one
17183                        // at a time, waiting a few seconds between each.
17184                        performAppGcLocked(proc);
17185                        scheduleAppGcsLocked();
17186                        return;
17187                    } else {
17188                        // It hasn't been long enough since we last GCed this
17189                        // process...  put it in the list to wait for its time.
17190                        addProcessToGcListLocked(proc);
17191                        break;
17192                    }
17193                }
17194            }
17195
17196            scheduleAppGcsLocked();
17197        }
17198    }
17199
17200    /**
17201     * If all looks good, perform GCs on all processes waiting for them.
17202     */
17203    final void performAppGcsIfAppropriateLocked() {
17204        if (canGcNowLocked()) {
17205            performAppGcsLocked();
17206            return;
17207        }
17208        // Still not idle, wait some more.
17209        scheduleAppGcsLocked();
17210    }
17211
17212    /**
17213     * Schedule the execution of all pending app GCs.
17214     */
17215    final void scheduleAppGcsLocked() {
17216        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17217
17218        if (mProcessesToGc.size() > 0) {
17219            // Schedule a GC for the time to the next process.
17220            ProcessRecord proc = mProcessesToGc.get(0);
17221            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17222
17223            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17224            long now = SystemClock.uptimeMillis();
17225            if (when < (now+GC_TIMEOUT)) {
17226                when = now + GC_TIMEOUT;
17227            }
17228            mHandler.sendMessageAtTime(msg, when);
17229        }
17230    }
17231
17232    /**
17233     * Add a process to the array of processes waiting to be GCed.  Keeps the
17234     * list in sorted order by the last GC time.  The process can't already be
17235     * on the list.
17236     */
17237    final void addProcessToGcListLocked(ProcessRecord proc) {
17238        boolean added = false;
17239        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17240            if (mProcessesToGc.get(i).lastRequestedGc <
17241                    proc.lastRequestedGc) {
17242                added = true;
17243                mProcessesToGc.add(i+1, proc);
17244                break;
17245            }
17246        }
17247        if (!added) {
17248            mProcessesToGc.add(0, proc);
17249        }
17250    }
17251
17252    /**
17253     * Set up to ask a process to GC itself.  This will either do it
17254     * immediately, or put it on the list of processes to gc the next
17255     * time things are idle.
17256     */
17257    final void scheduleAppGcLocked(ProcessRecord app) {
17258        long now = SystemClock.uptimeMillis();
17259        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17260            return;
17261        }
17262        if (!mProcessesToGc.contains(app)) {
17263            addProcessToGcListLocked(app);
17264            scheduleAppGcsLocked();
17265        }
17266    }
17267
17268    final void checkExcessivePowerUsageLocked(boolean doKills) {
17269        updateCpuStatsNow();
17270
17271        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17272        boolean doWakeKills = doKills;
17273        boolean doCpuKills = doKills;
17274        if (mLastPowerCheckRealtime == 0) {
17275            doWakeKills = false;
17276        }
17277        if (mLastPowerCheckUptime == 0) {
17278            doCpuKills = false;
17279        }
17280        if (stats.isScreenOn()) {
17281            doWakeKills = false;
17282        }
17283        final long curRealtime = SystemClock.elapsedRealtime();
17284        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17285        final long curUptime = SystemClock.uptimeMillis();
17286        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17287        mLastPowerCheckRealtime = curRealtime;
17288        mLastPowerCheckUptime = curUptime;
17289        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17290            doWakeKills = false;
17291        }
17292        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17293            doCpuKills = false;
17294        }
17295        int i = mLruProcesses.size();
17296        while (i > 0) {
17297            i--;
17298            ProcessRecord app = mLruProcesses.get(i);
17299            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17300                long wtime;
17301                synchronized (stats) {
17302                    wtime = stats.getProcessWakeTime(app.info.uid,
17303                            app.pid, curRealtime);
17304                }
17305                long wtimeUsed = wtime - app.lastWakeTime;
17306                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17307                if (DEBUG_POWER) {
17308                    StringBuilder sb = new StringBuilder(128);
17309                    sb.append("Wake for ");
17310                    app.toShortString(sb);
17311                    sb.append(": over ");
17312                    TimeUtils.formatDuration(realtimeSince, sb);
17313                    sb.append(" used ");
17314                    TimeUtils.formatDuration(wtimeUsed, sb);
17315                    sb.append(" (");
17316                    sb.append((wtimeUsed*100)/realtimeSince);
17317                    sb.append("%)");
17318                    Slog.i(TAG, sb.toString());
17319                    sb.setLength(0);
17320                    sb.append("CPU for ");
17321                    app.toShortString(sb);
17322                    sb.append(": over ");
17323                    TimeUtils.formatDuration(uptimeSince, sb);
17324                    sb.append(" used ");
17325                    TimeUtils.formatDuration(cputimeUsed, sb);
17326                    sb.append(" (");
17327                    sb.append((cputimeUsed*100)/uptimeSince);
17328                    sb.append("%)");
17329                    Slog.i(TAG, sb.toString());
17330                }
17331                // If a process has held a wake lock for more
17332                // than 50% of the time during this period,
17333                // that sounds bad.  Kill!
17334                if (doWakeKills && realtimeSince > 0
17335                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17336                    synchronized (stats) {
17337                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17338                                realtimeSince, wtimeUsed);
17339                    }
17340                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17341                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17342                } else if (doCpuKills && uptimeSince > 0
17343                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17344                    synchronized (stats) {
17345                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17346                                uptimeSince, cputimeUsed);
17347                    }
17348                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17349                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17350                } else {
17351                    app.lastWakeTime = wtime;
17352                    app.lastCpuTime = app.curCpuTime;
17353                }
17354            }
17355        }
17356    }
17357
17358    private final boolean applyOomAdjLocked(ProcessRecord app,
17359            ProcessRecord TOP_APP, boolean doingAll, long now) {
17360        boolean success = true;
17361
17362        if (app.curRawAdj != app.setRawAdj) {
17363            app.setRawAdj = app.curRawAdj;
17364        }
17365
17366        int changes = 0;
17367
17368        if (app.curAdj != app.setAdj) {
17369            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17370            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17371                TAG, "Set " + app.pid + " " + app.processName +
17372                " adj " + app.curAdj + ": " + app.adjType);
17373            app.setAdj = app.curAdj;
17374        }
17375
17376        if (app.setSchedGroup != app.curSchedGroup) {
17377            app.setSchedGroup = app.curSchedGroup;
17378            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17379                    "Setting process group of " + app.processName
17380                    + " to " + app.curSchedGroup);
17381            if (app.waitingToKill != null &&
17382                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17383                app.kill(app.waitingToKill, true);
17384                success = false;
17385            } else {
17386                if (true) {
17387                    long oldId = Binder.clearCallingIdentity();
17388                    try {
17389                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17390                    } catch (Exception e) {
17391                        Slog.w(TAG, "Failed setting process group of " + app.pid
17392                                + " to " + app.curSchedGroup);
17393                        e.printStackTrace();
17394                    } finally {
17395                        Binder.restoreCallingIdentity(oldId);
17396                    }
17397                } else {
17398                    if (app.thread != null) {
17399                        try {
17400                            app.thread.setSchedulingGroup(app.curSchedGroup);
17401                        } catch (RemoteException e) {
17402                        }
17403                    }
17404                }
17405                Process.setSwappiness(app.pid,
17406                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17407            }
17408        }
17409        if (app.repForegroundActivities != app.foregroundActivities) {
17410            app.repForegroundActivities = app.foregroundActivities;
17411            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17412        }
17413        if (app.repProcState != app.curProcState) {
17414            app.repProcState = app.curProcState;
17415            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17416            if (app.thread != null) {
17417                try {
17418                    if (false) {
17419                        //RuntimeException h = new RuntimeException("here");
17420                        Slog.i(TAG, "Sending new process state " + app.repProcState
17421                                + " to " + app /*, h*/);
17422                    }
17423                    app.thread.setProcessState(app.repProcState);
17424                } catch (RemoteException e) {
17425                }
17426            }
17427        }
17428        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17429                app.setProcState)) {
17430            app.lastStateTime = now;
17431            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17432                    isSleeping(), now);
17433            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17434                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17435                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17436                    + (app.nextPssTime-now) + ": " + app);
17437        } else {
17438            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17439                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17440                requestPssLocked(app, app.setProcState);
17441                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17442                        isSleeping(), now);
17443            } else if (false && DEBUG_PSS) {
17444                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17445            }
17446        }
17447        if (app.setProcState != app.curProcState) {
17448            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17449                    "Proc state change of " + app.processName
17450                    + " to " + app.curProcState);
17451            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17452            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17453            if (setImportant && !curImportant) {
17454                // This app is no longer something we consider important enough to allow to
17455                // use arbitrary amounts of battery power.  Note
17456                // its current wake lock time to later know to kill it if
17457                // it is not behaving well.
17458                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17459                synchronized (stats) {
17460                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17461                            app.pid, SystemClock.elapsedRealtime());
17462                }
17463                app.lastCpuTime = app.curCpuTime;
17464
17465            }
17466            app.setProcState = app.curProcState;
17467            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17468                app.notCachedSinceIdle = false;
17469            }
17470            if (!doingAll) {
17471                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17472            } else {
17473                app.procStateChanged = true;
17474            }
17475        }
17476
17477        if (changes != 0) {
17478            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17479            int i = mPendingProcessChanges.size()-1;
17480            ProcessChangeItem item = null;
17481            while (i >= 0) {
17482                item = mPendingProcessChanges.get(i);
17483                if (item.pid == app.pid) {
17484                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17485                    break;
17486                }
17487                i--;
17488            }
17489            if (i < 0) {
17490                // No existing item in pending changes; need a new one.
17491                final int NA = mAvailProcessChanges.size();
17492                if (NA > 0) {
17493                    item = mAvailProcessChanges.remove(NA-1);
17494                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17495                } else {
17496                    item = new ProcessChangeItem();
17497                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17498                }
17499                item.changes = 0;
17500                item.pid = app.pid;
17501                item.uid = app.info.uid;
17502                if (mPendingProcessChanges.size() == 0) {
17503                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17504                            "*** Enqueueing dispatch processes changed!");
17505                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17506                }
17507                mPendingProcessChanges.add(item);
17508            }
17509            item.changes |= changes;
17510            item.processState = app.repProcState;
17511            item.foregroundActivities = app.repForegroundActivities;
17512            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17513                    + Integer.toHexString(System.identityHashCode(item))
17514                    + " " + app.toShortString() + ": changes=" + item.changes
17515                    + " procState=" + item.processState
17516                    + " foreground=" + item.foregroundActivities
17517                    + " type=" + app.adjType + " source=" + app.adjSource
17518                    + " target=" + app.adjTarget);
17519        }
17520
17521        return success;
17522    }
17523
17524    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17525        if (proc.thread != null) {
17526            if (proc.baseProcessTracker != null) {
17527                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17528            }
17529            if (proc.repProcState >= 0) {
17530                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17531                        proc.repProcState);
17532            }
17533        }
17534    }
17535
17536    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17537            ProcessRecord TOP_APP, boolean doingAll, long now) {
17538        if (app.thread == null) {
17539            return false;
17540        }
17541
17542        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17543
17544        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17545    }
17546
17547    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17548            boolean oomAdj) {
17549        if (isForeground != proc.foregroundServices) {
17550            proc.foregroundServices = isForeground;
17551            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17552                    proc.info.uid);
17553            if (isForeground) {
17554                if (curProcs == null) {
17555                    curProcs = new ArrayList<ProcessRecord>();
17556                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17557                }
17558                if (!curProcs.contains(proc)) {
17559                    curProcs.add(proc);
17560                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17561                            proc.info.packageName, proc.info.uid);
17562                }
17563            } else {
17564                if (curProcs != null) {
17565                    if (curProcs.remove(proc)) {
17566                        mBatteryStatsService.noteEvent(
17567                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17568                                proc.info.packageName, proc.info.uid);
17569                        if (curProcs.size() <= 0) {
17570                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17571                        }
17572                    }
17573                }
17574            }
17575            if (oomAdj) {
17576                updateOomAdjLocked();
17577            }
17578        }
17579    }
17580
17581    private final ActivityRecord resumedAppLocked() {
17582        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17583        String pkg;
17584        int uid;
17585        if (act != null) {
17586            pkg = act.packageName;
17587            uid = act.info.applicationInfo.uid;
17588        } else {
17589            pkg = null;
17590            uid = -1;
17591        }
17592        // Has the UID or resumed package name changed?
17593        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17594                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17595            if (mCurResumedPackage != null) {
17596                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17597                        mCurResumedPackage, mCurResumedUid);
17598            }
17599            mCurResumedPackage = pkg;
17600            mCurResumedUid = uid;
17601            if (mCurResumedPackage != null) {
17602                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17603                        mCurResumedPackage, mCurResumedUid);
17604            }
17605        }
17606        return act;
17607    }
17608
17609    final boolean updateOomAdjLocked(ProcessRecord app) {
17610        final ActivityRecord TOP_ACT = resumedAppLocked();
17611        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17612        final boolean wasCached = app.cached;
17613
17614        mAdjSeq++;
17615
17616        // This is the desired cached adjusment we want to tell it to use.
17617        // If our app is currently cached, we know it, and that is it.  Otherwise,
17618        // we don't know it yet, and it needs to now be cached we will then
17619        // need to do a complete oom adj.
17620        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17621                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17622        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17623                SystemClock.uptimeMillis());
17624        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17625            // Changed to/from cached state, so apps after it in the LRU
17626            // list may also be changed.
17627            updateOomAdjLocked();
17628        }
17629        return success;
17630    }
17631
17632    final void updateOomAdjLocked() {
17633        final ActivityRecord TOP_ACT = resumedAppLocked();
17634        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17635        final long now = SystemClock.uptimeMillis();
17636        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17637        final int N = mLruProcesses.size();
17638
17639        if (false) {
17640            RuntimeException e = new RuntimeException();
17641            e.fillInStackTrace();
17642            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17643        }
17644
17645        mAdjSeq++;
17646        mNewNumServiceProcs = 0;
17647        mNewNumAServiceProcs = 0;
17648
17649        final int emptyProcessLimit;
17650        final int cachedProcessLimit;
17651        if (mProcessLimit <= 0) {
17652            emptyProcessLimit = cachedProcessLimit = 0;
17653        } else if (mProcessLimit == 1) {
17654            emptyProcessLimit = 1;
17655            cachedProcessLimit = 0;
17656        } else {
17657            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17658            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17659        }
17660
17661        // Let's determine how many processes we have running vs.
17662        // how many slots we have for background processes; we may want
17663        // to put multiple processes in a slot of there are enough of
17664        // them.
17665        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17666                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17667        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17668        if (numEmptyProcs > cachedProcessLimit) {
17669            // If there are more empty processes than our limit on cached
17670            // processes, then use the cached process limit for the factor.
17671            // This ensures that the really old empty processes get pushed
17672            // down to the bottom, so if we are running low on memory we will
17673            // have a better chance at keeping around more cached processes
17674            // instead of a gazillion empty processes.
17675            numEmptyProcs = cachedProcessLimit;
17676        }
17677        int emptyFactor = numEmptyProcs/numSlots;
17678        if (emptyFactor < 1) emptyFactor = 1;
17679        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17680        if (cachedFactor < 1) cachedFactor = 1;
17681        int stepCached = 0;
17682        int stepEmpty = 0;
17683        int numCached = 0;
17684        int numEmpty = 0;
17685        int numTrimming = 0;
17686
17687        mNumNonCachedProcs = 0;
17688        mNumCachedHiddenProcs = 0;
17689
17690        // First update the OOM adjustment for each of the
17691        // application processes based on their current state.
17692        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17693        int nextCachedAdj = curCachedAdj+1;
17694        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17695        int nextEmptyAdj = curEmptyAdj+2;
17696        for (int i=N-1; i>=0; i--) {
17697            ProcessRecord app = mLruProcesses.get(i);
17698            if (!app.killedByAm && app.thread != null) {
17699                app.procStateChanged = false;
17700                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17701
17702                // If we haven't yet assigned the final cached adj
17703                // to the process, do that now.
17704                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17705                    switch (app.curProcState) {
17706                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17707                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17708                            // This process is a cached process holding activities...
17709                            // assign it the next cached value for that type, and then
17710                            // step that cached level.
17711                            app.curRawAdj = curCachedAdj;
17712                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17713                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17714                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17715                                    + ")");
17716                            if (curCachedAdj != nextCachedAdj) {
17717                                stepCached++;
17718                                if (stepCached >= cachedFactor) {
17719                                    stepCached = 0;
17720                                    curCachedAdj = nextCachedAdj;
17721                                    nextCachedAdj += 2;
17722                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17723                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17724                                    }
17725                                }
17726                            }
17727                            break;
17728                        default:
17729                            // For everything else, assign next empty cached process
17730                            // level and bump that up.  Note that this means that
17731                            // long-running services that have dropped down to the
17732                            // cached level will be treated as empty (since their process
17733                            // state is still as a service), which is what we want.
17734                            app.curRawAdj = curEmptyAdj;
17735                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17736                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17737                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17738                                    + ")");
17739                            if (curEmptyAdj != nextEmptyAdj) {
17740                                stepEmpty++;
17741                                if (stepEmpty >= emptyFactor) {
17742                                    stepEmpty = 0;
17743                                    curEmptyAdj = nextEmptyAdj;
17744                                    nextEmptyAdj += 2;
17745                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17746                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17747                                    }
17748                                }
17749                            }
17750                            break;
17751                    }
17752                }
17753
17754                applyOomAdjLocked(app, TOP_APP, true, now);
17755
17756                // Count the number of process types.
17757                switch (app.curProcState) {
17758                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17759                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17760                        mNumCachedHiddenProcs++;
17761                        numCached++;
17762                        if (numCached > cachedProcessLimit) {
17763                            app.kill("cached #" + numCached, true);
17764                        }
17765                        break;
17766                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17767                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17768                                && app.lastActivityTime < oldTime) {
17769                            app.kill("empty for "
17770                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17771                                    / 1000) + "s", true);
17772                        } else {
17773                            numEmpty++;
17774                            if (numEmpty > emptyProcessLimit) {
17775                                app.kill("empty #" + numEmpty, true);
17776                            }
17777                        }
17778                        break;
17779                    default:
17780                        mNumNonCachedProcs++;
17781                        break;
17782                }
17783
17784                if (app.isolated && app.services.size() <= 0) {
17785                    // If this is an isolated process, and there are no
17786                    // services running in it, then the process is no longer
17787                    // needed.  We agressively kill these because we can by
17788                    // definition not re-use the same process again, and it is
17789                    // good to avoid having whatever code was running in them
17790                    // left sitting around after no longer needed.
17791                    app.kill("isolated not needed", true);
17792                }
17793
17794                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17795                        && !app.killedByAm) {
17796                    numTrimming++;
17797                }
17798            }
17799        }
17800
17801        mNumServiceProcs = mNewNumServiceProcs;
17802
17803        // Now determine the memory trimming level of background processes.
17804        // Unfortunately we need to start at the back of the list to do this
17805        // properly.  We only do this if the number of background apps we
17806        // are managing to keep around is less than half the maximum we desire;
17807        // if we are keeping a good number around, we'll let them use whatever
17808        // memory they want.
17809        final int numCachedAndEmpty = numCached + numEmpty;
17810        int memFactor;
17811        if (numCached <= ProcessList.TRIM_CACHED_APPS
17812                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17813            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17814                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17815            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17816                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17817            } else {
17818                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17819            }
17820        } else {
17821            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17822        }
17823        // We always allow the memory level to go up (better).  We only allow it to go
17824        // down if we are in a state where that is allowed, *and* the total number of processes
17825        // has gone down since last time.
17826        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17827                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17828                + " last=" + mLastNumProcesses);
17829        if (memFactor > mLastMemoryLevel) {
17830            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17831                memFactor = mLastMemoryLevel;
17832                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17833            }
17834        }
17835        mLastMemoryLevel = memFactor;
17836        mLastNumProcesses = mLruProcesses.size();
17837        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17838        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17839        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17840            if (mLowRamStartTime == 0) {
17841                mLowRamStartTime = now;
17842            }
17843            int step = 0;
17844            int fgTrimLevel;
17845            switch (memFactor) {
17846                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17847                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17848                    break;
17849                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17850                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17851                    break;
17852                default:
17853                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17854                    break;
17855            }
17856            int factor = numTrimming/3;
17857            int minFactor = 2;
17858            if (mHomeProcess != null) minFactor++;
17859            if (mPreviousProcess != null) minFactor++;
17860            if (factor < minFactor) factor = minFactor;
17861            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17862            for (int i=N-1; i>=0; i--) {
17863                ProcessRecord app = mLruProcesses.get(i);
17864                if (allChanged || app.procStateChanged) {
17865                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17866                    app.procStateChanged = false;
17867                }
17868                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17869                        && !app.killedByAm) {
17870                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17871                        try {
17872                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17873                                    "Trimming memory of " + app.processName
17874                                    + " to " + curLevel);
17875                            app.thread.scheduleTrimMemory(curLevel);
17876                        } catch (RemoteException e) {
17877                        }
17878                        if (false) {
17879                            // For now we won't do this; our memory trimming seems
17880                            // to be good enough at this point that destroying
17881                            // activities causes more harm than good.
17882                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17883                                    && app != mHomeProcess && app != mPreviousProcess) {
17884                                // Need to do this on its own message because the stack may not
17885                                // be in a consistent state at this point.
17886                                // For these apps we will also finish their activities
17887                                // to help them free memory.
17888                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17889                            }
17890                        }
17891                    }
17892                    app.trimMemoryLevel = curLevel;
17893                    step++;
17894                    if (step >= factor) {
17895                        step = 0;
17896                        switch (curLevel) {
17897                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17898                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17899                                break;
17900                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17901                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17902                                break;
17903                        }
17904                    }
17905                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17906                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17907                            && app.thread != null) {
17908                        try {
17909                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17910                                    "Trimming memory of heavy-weight " + app.processName
17911                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17912                            app.thread.scheduleTrimMemory(
17913                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17914                        } catch (RemoteException e) {
17915                        }
17916                    }
17917                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17918                } else {
17919                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17920                            || app.systemNoUi) && app.pendingUiClean) {
17921                        // If this application is now in the background and it
17922                        // had done UI, then give it the special trim level to
17923                        // have it free UI resources.
17924                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17925                        if (app.trimMemoryLevel < level && app.thread != null) {
17926                            try {
17927                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17928                                        "Trimming memory of bg-ui " + app.processName
17929                                        + " to " + level);
17930                                app.thread.scheduleTrimMemory(level);
17931                            } catch (RemoteException e) {
17932                            }
17933                        }
17934                        app.pendingUiClean = false;
17935                    }
17936                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17937                        try {
17938                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17939                                    "Trimming memory of fg " + app.processName
17940                                    + " to " + fgTrimLevel);
17941                            app.thread.scheduleTrimMemory(fgTrimLevel);
17942                        } catch (RemoteException e) {
17943                        }
17944                    }
17945                    app.trimMemoryLevel = fgTrimLevel;
17946                }
17947            }
17948        } else {
17949            if (mLowRamStartTime != 0) {
17950                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17951                mLowRamStartTime = 0;
17952            }
17953            for (int i=N-1; i>=0; i--) {
17954                ProcessRecord app = mLruProcesses.get(i);
17955                if (allChanged || app.procStateChanged) {
17956                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17957                    app.procStateChanged = false;
17958                }
17959                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17960                        || app.systemNoUi) && app.pendingUiClean) {
17961                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17962                            && app.thread != null) {
17963                        try {
17964                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17965                                    "Trimming memory of ui hidden " + app.processName
17966                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17967                            app.thread.scheduleTrimMemory(
17968                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17969                        } catch (RemoteException e) {
17970                        }
17971                    }
17972                    app.pendingUiClean = false;
17973                }
17974                app.trimMemoryLevel = 0;
17975            }
17976        }
17977
17978        if (mAlwaysFinishActivities) {
17979            // Need to do this on its own message because the stack may not
17980            // be in a consistent state at this point.
17981            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17982        }
17983
17984        if (allChanged) {
17985            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17986        }
17987
17988        if (mProcessStats.shouldWriteNowLocked(now)) {
17989            mHandler.post(new Runnable() {
17990                @Override public void run() {
17991                    synchronized (ActivityManagerService.this) {
17992                        mProcessStats.writeStateAsyncLocked();
17993                    }
17994                }
17995            });
17996        }
17997
17998        if (DEBUG_OOM_ADJ) {
17999            if (false) {
18000                RuntimeException here = new RuntimeException("here");
18001                here.fillInStackTrace();
18002                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18003            } else {
18004                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18005            }
18006        }
18007    }
18008
18009    final void trimApplications() {
18010        synchronized (this) {
18011            int i;
18012
18013            // First remove any unused application processes whose package
18014            // has been removed.
18015            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18016                final ProcessRecord app = mRemovedProcesses.get(i);
18017                if (app.activities.size() == 0
18018                        && app.curReceiver == null && app.services.size() == 0) {
18019                    Slog.i(
18020                        TAG, "Exiting empty application process "
18021                        + app.processName + " ("
18022                        + (app.thread != null ? app.thread.asBinder() : null)
18023                        + ")\n");
18024                    if (app.pid > 0 && app.pid != MY_PID) {
18025                        app.kill("empty", false);
18026                    } else {
18027                        try {
18028                            app.thread.scheduleExit();
18029                        } catch (Exception e) {
18030                            // Ignore exceptions.
18031                        }
18032                    }
18033                    cleanUpApplicationRecordLocked(app, false, true, -1);
18034                    mRemovedProcesses.remove(i);
18035
18036                    if (app.persistent) {
18037                        addAppLocked(app.info, false, null /* ABI override */);
18038                    }
18039                }
18040            }
18041
18042            // Now update the oom adj for all processes.
18043            updateOomAdjLocked();
18044        }
18045    }
18046
18047    /** This method sends the specified signal to each of the persistent apps */
18048    public void signalPersistentProcesses(int sig) throws RemoteException {
18049        if (sig != Process.SIGNAL_USR1) {
18050            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18051        }
18052
18053        synchronized (this) {
18054            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18055                    != PackageManager.PERMISSION_GRANTED) {
18056                throw new SecurityException("Requires permission "
18057                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18058            }
18059
18060            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18061                ProcessRecord r = mLruProcesses.get(i);
18062                if (r.thread != null && r.persistent) {
18063                    Process.sendSignal(r.pid, sig);
18064                }
18065            }
18066        }
18067    }
18068
18069    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18070        if (proc == null || proc == mProfileProc) {
18071            proc = mProfileProc;
18072            profileType = mProfileType;
18073            clearProfilerLocked();
18074        }
18075        if (proc == null) {
18076            return;
18077        }
18078        try {
18079            proc.thread.profilerControl(false, null, profileType);
18080        } catch (RemoteException e) {
18081            throw new IllegalStateException("Process disappeared");
18082        }
18083    }
18084
18085    private void clearProfilerLocked() {
18086        if (mProfileFd != null) {
18087            try {
18088                mProfileFd.close();
18089            } catch (IOException e) {
18090            }
18091        }
18092        mProfileApp = null;
18093        mProfileProc = null;
18094        mProfileFile = null;
18095        mProfileType = 0;
18096        mAutoStopProfiler = false;
18097        mSamplingInterval = 0;
18098    }
18099
18100    public boolean profileControl(String process, int userId, boolean start,
18101            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18102
18103        try {
18104            synchronized (this) {
18105                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18106                // its own permission.
18107                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18108                        != PackageManager.PERMISSION_GRANTED) {
18109                    throw new SecurityException("Requires permission "
18110                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18111                }
18112
18113                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18114                    throw new IllegalArgumentException("null profile info or fd");
18115                }
18116
18117                ProcessRecord proc = null;
18118                if (process != null) {
18119                    proc = findProcessLocked(process, userId, "profileControl");
18120                }
18121
18122                if (start && (proc == null || proc.thread == null)) {
18123                    throw new IllegalArgumentException("Unknown process: " + process);
18124                }
18125
18126                if (start) {
18127                    stopProfilerLocked(null, 0);
18128                    setProfileApp(proc.info, proc.processName, profilerInfo);
18129                    mProfileProc = proc;
18130                    mProfileType = profileType;
18131                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18132                    try {
18133                        fd = fd.dup();
18134                    } catch (IOException e) {
18135                        fd = null;
18136                    }
18137                    profilerInfo.profileFd = fd;
18138                    proc.thread.profilerControl(start, profilerInfo, profileType);
18139                    fd = null;
18140                    mProfileFd = null;
18141                } else {
18142                    stopProfilerLocked(proc, profileType);
18143                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18144                        try {
18145                            profilerInfo.profileFd.close();
18146                        } catch (IOException e) {
18147                        }
18148                    }
18149                }
18150
18151                return true;
18152            }
18153        } catch (RemoteException e) {
18154            throw new IllegalStateException("Process disappeared");
18155        } finally {
18156            if (profilerInfo != null && profilerInfo.profileFd != null) {
18157                try {
18158                    profilerInfo.profileFd.close();
18159                } catch (IOException e) {
18160                }
18161            }
18162        }
18163    }
18164
18165    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18166        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18167                userId, true, ALLOW_FULL_ONLY, callName, null);
18168        ProcessRecord proc = null;
18169        try {
18170            int pid = Integer.parseInt(process);
18171            synchronized (mPidsSelfLocked) {
18172                proc = mPidsSelfLocked.get(pid);
18173            }
18174        } catch (NumberFormatException e) {
18175        }
18176
18177        if (proc == null) {
18178            ArrayMap<String, SparseArray<ProcessRecord>> all
18179                    = mProcessNames.getMap();
18180            SparseArray<ProcessRecord> procs = all.get(process);
18181            if (procs != null && procs.size() > 0) {
18182                proc = procs.valueAt(0);
18183                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18184                    for (int i=1; i<procs.size(); i++) {
18185                        ProcessRecord thisProc = procs.valueAt(i);
18186                        if (thisProc.userId == userId) {
18187                            proc = thisProc;
18188                            break;
18189                        }
18190                    }
18191                }
18192            }
18193        }
18194
18195        return proc;
18196    }
18197
18198    public boolean dumpHeap(String process, int userId, boolean managed,
18199            String path, ParcelFileDescriptor fd) throws RemoteException {
18200
18201        try {
18202            synchronized (this) {
18203                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18204                // its own permission (same as profileControl).
18205                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18206                        != PackageManager.PERMISSION_GRANTED) {
18207                    throw new SecurityException("Requires permission "
18208                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18209                }
18210
18211                if (fd == null) {
18212                    throw new IllegalArgumentException("null fd");
18213                }
18214
18215                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18216                if (proc == null || proc.thread == null) {
18217                    throw new IllegalArgumentException("Unknown process: " + process);
18218                }
18219
18220                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18221                if (!isDebuggable) {
18222                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18223                        throw new SecurityException("Process not debuggable: " + proc);
18224                    }
18225                }
18226
18227                proc.thread.dumpHeap(managed, path, fd);
18228                fd = null;
18229                return true;
18230            }
18231        } catch (RemoteException e) {
18232            throw new IllegalStateException("Process disappeared");
18233        } finally {
18234            if (fd != null) {
18235                try {
18236                    fd.close();
18237                } catch (IOException e) {
18238                }
18239            }
18240        }
18241    }
18242
18243    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18244    public void monitor() {
18245        synchronized (this) { }
18246    }
18247
18248    void onCoreSettingsChange(Bundle settings) {
18249        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18250            ProcessRecord processRecord = mLruProcesses.get(i);
18251            try {
18252                if (processRecord.thread != null) {
18253                    processRecord.thread.setCoreSettings(settings);
18254                }
18255            } catch (RemoteException re) {
18256                /* ignore */
18257            }
18258        }
18259    }
18260
18261    // Multi-user methods
18262
18263    /**
18264     * Start user, if its not already running, but don't bring it to foreground.
18265     */
18266    @Override
18267    public boolean startUserInBackground(final int userId) {
18268        return startUser(userId, /* foreground */ false);
18269    }
18270
18271    /**
18272     * Start user, if its not already running, and bring it to foreground.
18273     */
18274    boolean startUserInForeground(final int userId, Dialog dlg) {
18275        boolean result = startUser(userId, /* foreground */ true);
18276        dlg.dismiss();
18277        return result;
18278    }
18279
18280    /**
18281     * Refreshes the list of users related to the current user when either a
18282     * user switch happens or when a new related user is started in the
18283     * background.
18284     */
18285    private void updateCurrentProfileIdsLocked() {
18286        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18287                mCurrentUserId, false /* enabledOnly */);
18288        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18289        for (int i = 0; i < currentProfileIds.length; i++) {
18290            currentProfileIds[i] = profiles.get(i).id;
18291        }
18292        mCurrentProfileIds = currentProfileIds;
18293
18294        synchronized (mUserProfileGroupIdsSelfLocked) {
18295            mUserProfileGroupIdsSelfLocked.clear();
18296            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18297            for (int i = 0; i < users.size(); i++) {
18298                UserInfo user = users.get(i);
18299                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18300                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18301                }
18302            }
18303        }
18304    }
18305
18306    private Set getProfileIdsLocked(int userId) {
18307        Set userIds = new HashSet<Integer>();
18308        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18309                userId, false /* enabledOnly */);
18310        for (UserInfo user : profiles) {
18311            userIds.add(Integer.valueOf(user.id));
18312        }
18313        return userIds;
18314    }
18315
18316    @Override
18317    public boolean switchUser(final int userId) {
18318        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18319        String userName;
18320        synchronized (this) {
18321            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18322            if (userInfo == null) {
18323                Slog.w(TAG, "No user info for user #" + userId);
18324                return false;
18325            }
18326            if (userInfo.isManagedProfile()) {
18327                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18328                return false;
18329            }
18330            userName = userInfo.name;
18331            mTargetUserId = userId;
18332        }
18333        mHandler.removeMessages(START_USER_SWITCH_MSG);
18334        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18335        return true;
18336    }
18337
18338    private void showUserSwitchDialog(int userId, String userName) {
18339        // The dialog will show and then initiate the user switch by calling startUserInForeground
18340        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18341                true /* above system */);
18342        d.show();
18343    }
18344
18345    private boolean startUser(final int userId, final boolean foreground) {
18346        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18347                != PackageManager.PERMISSION_GRANTED) {
18348            String msg = "Permission Denial: switchUser() from pid="
18349                    + Binder.getCallingPid()
18350                    + ", uid=" + Binder.getCallingUid()
18351                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18352            Slog.w(TAG, msg);
18353            throw new SecurityException(msg);
18354        }
18355
18356        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18357
18358        final long ident = Binder.clearCallingIdentity();
18359        try {
18360            synchronized (this) {
18361                final int oldUserId = mCurrentUserId;
18362                if (oldUserId == userId) {
18363                    return true;
18364                }
18365
18366                mStackSupervisor.setLockTaskModeLocked(null, false);
18367
18368                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18369                if (userInfo == null) {
18370                    Slog.w(TAG, "No user info for user #" + userId);
18371                    return false;
18372                }
18373                if (foreground && userInfo.isManagedProfile()) {
18374                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18375                    return false;
18376                }
18377
18378                if (foreground) {
18379                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18380                            R.anim.screen_user_enter);
18381                }
18382
18383                boolean needStart = false;
18384
18385                // If the user we are switching to is not currently started, then
18386                // we need to start it now.
18387                if (mStartedUsers.get(userId) == null) {
18388                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18389                    updateStartedUserArrayLocked();
18390                    needStart = true;
18391                }
18392
18393                final Integer userIdInt = Integer.valueOf(userId);
18394                mUserLru.remove(userIdInt);
18395                mUserLru.add(userIdInt);
18396
18397                if (foreground) {
18398                    mCurrentUserId = userId;
18399                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18400                    updateCurrentProfileIdsLocked();
18401                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18402                    // Once the internal notion of the active user has switched, we lock the device
18403                    // with the option to show the user switcher on the keyguard.
18404                    mWindowManager.lockNow(null);
18405                } else {
18406                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18407                    updateCurrentProfileIdsLocked();
18408                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18409                    mUserLru.remove(currentUserIdInt);
18410                    mUserLru.add(currentUserIdInt);
18411                }
18412
18413                final UserStartedState uss = mStartedUsers.get(userId);
18414
18415                // Make sure user is in the started state.  If it is currently
18416                // stopping, we need to knock that off.
18417                if (uss.mState == UserStartedState.STATE_STOPPING) {
18418                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18419                    // so we can just fairly silently bring the user back from
18420                    // the almost-dead.
18421                    uss.mState = UserStartedState.STATE_RUNNING;
18422                    updateStartedUserArrayLocked();
18423                    needStart = true;
18424                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18425                    // This means ACTION_SHUTDOWN has been sent, so we will
18426                    // need to treat this as a new boot of the user.
18427                    uss.mState = UserStartedState.STATE_BOOTING;
18428                    updateStartedUserArrayLocked();
18429                    needStart = true;
18430                }
18431
18432                if (uss.mState == UserStartedState.STATE_BOOTING) {
18433                    // Booting up a new user, need to tell system services about it.
18434                    // Note that this is on the same handler as scheduling of broadcasts,
18435                    // which is important because it needs to go first.
18436                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18437                }
18438
18439                if (foreground) {
18440                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18441                            oldUserId));
18442                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18443                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18444                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18445                            oldUserId, userId, uss));
18446                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18447                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18448                }
18449
18450                if (needStart) {
18451                    // Send USER_STARTED broadcast
18452                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18453                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18454                            | Intent.FLAG_RECEIVER_FOREGROUND);
18455                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18456                    broadcastIntentLocked(null, null, intent,
18457                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18458                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18459                }
18460
18461                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18462                    if (userId != UserHandle.USER_OWNER) {
18463                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18464                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18465                        broadcastIntentLocked(null, null, intent, null,
18466                                new IIntentReceiver.Stub() {
18467                                    public void performReceive(Intent intent, int resultCode,
18468                                            String data, Bundle extras, boolean ordered,
18469                                            boolean sticky, int sendingUser) {
18470                                        onUserInitialized(uss, foreground, oldUserId, userId);
18471                                    }
18472                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18473                                true, false, MY_PID, Process.SYSTEM_UID,
18474                                userId);
18475                        uss.initializing = true;
18476                    } else {
18477                        getUserManagerLocked().makeInitialized(userInfo.id);
18478                    }
18479                }
18480
18481                if (foreground) {
18482                    if (!uss.initializing) {
18483                        moveUserToForeground(uss, oldUserId, userId);
18484                    }
18485                } else {
18486                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18487                }
18488
18489                if (needStart) {
18490                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18491                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18492                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18493                    broadcastIntentLocked(null, null, intent,
18494                            null, new IIntentReceiver.Stub() {
18495                                @Override
18496                                public void performReceive(Intent intent, int resultCode, String data,
18497                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18498                                        throws RemoteException {
18499                                }
18500                            }, 0, null, null,
18501                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18502                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18503                }
18504            }
18505        } finally {
18506            Binder.restoreCallingIdentity(ident);
18507        }
18508
18509        return true;
18510    }
18511
18512    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18513        long ident = Binder.clearCallingIdentity();
18514        try {
18515            Intent intent;
18516            if (oldUserId >= 0) {
18517                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18518                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18519                int count = profiles.size();
18520                for (int i = 0; i < count; i++) {
18521                    int profileUserId = profiles.get(i).id;
18522                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18523                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18524                            | Intent.FLAG_RECEIVER_FOREGROUND);
18525                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18526                    broadcastIntentLocked(null, null, intent,
18527                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18528                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18529                }
18530            }
18531            if (newUserId >= 0) {
18532                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18533                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18534                int count = profiles.size();
18535                for (int i = 0; i < count; i++) {
18536                    int profileUserId = profiles.get(i).id;
18537                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18538                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18539                            | Intent.FLAG_RECEIVER_FOREGROUND);
18540                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18541                    broadcastIntentLocked(null, null, intent,
18542                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18543                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18544                }
18545                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18546                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18547                        | Intent.FLAG_RECEIVER_FOREGROUND);
18548                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18549                broadcastIntentLocked(null, null, intent,
18550                        null, null, 0, null, null,
18551                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18552                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18553            }
18554        } finally {
18555            Binder.restoreCallingIdentity(ident);
18556        }
18557    }
18558
18559    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18560            final int newUserId) {
18561        final int N = mUserSwitchObservers.beginBroadcast();
18562        if (N > 0) {
18563            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18564                int mCount = 0;
18565                @Override
18566                public void sendResult(Bundle data) throws RemoteException {
18567                    synchronized (ActivityManagerService.this) {
18568                        if (mCurUserSwitchCallback == this) {
18569                            mCount++;
18570                            if (mCount == N) {
18571                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18572                            }
18573                        }
18574                    }
18575                }
18576            };
18577            synchronized (this) {
18578                uss.switching = true;
18579                mCurUserSwitchCallback = callback;
18580            }
18581            for (int i=0; i<N; i++) {
18582                try {
18583                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18584                            newUserId, callback);
18585                } catch (RemoteException e) {
18586                }
18587            }
18588        } else {
18589            synchronized (this) {
18590                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18591            }
18592        }
18593        mUserSwitchObservers.finishBroadcast();
18594    }
18595
18596    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18597        synchronized (this) {
18598            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18599            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18600        }
18601    }
18602
18603    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18604        mCurUserSwitchCallback = null;
18605        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18606        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18607                oldUserId, newUserId, uss));
18608    }
18609
18610    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18611        synchronized (this) {
18612            if (foreground) {
18613                moveUserToForeground(uss, oldUserId, newUserId);
18614            }
18615        }
18616
18617        completeSwitchAndInitalize(uss, newUserId, true, false);
18618    }
18619
18620    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18621        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18622        if (homeInFront) {
18623            startHomeActivityLocked(newUserId);
18624        } else {
18625            mStackSupervisor.resumeTopActivitiesLocked();
18626        }
18627        EventLogTags.writeAmSwitchUser(newUserId);
18628        getUserManagerLocked().userForeground(newUserId);
18629        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18630    }
18631
18632    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18633        completeSwitchAndInitalize(uss, newUserId, false, true);
18634    }
18635
18636    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18637            boolean clearInitializing, boolean clearSwitching) {
18638        boolean unfrozen = false;
18639        synchronized (this) {
18640            if (clearInitializing) {
18641                uss.initializing = false;
18642                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18643            }
18644            if (clearSwitching) {
18645                uss.switching = false;
18646            }
18647            if (!uss.switching && !uss.initializing) {
18648                mWindowManager.stopFreezingScreen();
18649                unfrozen = true;
18650            }
18651        }
18652        if (unfrozen) {
18653            final int N = mUserSwitchObservers.beginBroadcast();
18654            for (int i=0; i<N; i++) {
18655                try {
18656                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18657                } catch (RemoteException e) {
18658                }
18659            }
18660            mUserSwitchObservers.finishBroadcast();
18661        }
18662    }
18663
18664    void scheduleStartProfilesLocked() {
18665        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18666            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18667                    DateUtils.SECOND_IN_MILLIS);
18668        }
18669    }
18670
18671    void startProfilesLocked() {
18672        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18673        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18674                mCurrentUserId, false /* enabledOnly */);
18675        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18676        for (UserInfo user : profiles) {
18677            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18678                    && user.id != mCurrentUserId) {
18679                toStart.add(user);
18680            }
18681        }
18682        final int n = toStart.size();
18683        int i = 0;
18684        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18685            startUserInBackground(toStart.get(i).id);
18686        }
18687        if (i < n) {
18688            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18689        }
18690    }
18691
18692    void finishUserBoot(UserStartedState uss) {
18693        synchronized (this) {
18694            if (uss.mState == UserStartedState.STATE_BOOTING
18695                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18696                uss.mState = UserStartedState.STATE_RUNNING;
18697                final int userId = uss.mHandle.getIdentifier();
18698                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18699                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18700                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18701                broadcastIntentLocked(null, null, intent,
18702                        null, null, 0, null, null,
18703                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18704                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18705            }
18706        }
18707    }
18708
18709    void finishUserSwitch(UserStartedState uss) {
18710        synchronized (this) {
18711            finishUserBoot(uss);
18712
18713            startProfilesLocked();
18714
18715            int num = mUserLru.size();
18716            int i = 0;
18717            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18718                Integer oldUserId = mUserLru.get(i);
18719                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18720                if (oldUss == null) {
18721                    // Shouldn't happen, but be sane if it does.
18722                    mUserLru.remove(i);
18723                    num--;
18724                    continue;
18725                }
18726                if (oldUss.mState == UserStartedState.STATE_STOPPING
18727                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18728                    // This user is already stopping, doesn't count.
18729                    num--;
18730                    i++;
18731                    continue;
18732                }
18733                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18734                    // Owner and current can't be stopped, but count as running.
18735                    i++;
18736                    continue;
18737                }
18738                // This is a user to be stopped.
18739                stopUserLocked(oldUserId, null);
18740                num--;
18741                i++;
18742            }
18743        }
18744    }
18745
18746    @Override
18747    public int stopUser(final int userId, final IStopUserCallback callback) {
18748        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18749                != PackageManager.PERMISSION_GRANTED) {
18750            String msg = "Permission Denial: switchUser() from pid="
18751                    + Binder.getCallingPid()
18752                    + ", uid=" + Binder.getCallingUid()
18753                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18754            Slog.w(TAG, msg);
18755            throw new SecurityException(msg);
18756        }
18757        if (userId <= 0) {
18758            throw new IllegalArgumentException("Can't stop primary user " + userId);
18759        }
18760        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18761        synchronized (this) {
18762            return stopUserLocked(userId, callback);
18763        }
18764    }
18765
18766    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18767        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18768        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18769            return ActivityManager.USER_OP_IS_CURRENT;
18770        }
18771
18772        final UserStartedState uss = mStartedUsers.get(userId);
18773        if (uss == null) {
18774            // User is not started, nothing to do...  but we do need to
18775            // callback if requested.
18776            if (callback != null) {
18777                mHandler.post(new Runnable() {
18778                    @Override
18779                    public void run() {
18780                        try {
18781                            callback.userStopped(userId);
18782                        } catch (RemoteException e) {
18783                        }
18784                    }
18785                });
18786            }
18787            return ActivityManager.USER_OP_SUCCESS;
18788        }
18789
18790        if (callback != null) {
18791            uss.mStopCallbacks.add(callback);
18792        }
18793
18794        if (uss.mState != UserStartedState.STATE_STOPPING
18795                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18796            uss.mState = UserStartedState.STATE_STOPPING;
18797            updateStartedUserArrayLocked();
18798
18799            long ident = Binder.clearCallingIdentity();
18800            try {
18801                // We are going to broadcast ACTION_USER_STOPPING and then
18802                // once that is done send a final ACTION_SHUTDOWN and then
18803                // stop the user.
18804                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18805                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18806                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18807                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18808                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18809                // This is the result receiver for the final shutdown broadcast.
18810                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18811                    @Override
18812                    public void performReceive(Intent intent, int resultCode, String data,
18813                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18814                        finishUserStop(uss);
18815                    }
18816                };
18817                // This is the result receiver for the initial stopping broadcast.
18818                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18819                    @Override
18820                    public void performReceive(Intent intent, int resultCode, String data,
18821                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18822                        // On to the next.
18823                        synchronized (ActivityManagerService.this) {
18824                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18825                                // Whoops, we are being started back up.  Abort, abort!
18826                                return;
18827                            }
18828                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18829                        }
18830                        mBatteryStatsService.noteEvent(
18831                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18832                                Integer.toString(userId), userId);
18833                        mSystemServiceManager.stopUser(userId);
18834                        broadcastIntentLocked(null, null, shutdownIntent,
18835                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18836                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18837                    }
18838                };
18839                // Kick things off.
18840                broadcastIntentLocked(null, null, stoppingIntent,
18841                        null, stoppingReceiver, 0, null, null,
18842                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18843                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18844            } finally {
18845                Binder.restoreCallingIdentity(ident);
18846            }
18847        }
18848
18849        return ActivityManager.USER_OP_SUCCESS;
18850    }
18851
18852    void finishUserStop(UserStartedState uss) {
18853        final int userId = uss.mHandle.getIdentifier();
18854        boolean stopped;
18855        ArrayList<IStopUserCallback> callbacks;
18856        synchronized (this) {
18857            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18858            if (mStartedUsers.get(userId) != uss) {
18859                stopped = false;
18860            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18861                stopped = false;
18862            } else {
18863                stopped = true;
18864                // User can no longer run.
18865                mStartedUsers.remove(userId);
18866                mUserLru.remove(Integer.valueOf(userId));
18867                updateStartedUserArrayLocked();
18868
18869                // Clean up all state and processes associated with the user.
18870                // Kill all the processes for the user.
18871                forceStopUserLocked(userId, "finish user");
18872            }
18873
18874            // Explicitly remove the old information in mRecentTasks.
18875            removeRecentTasksForUserLocked(userId);
18876        }
18877
18878        for (int i=0; i<callbacks.size(); i++) {
18879            try {
18880                if (stopped) callbacks.get(i).userStopped(userId);
18881                else callbacks.get(i).userStopAborted(userId);
18882            } catch (RemoteException e) {
18883            }
18884        }
18885
18886        if (stopped) {
18887            mSystemServiceManager.cleanupUser(userId);
18888            synchronized (this) {
18889                mStackSupervisor.removeUserLocked(userId);
18890            }
18891        }
18892    }
18893
18894    @Override
18895    public UserInfo getCurrentUser() {
18896        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18897                != PackageManager.PERMISSION_GRANTED) && (
18898                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18899                != PackageManager.PERMISSION_GRANTED)) {
18900            String msg = "Permission Denial: getCurrentUser() from pid="
18901                    + Binder.getCallingPid()
18902                    + ", uid=" + Binder.getCallingUid()
18903                    + " requires " + INTERACT_ACROSS_USERS;
18904            Slog.w(TAG, msg);
18905            throw new SecurityException(msg);
18906        }
18907        synchronized (this) {
18908            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18909            return getUserManagerLocked().getUserInfo(userId);
18910        }
18911    }
18912
18913    int getCurrentUserIdLocked() {
18914        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18915    }
18916
18917    @Override
18918    public boolean isUserRunning(int userId, boolean orStopped) {
18919        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18920                != PackageManager.PERMISSION_GRANTED) {
18921            String msg = "Permission Denial: isUserRunning() from pid="
18922                    + Binder.getCallingPid()
18923                    + ", uid=" + Binder.getCallingUid()
18924                    + " requires " + INTERACT_ACROSS_USERS;
18925            Slog.w(TAG, msg);
18926            throw new SecurityException(msg);
18927        }
18928        synchronized (this) {
18929            return isUserRunningLocked(userId, orStopped);
18930        }
18931    }
18932
18933    boolean isUserRunningLocked(int userId, boolean orStopped) {
18934        UserStartedState state = mStartedUsers.get(userId);
18935        if (state == null) {
18936            return false;
18937        }
18938        if (orStopped) {
18939            return true;
18940        }
18941        return state.mState != UserStartedState.STATE_STOPPING
18942                && state.mState != UserStartedState.STATE_SHUTDOWN;
18943    }
18944
18945    @Override
18946    public int[] getRunningUserIds() {
18947        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18948                != PackageManager.PERMISSION_GRANTED) {
18949            String msg = "Permission Denial: isUserRunning() from pid="
18950                    + Binder.getCallingPid()
18951                    + ", uid=" + Binder.getCallingUid()
18952                    + " requires " + INTERACT_ACROSS_USERS;
18953            Slog.w(TAG, msg);
18954            throw new SecurityException(msg);
18955        }
18956        synchronized (this) {
18957            return mStartedUserArray;
18958        }
18959    }
18960
18961    private void updateStartedUserArrayLocked() {
18962        int num = 0;
18963        for (int i=0; i<mStartedUsers.size();  i++) {
18964            UserStartedState uss = mStartedUsers.valueAt(i);
18965            // This list does not include stopping users.
18966            if (uss.mState != UserStartedState.STATE_STOPPING
18967                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18968                num++;
18969            }
18970        }
18971        mStartedUserArray = new int[num];
18972        num = 0;
18973        for (int i=0; i<mStartedUsers.size();  i++) {
18974            UserStartedState uss = mStartedUsers.valueAt(i);
18975            if (uss.mState != UserStartedState.STATE_STOPPING
18976                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18977                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18978                num++;
18979            }
18980        }
18981    }
18982
18983    @Override
18984    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18985        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18986                != PackageManager.PERMISSION_GRANTED) {
18987            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18988                    + Binder.getCallingPid()
18989                    + ", uid=" + Binder.getCallingUid()
18990                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18991            Slog.w(TAG, msg);
18992            throw new SecurityException(msg);
18993        }
18994
18995        mUserSwitchObservers.register(observer);
18996    }
18997
18998    @Override
18999    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19000        mUserSwitchObservers.unregister(observer);
19001    }
19002
19003    private boolean userExists(int userId) {
19004        if (userId == 0) {
19005            return true;
19006        }
19007        UserManagerService ums = getUserManagerLocked();
19008        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19009    }
19010
19011    int[] getUsersLocked() {
19012        UserManagerService ums = getUserManagerLocked();
19013        return ums != null ? ums.getUserIds() : new int[] { 0 };
19014    }
19015
19016    UserManagerService getUserManagerLocked() {
19017        if (mUserManager == null) {
19018            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19019            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19020        }
19021        return mUserManager;
19022    }
19023
19024    private int applyUserId(int uid, int userId) {
19025        return UserHandle.getUid(userId, uid);
19026    }
19027
19028    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19029        if (info == null) return null;
19030        ApplicationInfo newInfo = new ApplicationInfo(info);
19031        newInfo.uid = applyUserId(info.uid, userId);
19032        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19033                + info.packageName;
19034        return newInfo;
19035    }
19036
19037    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19038        if (aInfo == null
19039                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19040            return aInfo;
19041        }
19042
19043        ActivityInfo info = new ActivityInfo(aInfo);
19044        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19045        return info;
19046    }
19047
19048    private final class LocalService extends ActivityManagerInternal {
19049        @Override
19050        public void onWakefulnessChanged(int wakefulness) {
19051            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19052        }
19053
19054        @Override
19055        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19056                String processName, String abiOverride, int uid, Runnable crashHandler) {
19057            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19058                    processName, abiOverride, uid, crashHandler);
19059        }
19060    }
19061
19062    /**
19063     * An implementation of IAppTask, that allows an app to manage its own tasks via
19064     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19065     * only the process that calls getAppTasks() can call the AppTask methods.
19066     */
19067    class AppTaskImpl extends IAppTask.Stub {
19068        private int mTaskId;
19069        private int mCallingUid;
19070
19071        public AppTaskImpl(int taskId, int callingUid) {
19072            mTaskId = taskId;
19073            mCallingUid = callingUid;
19074        }
19075
19076        private void checkCaller() {
19077            if (mCallingUid != Binder.getCallingUid()) {
19078                throw new SecurityException("Caller " + mCallingUid
19079                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19080            }
19081        }
19082
19083        @Override
19084        public void finishAndRemoveTask() {
19085            checkCaller();
19086
19087            synchronized (ActivityManagerService.this) {
19088                long origId = Binder.clearCallingIdentity();
19089                try {
19090                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19091                    if (tr == null) {
19092                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19093                    }
19094                    // Only kill the process if we are not a new document
19095                    int flags = tr.getBaseIntent().getFlags();
19096                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19097                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19098                    removeTaskByIdLocked(mTaskId,
19099                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19100                } finally {
19101                    Binder.restoreCallingIdentity(origId);
19102                }
19103            }
19104        }
19105
19106        @Override
19107        public ActivityManager.RecentTaskInfo getTaskInfo() {
19108            checkCaller();
19109
19110            synchronized (ActivityManagerService.this) {
19111                long origId = Binder.clearCallingIdentity();
19112                try {
19113                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19114                    if (tr == null) {
19115                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19116                    }
19117                    return createRecentTaskInfoFromTaskRecord(tr);
19118                } finally {
19119                    Binder.restoreCallingIdentity(origId);
19120                }
19121            }
19122        }
19123
19124        @Override
19125        public void moveToFront() {
19126            checkCaller();
19127
19128            final TaskRecord tr;
19129            synchronized (ActivityManagerService.this) {
19130                tr = recentTaskForIdLocked(mTaskId);
19131                if (tr == null) {
19132                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19133                }
19134                if (tr.getRootActivity() != null) {
19135                    moveTaskToFrontLocked(tr.taskId, 0, null);
19136                    return;
19137                }
19138            }
19139
19140            startActivityFromRecentsInner(tr.taskId, null);
19141        }
19142
19143        @Override
19144        public int startActivity(IBinder whoThread, String callingPackage,
19145                Intent intent, String resolvedType, Bundle options) {
19146            checkCaller();
19147
19148            int callingUser = UserHandle.getCallingUserId();
19149            TaskRecord tr;
19150            IApplicationThread appThread;
19151            synchronized (ActivityManagerService.this) {
19152                tr = recentTaskForIdLocked(mTaskId);
19153                if (tr == null) {
19154                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19155                }
19156                appThread = ApplicationThreadNative.asInterface(whoThread);
19157                if (appThread == null) {
19158                    throw new IllegalArgumentException("Bad app thread " + appThread);
19159                }
19160            }
19161            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19162                    resolvedType, null, null, null, null, 0, 0, null, null,
19163                    null, options, callingUser, null, tr);
19164        }
19165
19166        @Override
19167        public void setExcludeFromRecents(boolean exclude) {
19168            checkCaller();
19169
19170            synchronized (ActivityManagerService.this) {
19171                long origId = Binder.clearCallingIdentity();
19172                try {
19173                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19174                    if (tr == null) {
19175                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19176                    }
19177                    Intent intent = tr.getBaseIntent();
19178                    if (exclude) {
19179                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19180                    } else {
19181                        intent.setFlags(intent.getFlags()
19182                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19183                    }
19184                } finally {
19185                    Binder.restoreCallingIdentity(origId);
19186                }
19187            }
19188        }
19189    }
19190}
19191