ActivityManagerService.java revision dcf21d15456e5aca28d063aea73139e30842e6d1
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 com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
31import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
32import static org.xmlpull.v1.XmlPullParser.START_TAG;
33import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ProfilerInfo;
42import android.app.admin.DevicePolicyManager;
43import android.app.usage.UsageEvents;
44import android.app.usage.UsageStatsManagerInternal;
45import android.appwidget.AppWidgetManager;
46import android.content.res.Resources;
47import android.graphics.Bitmap;
48import android.graphics.Point;
49import android.graphics.Rect;
50import android.os.BatteryStats;
51import android.os.PersistableBundle;
52import android.os.storage.IMountService;
53import android.os.storage.StorageManager;
54import android.service.voice.IVoiceInteractionSession;
55import android.util.ArrayMap;
56import android.util.ArraySet;
57import android.util.SparseIntArray;
58
59import com.android.internal.R;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.app.IAppOpsService;
62import com.android.internal.app.IVoiceInteractor;
63import com.android.internal.app.ProcessMap;
64import com.android.internal.app.ProcessStats;
65import com.android.internal.content.PackageMonitor;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.UserManagerService;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
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 boolean haveResult = false;
439        public Bundle result = null;
440        public PendingAssistExtras(ActivityRecord _activity) {
441            activity = _activity;
442        }
443        @Override
444        public void run() {
445            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
446            synchronized (this) {
447                haveResult = true;
448                notifyAll();
449            }
450        }
451    }
452
453    final ArrayList<PendingAssistExtras> mPendingAssistExtras
454            = new ArrayList<PendingAssistExtras>();
455
456    /**
457     * Process management.
458     */
459    final ProcessList mProcessList = new ProcessList();
460
461    /**
462     * All of the applications we currently have running organized by name.
463     * The keys are strings of the application package name (as
464     * returned by the package manager), and the keys are ApplicationRecord
465     * objects.
466     */
467    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
468
469    /**
470     * Tracking long-term execution of processes to look for abuse and other
471     * bad app behavior.
472     */
473    final ProcessStatsService mProcessStats;
474
475    /**
476     * The currently running isolated processes.
477     */
478    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
479
480    /**
481     * Counter for assigning isolated process uids, to avoid frequently reusing the
482     * same ones.
483     */
484    int mNextIsolatedProcessUid = 0;
485
486    /**
487     * The currently running heavy-weight process, if any.
488     */
489    ProcessRecord mHeavyWeightProcess = null;
490
491    /**
492     * The last time that various processes have crashed.
493     */
494    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
495
496    /**
497     * Information about a process that is currently marked as bad.
498     */
499    static final class BadProcessInfo {
500        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
501            this.time = time;
502            this.shortMsg = shortMsg;
503            this.longMsg = longMsg;
504            this.stack = stack;
505        }
506
507        final long time;
508        final String shortMsg;
509        final String longMsg;
510        final String stack;
511    }
512
513    /**
514     * Set of applications that we consider to be bad, and will reject
515     * incoming broadcasts from (which the user has no control over).
516     * Processes are added to this set when they have crashed twice within
517     * a minimum amount of time; they are removed from it when they are
518     * later restarted (hopefully due to some user action).  The value is the
519     * time it was added to the list.
520     */
521    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
522
523    /**
524     * All of the processes we currently have running organized by pid.
525     * The keys are the pid running the application.
526     *
527     * <p>NOTE: This object is protected by its own lock, NOT the global
528     * activity manager lock!
529     */
530    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
531
532    /**
533     * All of the processes that have been forced to be foreground.  The key
534     * is the pid of the caller who requested it (we hold a death
535     * link on it).
536     */
537    abstract class ForegroundToken implements IBinder.DeathRecipient {
538        int pid;
539        IBinder token;
540    }
541    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
542
543    /**
544     * List of records for processes that someone had tried to start before the
545     * system was ready.  We don't start them at that point, but ensure they
546     * are started by the time booting is complete.
547     */
548    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
549
550    /**
551     * List of persistent applications that are in the process
552     * of being started.
553     */
554    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * Processes that are being forcibly torn down.
558     */
559    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
560
561    /**
562     * List of running applications, sorted by recent usage.
563     * The first entry in the list is the least recently used.
564     */
565    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Where in mLruProcesses that the processes hosting activities start.
569     */
570    int mLruProcessActivityStart = 0;
571
572    /**
573     * Where in mLruProcesses that the processes hosting services start.
574     * This is after (lower index) than mLruProcessesActivityStart.
575     */
576    int mLruProcessServiceStart = 0;
577
578    /**
579     * List of processes that should gc as soon as things are idle.
580     */
581    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
582
583    /**
584     * Processes we want to collect PSS data from.
585     */
586    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
587
588    /**
589     * Last time we requested PSS data of all processes.
590     */
591    long mLastFullPssTime = SystemClock.uptimeMillis();
592
593    /**
594     * If set, the next time we collect PSS data we should do a full collection
595     * with data from native processes and the kernel.
596     */
597    boolean mFullPssPending = false;
598
599    /**
600     * This is the process holding what we currently consider to be
601     * the "home" activity.
602     */
603    ProcessRecord mHomeProcess;
604
605    /**
606     * This is the process holding the activity the user last visited that
607     * is in a different process from the one they are currently in.
608     */
609    ProcessRecord mPreviousProcess;
610
611    /**
612     * The time at which the previous process was last visible.
613     */
614    long mPreviousProcessVisibleTime;
615
616    /**
617     * Which uses have been started, so are allowed to run code.
618     */
619    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
620
621    /**
622     * LRU list of history of current users.  Most recently current is at the end.
623     */
624    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
625
626    /**
627     * Constant array of the users that are currently started.
628     */
629    int[] mStartedUserArray = new int[] { 0 };
630
631    /**
632     * Registered observers of the user switching mechanics.
633     */
634    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
635            = new RemoteCallbackList<IUserSwitchObserver>();
636
637    /**
638     * Currently active user switch.
639     */
640    Object mCurUserSwitchCallback;
641
642    /**
643     * Packages that the user has asked to have run in screen size
644     * compatibility mode instead of filling the screen.
645     */
646    final CompatModePackages mCompatModePackages;
647
648    /**
649     * Set of IntentSenderRecord objects that are currently active.
650     */
651    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
652            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
653
654    /**
655     * Fingerprints (hashCode()) of stack traces that we've
656     * already logged DropBox entries for.  Guarded by itself.  If
657     * something (rogue user app) forces this over
658     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
659     */
660    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
661    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
662
663    /**
664     * Strict Mode background batched logging state.
665     *
666     * The string buffer is guarded by itself, and its lock is also
667     * used to determine if another batched write is already
668     * in-flight.
669     */
670    private final StringBuilder mStrictModeBuffer = new StringBuilder();
671
672    /**
673     * Keeps track of all IIntentReceivers that have been registered for
674     * broadcasts.  Hash keys are the receiver IBinder, hash value is
675     * a ReceiverList.
676     */
677    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
678            new HashMap<IBinder, ReceiverList>();
679
680    /**
681     * Resolver for broadcast intents to registered receivers.
682     * Holds BroadcastFilter (subclass of IntentFilter).
683     */
684    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
685            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
686        @Override
687        protected boolean allowFilterResult(
688                BroadcastFilter filter, List<BroadcastFilter> dest) {
689            IBinder target = filter.receiverList.receiver.asBinder();
690            for (int i=dest.size()-1; i>=0; i--) {
691                if (dest.get(i).receiverList.receiver.asBinder() == target) {
692                    return false;
693                }
694            }
695            return true;
696        }
697
698        @Override
699        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
700            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
701                    || userId == filter.owningUserId) {
702                return super.newResult(filter, match, userId);
703            }
704            return null;
705        }
706
707        @Override
708        protected BroadcastFilter[] newArray(int size) {
709            return new BroadcastFilter[size];
710        }
711
712        @Override
713        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
714            return packageName.equals(filter.packageName);
715        }
716    };
717
718    /**
719     * State of all active sticky broadcasts per user.  Keys are the action of the
720     * sticky Intent, values are an ArrayList of all broadcasted intents with
721     * that action (which should usually be one).  The SparseArray is keyed
722     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
723     * for stickies that are sent to all users.
724     */
725    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
726            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
727
728    final ActiveServices mServices;
729
730    /**
731     * Backup/restore process management
732     */
733    String mBackupAppName = null;
734    BackupRecord mBackupTarget = null;
735
736    final ProviderMap mProviderMap;
737
738    /**
739     * List of content providers who have clients waiting for them.  The
740     * application is currently being launched and the provider will be
741     * removed from this list once it is published.
742     */
743    final ArrayList<ContentProviderRecord> mLaunchingProviders
744            = new ArrayList<ContentProviderRecord>();
745
746    /**
747     * File storing persisted {@link #mGrantedUriPermissions}.
748     */
749    private final AtomicFile mGrantFile;
750
751    /** XML constants used in {@link #mGrantFile} */
752    private static final String TAG_URI_GRANTS = "uri-grants";
753    private static final String TAG_URI_GRANT = "uri-grant";
754    private static final String ATTR_USER_HANDLE = "userHandle";
755    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
756    private static final String ATTR_TARGET_USER_ID = "targetUserId";
757    private static final String ATTR_SOURCE_PKG = "sourcePkg";
758    private static final String ATTR_TARGET_PKG = "targetPkg";
759    private static final String ATTR_URI = "uri";
760    private static final String ATTR_MODE_FLAGS = "modeFlags";
761    private static final String ATTR_CREATED_TIME = "createdTime";
762    private static final String ATTR_PREFIX = "prefix";
763
764    /**
765     * Global set of specific {@link Uri} permissions that have been granted.
766     * This optimized lookup structure maps from {@link UriPermission#targetUid}
767     * to {@link UriPermission#uri} to {@link UriPermission}.
768     */
769    @GuardedBy("this")
770    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
771            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
772
773    public static class GrantUri {
774        public final int sourceUserId;
775        public final Uri uri;
776        public boolean prefix;
777
778        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
779            this.sourceUserId = sourceUserId;
780            this.uri = uri;
781            this.prefix = prefix;
782        }
783
784        @Override
785        public int hashCode() {
786            return toString().hashCode();
787        }
788
789        @Override
790        public boolean equals(Object o) {
791            if (o instanceof GrantUri) {
792                GrantUri other = (GrantUri) o;
793                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
794                        && prefix == other.prefix;
795            }
796            return false;
797        }
798
799        @Override
800        public String toString() {
801            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
802            if (prefix) result += " [prefix]";
803            return result;
804        }
805
806        public String toSafeString() {
807            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
808            if (prefix) result += " [prefix]";
809            return result;
810        }
811
812        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
813            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
814                    ContentProvider.getUriWithoutUserId(uri), false);
815        }
816    }
817
818    CoreSettingsObserver mCoreSettingsObserver;
819
820    /**
821     * Thread-local storage used to carry caller permissions over through
822     * indirect content-provider access.
823     */
824    private class Identity {
825        public int pid;
826        public int uid;
827
828        Identity(int _pid, int _uid) {
829            pid = _pid;
830            uid = _uid;
831        }
832    }
833
834    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
835
836    /**
837     * All information we have collected about the runtime performance of
838     * any user id that can impact battery performance.
839     */
840    final BatteryStatsService mBatteryStatsService;
841
842    /**
843     * Information about component usage
844     */
845    UsageStatsManagerInternal mUsageStatsService;
846
847    /**
848     * Information about and control over application operations
849     */
850    final AppOpsService mAppOpsService;
851
852    /**
853     * Save recent tasks information across reboots.
854     */
855    final TaskPersister mTaskPersister;
856
857    /**
858     * Current configuration information.  HistoryRecord objects are given
859     * a reference to this object to indicate which configuration they are
860     * currently running in, so this object must be kept immutable.
861     */
862    Configuration mConfiguration = new Configuration();
863
864    /**
865     * Current sequencing integer of the configuration, for skipping old
866     * configurations.
867     */
868    int mConfigurationSeq = 0;
869
870    /**
871     * Hardware-reported OpenGLES version.
872     */
873    final int GL_ES_VERSION;
874
875    /**
876     * List of initialization arguments to pass to all processes when binding applications to them.
877     * For example, references to the commonly used services.
878     */
879    HashMap<String, IBinder> mAppBindArgs;
880
881    /**
882     * Temporary to avoid allocations.  Protected by main lock.
883     */
884    final StringBuilder mStringBuilder = new StringBuilder(256);
885
886    /**
887     * Used to control how we initialize the service.
888     */
889    ComponentName mTopComponent;
890    String mTopAction = Intent.ACTION_MAIN;
891    String mTopData;
892    boolean mProcessesReady = false;
893    boolean mSystemReady = false;
894    boolean mBooting = false;
895    boolean mCallFinishBooting = false;
896    boolean mBootAnimationComplete = false;
897    boolean mWaitingUpdate = false;
898    boolean mDidUpdate = false;
899    boolean mOnBattery = false;
900    boolean mLaunchWarningShown = false;
901
902    Context mContext;
903
904    int mFactoryTest;
905
906    boolean mCheckedForSetup;
907
908    /**
909     * The time at which we will allow normal application switches again,
910     * after a call to {@link #stopAppSwitches()}.
911     */
912    long mAppSwitchesAllowedTime;
913
914    /**
915     * This is set to true after the first switch after mAppSwitchesAllowedTime
916     * is set; any switches after that will clear the time.
917     */
918    boolean mDidAppSwitch;
919
920    /**
921     * Last time (in realtime) at which we checked for power usage.
922     */
923    long mLastPowerCheckRealtime;
924
925    /**
926     * Last time (in uptime) at which we checked for power usage.
927     */
928    long mLastPowerCheckUptime;
929
930    /**
931     * Set while we are wanting to sleep, to prevent any
932     * activities from being started/resumed.
933     */
934    private boolean mSleeping = false;
935
936    /**
937     * Set while we are running a voice interaction.  This overrides
938     * sleeping while it is active.
939     */
940    private boolean mRunningVoice = false;
941
942    /**
943     * State of external calls telling us if the device is asleep.
944     */
945    private boolean mWentToSleep = false;
946
947    /**
948     * State of external call telling us if the lock screen is shown.
949     */
950    private boolean mLockScreenShown = false;
951
952    /**
953     * Set if we are shutting down the system, similar to sleeping.
954     */
955    boolean mShuttingDown = false;
956
957    /**
958     * Current sequence id for oom_adj computation traversal.
959     */
960    int mAdjSeq = 0;
961
962    /**
963     * Current sequence id for process LRU updating.
964     */
965    int mLruSeq = 0;
966
967    /**
968     * Keep track of the non-cached/empty process we last found, to help
969     * determine how to distribute cached/empty processes next time.
970     */
971    int mNumNonCachedProcs = 0;
972
973    /**
974     * Keep track of the number of cached hidden procs, to balance oom adj
975     * distribution between those and empty procs.
976     */
977    int mNumCachedHiddenProcs = 0;
978
979    /**
980     * Keep track of the number of service processes we last found, to
981     * determine on the next iteration which should be B services.
982     */
983    int mNumServiceProcs = 0;
984    int mNewNumAServiceProcs = 0;
985    int mNewNumServiceProcs = 0;
986
987    /**
988     * Allow the current computed overall memory level of the system to go down?
989     * This is set to false when we are killing processes for reasons other than
990     * memory management, so that the now smaller process list will not be taken as
991     * an indication that memory is tighter.
992     */
993    boolean mAllowLowerMemLevel = false;
994
995    /**
996     * The last computed memory level, for holding when we are in a state that
997     * processes are going away for other reasons.
998     */
999    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1000
1001    /**
1002     * The last total number of process we have, to determine if changes actually look
1003     * like a shrinking number of process due to lower RAM.
1004     */
1005    int mLastNumProcesses;
1006
1007    /**
1008     * The uptime of the last time we performed idle maintenance.
1009     */
1010    long mLastIdleTime = SystemClock.uptimeMillis();
1011
1012    /**
1013     * Total time spent with RAM that has been added in the past since the last idle time.
1014     */
1015    long mLowRamTimeSinceLastIdle = 0;
1016
1017    /**
1018     * If RAM is currently low, when that horrible situation started.
1019     */
1020    long mLowRamStartTime = 0;
1021
1022    /**
1023     * For reporting to battery stats the current top application.
1024     */
1025    private String mCurResumedPackage = null;
1026    private int mCurResumedUid = -1;
1027
1028    /**
1029     * For reporting to battery stats the apps currently running foreground
1030     * service.  The ProcessMap is package/uid tuples; each of these contain
1031     * an array of the currently foreground processes.
1032     */
1033    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1034            = new ProcessMap<ArrayList<ProcessRecord>>();
1035
1036    /**
1037     * This is set if we had to do a delayed dexopt of an app before launching
1038     * it, to increase the ANR timeouts in that case.
1039     */
1040    boolean mDidDexOpt;
1041
1042    /**
1043     * Set if the systemServer made a call to enterSafeMode.
1044     */
1045    boolean mSafeMode;
1046
1047    String mDebugApp = null;
1048    boolean mWaitForDebugger = false;
1049    boolean mDebugTransient = false;
1050    String mOrigDebugApp = null;
1051    boolean mOrigWaitForDebugger = false;
1052    boolean mAlwaysFinishActivities = false;
1053    IActivityController mController = null;
1054    String mProfileApp = null;
1055    ProcessRecord mProfileProc = null;
1056    String mProfileFile;
1057    ParcelFileDescriptor mProfileFd;
1058    int mSamplingInterval = 0;
1059    boolean mAutoStopProfiler = false;
1060    int mProfileType = 0;
1061    String mOpenGlTraceApp = null;
1062
1063    static class ProcessChangeItem {
1064        static final int CHANGE_ACTIVITIES = 1<<0;
1065        static final int CHANGE_PROCESS_STATE = 1<<1;
1066        int changes;
1067        int uid;
1068        int pid;
1069        int processState;
1070        boolean foregroundActivities;
1071    }
1072
1073    final RemoteCallbackList<IProcessObserver> mProcessObservers
1074            = new RemoteCallbackList<IProcessObserver>();
1075    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1076
1077    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1078            = new ArrayList<ProcessChangeItem>();
1079    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1080            = new ArrayList<ProcessChangeItem>();
1081
1082    /**
1083     * Runtime CPU use collection thread.  This object's lock is used to
1084     * perform synchronization with the thread (notifying it to run).
1085     */
1086    final Thread mProcessCpuThread;
1087
1088    /**
1089     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1090     * Must acquire this object's lock when accessing it.
1091     * NOTE: this lock will be held while doing long operations (trawling
1092     * through all processes in /proc), so it should never be acquired by
1093     * any critical paths such as when holding the main activity manager lock.
1094     */
1095    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1096            MONITOR_THREAD_CPU_USAGE);
1097    final AtomicLong mLastCpuTime = new AtomicLong(0);
1098    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1099
1100    long mLastWriteTime = 0;
1101
1102    /**
1103     * Used to retain an update lock when the foreground activity is in
1104     * immersive mode.
1105     */
1106    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1107
1108    /**
1109     * Set to true after the system has finished booting.
1110     */
1111    boolean mBooted = false;
1112
1113    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1114    int mProcessLimitOverride = -1;
1115
1116    WindowManagerService mWindowManager;
1117
1118    final ActivityThread mSystemThread;
1119
1120    // Holds the current foreground user's id
1121    int mCurrentUserId = 0;
1122    // Holds the target user's id during a user switch
1123    int mTargetUserId = UserHandle.USER_NULL;
1124    // If there are multiple profiles for the current user, their ids are here
1125    // Currently only the primary user can have managed profiles
1126    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1127
1128    /**
1129     * Mapping from each known user ID to the profile group ID it is associated with.
1130     */
1131    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1132
1133    private UserManagerService mUserManager;
1134
1135    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1136        final ProcessRecord mApp;
1137        final int mPid;
1138        final IApplicationThread mAppThread;
1139
1140        AppDeathRecipient(ProcessRecord app, int pid,
1141                IApplicationThread thread) {
1142            if (localLOGV) Slog.v(
1143                TAG, "New death recipient " + this
1144                + " for thread " + thread.asBinder());
1145            mApp = app;
1146            mPid = pid;
1147            mAppThread = thread;
1148        }
1149
1150        @Override
1151        public void binderDied() {
1152            if (localLOGV) Slog.v(
1153                TAG, "Death received in " + this
1154                + " for thread " + mAppThread.asBinder());
1155            synchronized(ActivityManagerService.this) {
1156                appDiedLocked(mApp, mPid, mAppThread);
1157            }
1158        }
1159    }
1160
1161    static final int SHOW_ERROR_MSG = 1;
1162    static final int SHOW_NOT_RESPONDING_MSG = 2;
1163    static final int SHOW_FACTORY_ERROR_MSG = 3;
1164    static final int UPDATE_CONFIGURATION_MSG = 4;
1165    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1166    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1167    static final int SERVICE_TIMEOUT_MSG = 12;
1168    static final int UPDATE_TIME_ZONE = 13;
1169    static final int SHOW_UID_ERROR_MSG = 14;
1170    static final int IM_FEELING_LUCKY_MSG = 15;
1171    static final int PROC_START_TIMEOUT_MSG = 20;
1172    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1173    static final int KILL_APPLICATION_MSG = 22;
1174    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1175    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1176    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1177    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1178    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1179    static final int CLEAR_DNS_CACHE_MSG = 28;
1180    static final int UPDATE_HTTP_PROXY_MSG = 29;
1181    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1182    static final int DISPATCH_PROCESSES_CHANGED = 31;
1183    static final int DISPATCH_PROCESS_DIED = 32;
1184    static final int REPORT_MEM_USAGE_MSG = 33;
1185    static final int REPORT_USER_SWITCH_MSG = 34;
1186    static final int CONTINUE_USER_SWITCH_MSG = 35;
1187    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1188    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1189    static final int PERSIST_URI_GRANTS_MSG = 38;
1190    static final int REQUEST_ALL_PSS_MSG = 39;
1191    static final int START_PROFILES_MSG = 40;
1192    static final int UPDATE_TIME = 41;
1193    static final int SYSTEM_USER_START_MSG = 42;
1194    static final int SYSTEM_USER_CURRENT_MSG = 43;
1195    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1196    static final int FINISH_BOOTING_MSG = 45;
1197    static final int START_USER_SWITCH_MSG = 46;
1198    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1199
1200    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1201    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1202    static final int FIRST_COMPAT_MODE_MSG = 300;
1203    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1204
1205    AlertDialog mUidAlert;
1206    CompatModeDialog mCompatModeDialog;
1207    long mLastMemUsageReportTime = 0;
1208
1209    private LockToAppRequestDialog mLockToAppRequest;
1210
1211    /**
1212     * Flag whether the current user is a "monkey", i.e. whether
1213     * the UI is driven by a UI automation tool.
1214     */
1215    private boolean mUserIsMonkey;
1216
1217    /** Flag whether the device has a Recents UI */
1218    boolean mHasRecents;
1219
1220    /** The dimensions of the thumbnails in the Recents UI. */
1221    int mThumbnailWidth;
1222    int mThumbnailHeight;
1223
1224    final ServiceThread mHandlerThread;
1225    final MainHandler mHandler;
1226
1227    final class MainHandler extends Handler {
1228        public MainHandler(Looper looper) {
1229            super(looper, null, true);
1230        }
1231
1232        @Override
1233        public void handleMessage(Message msg) {
1234            switch (msg.what) {
1235            case SHOW_ERROR_MSG: {
1236                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1238                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1239                synchronized (ActivityManagerService.this) {
1240                    ProcessRecord proc = (ProcessRecord)data.get("app");
1241                    AppErrorResult res = (AppErrorResult) data.get("result");
1242                    if (proc != null && proc.crashDialog != null) {
1243                        Slog.e(TAG, "App already has crash dialog: " + proc);
1244                        if (res != null) {
1245                            res.set(0);
1246                        }
1247                        return;
1248                    }
1249                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1250                            >= Process.FIRST_APPLICATION_UID
1251                            && proc.pid != MY_PID);
1252                    for (int userId : mCurrentProfileIds) {
1253                        isBackground &= (proc.userId != userId);
1254                    }
1255                    if (isBackground && !showBackground) {
1256                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1257                        if (res != null) {
1258                            res.set(0);
1259                        }
1260                        return;
1261                    }
1262                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1263                        Dialog d = new AppErrorDialog(mContext,
1264                                ActivityManagerService.this, res, proc);
1265                        d.show();
1266                        proc.crashDialog = d;
1267                    } else {
1268                        // The device is asleep, so just pretend that the user
1269                        // saw a crash dialog and hit "force quit".
1270                        if (res != null) {
1271                            res.set(0);
1272                        }
1273                    }
1274                }
1275
1276                ensureBootCompleted();
1277            } break;
1278            case SHOW_NOT_RESPONDING_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1281                    ProcessRecord proc = (ProcessRecord)data.get("app");
1282                    if (proc != null && proc.anrDialog != null) {
1283                        Slog.e(TAG, "App already has anr dialog: " + proc);
1284                        return;
1285                    }
1286
1287                    Intent intent = new Intent("android.intent.action.ANR");
1288                    if (!mProcessesReady) {
1289                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1290                                | Intent.FLAG_RECEIVER_FOREGROUND);
1291                    }
1292                    broadcastIntentLocked(null, null, intent,
1293                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1294                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1295
1296                    if (mShowDialogs) {
1297                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1298                                mContext, proc, (ActivityRecord)data.get("activity"),
1299                                msg.arg1 != 0);
1300                        d.show();
1301                        proc.anrDialog = d;
1302                    } else {
1303                        // Just kill the app if there is no dialog to be shown.
1304                        killAppAtUsersRequest(proc, null);
1305                    }
1306                }
1307
1308                ensureBootCompleted();
1309            } break;
1310            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1311                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord proc = (ProcessRecord) data.get("app");
1314                    if (proc == null) {
1315                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1316                        break;
1317                    }
1318                    if (proc.crashDialog != null) {
1319                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1320                        return;
1321                    }
1322                    AppErrorResult res = (AppErrorResult) data.get("result");
1323                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1324                        Dialog d = new StrictModeViolationDialog(mContext,
1325                                ActivityManagerService.this, res, proc);
1326                        d.show();
1327                        proc.crashDialog = d;
1328                    } else {
1329                        // The device is asleep, so just pretend that the user
1330                        // saw a crash dialog and hit "force quit".
1331                        res.set(0);
1332                    }
1333                }
1334                ensureBootCompleted();
1335            } break;
1336            case SHOW_FACTORY_ERROR_MSG: {
1337                Dialog d = new FactoryErrorDialog(
1338                    mContext, msg.getData().getCharSequence("msg"));
1339                d.show();
1340                ensureBootCompleted();
1341            } break;
1342            case UPDATE_CONFIGURATION_MSG: {
1343                final ContentResolver resolver = mContext.getContentResolver();
1344                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1345            } break;
1346            case GC_BACKGROUND_PROCESSES_MSG: {
1347                synchronized (ActivityManagerService.this) {
1348                    performAppGcsIfAppropriateLocked();
1349                }
1350            } break;
1351            case WAIT_FOR_DEBUGGER_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    ProcessRecord app = (ProcessRecord)msg.obj;
1354                    if (msg.arg1 != 0) {
1355                        if (!app.waitedForDebugger) {
1356                            Dialog d = new AppWaitingForDebuggerDialog(
1357                                    ActivityManagerService.this,
1358                                    mContext, app);
1359                            app.waitDialog = d;
1360                            app.waitedForDebugger = true;
1361                            d.show();
1362                        }
1363                    } else {
1364                        if (app.waitDialog != null) {
1365                            app.waitDialog.dismiss();
1366                            app.waitDialog = null;
1367                        }
1368                    }
1369                }
1370            } break;
1371            case SERVICE_TIMEOUT_MSG: {
1372                if (mDidDexOpt) {
1373                    mDidDexOpt = false;
1374                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1375                    nmsg.obj = msg.obj;
1376                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1377                    return;
1378                }
1379                mServices.serviceTimeout((ProcessRecord)msg.obj);
1380            } break;
1381            case UPDATE_TIME_ZONE: {
1382                synchronized (ActivityManagerService.this) {
1383                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1384                        ProcessRecord r = mLruProcesses.get(i);
1385                        if (r.thread != null) {
1386                            try {
1387                                r.thread.updateTimeZone();
1388                            } catch (RemoteException ex) {
1389                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case CLEAR_DNS_CACHE_MSG: {
1396                synchronized (ActivityManagerService.this) {
1397                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1398                        ProcessRecord r = mLruProcesses.get(i);
1399                        if (r.thread != null) {
1400                            try {
1401                                r.thread.clearDnsCache();
1402                            } catch (RemoteException ex) {
1403                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1404                            }
1405                        }
1406                    }
1407                }
1408            } break;
1409            case UPDATE_HTTP_PROXY_MSG: {
1410                ProxyInfo proxy = (ProxyInfo)msg.obj;
1411                String host = "";
1412                String port = "";
1413                String exclList = "";
1414                Uri pacFileUrl = Uri.EMPTY;
1415                if (proxy != null) {
1416                    host = proxy.getHost();
1417                    port = Integer.toString(proxy.getPort());
1418                    exclList = proxy.getExclusionListAsString();
1419                    pacFileUrl = proxy.getPacFileUrl();
1420                }
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update http proxy for: " +
1429                                        r.info.processName);
1430                            }
1431                        }
1432                    }
1433                }
1434            } break;
1435            case SHOW_UID_ERROR_MSG: {
1436                String title = "System UIDs Inconsistent";
1437                String text = "UIDs on the system are inconsistent, you need to wipe your"
1438                        + " data partition or your device will be unstable.";
1439                Log.e(TAG, title + ": " + text);
1440                if (mShowDialogs) {
1441                    // XXX This is a temporary dialog, no need to localize.
1442                    AlertDialog d = new BaseErrorDialog(mContext);
1443                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1444                    d.setCancelable(false);
1445                    d.setTitle(title);
1446                    d.setMessage(text);
1447                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1448                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1449                    mUidAlert = d;
1450                    d.show();
1451                }
1452            } break;
1453            case IM_FEELING_LUCKY_MSG: {
1454                if (mUidAlert != null) {
1455                    mUidAlert.dismiss();
1456                    mUidAlert = null;
1457                }
1458            } break;
1459            case PROC_START_TIMEOUT_MSG: {
1460                if (mDidDexOpt) {
1461                    mDidDexOpt = false;
1462                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1463                    nmsg.obj = msg.obj;
1464                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1465                    return;
1466                }
1467                ProcessRecord app = (ProcessRecord)msg.obj;
1468                synchronized (ActivityManagerService.this) {
1469                    processStartTimedOutLocked(app);
1470                }
1471            } break;
1472            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1473                synchronized (ActivityManagerService.this) {
1474                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1475                }
1476            } break;
1477            case KILL_APPLICATION_MSG: {
1478                synchronized (ActivityManagerService.this) {
1479                    int appid = msg.arg1;
1480                    boolean restart = (msg.arg2 == 1);
1481                    Bundle bundle = (Bundle)msg.obj;
1482                    String pkg = bundle.getString("pkg");
1483                    String reason = bundle.getString("reason");
1484                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1485                            false, UserHandle.USER_ALL, reason);
1486                }
1487            } break;
1488            case FINALIZE_PENDING_INTENT_MSG: {
1489                ((PendingIntentRecord)msg.obj).completeFinalize();
1490            } break;
1491            case POST_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496
1497                ActivityRecord root = (ActivityRecord)msg.obj;
1498                ProcessRecord process = root.app;
1499                if (process == null) {
1500                    return;
1501                }
1502
1503                try {
1504                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1505                    String text = mContext.getString(R.string.heavy_weight_notification,
1506                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1507                    Notification notification = new Notification();
1508                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1509                    notification.when = 0;
1510                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1511                    notification.tickerText = text;
1512                    notification.defaults = 0; // please be quiet
1513                    notification.sound = null;
1514                    notification.vibrate = null;
1515                    notification.color = mContext.getResources().getColor(
1516                            com.android.internal.R.color.system_notification_accent_color);
1517                    notification.setLatestEventInfo(context, text,
1518                            mContext.getText(R.string.heavy_weight_notification_detail),
1519                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1520                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1521                                    new UserHandle(root.userId)));
1522
1523                    try {
1524                        int[] outId = new int[1];
1525                        inm.enqueueNotificationWithTag("android", "android", null,
1526                                R.string.heavy_weight_notification,
1527                                notification, outId, root.userId);
1528                    } catch (RuntimeException e) {
1529                        Slog.w(ActivityManagerService.TAG,
1530                                "Error showing notification for heavy-weight app", e);
1531                    } catch (RemoteException e) {
1532                    }
1533                } catch (NameNotFoundException e) {
1534                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1535                }
1536            } break;
1537            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1538                INotificationManager inm = NotificationManager.getService();
1539                if (inm == null) {
1540                    return;
1541                }
1542                try {
1543                    inm.cancelNotificationWithTag("android", null,
1544                            R.string.heavy_weight_notification,  msg.arg1);
1545                } catch (RuntimeException e) {
1546                    Slog.w(ActivityManagerService.TAG,
1547                            "Error canceling notification for service", e);
1548                } catch (RemoteException e) {
1549                }
1550            } break;
1551            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1552                synchronized (ActivityManagerService.this) {
1553                    checkExcessivePowerUsageLocked(true);
1554                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1555                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1556                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1557                }
1558            } break;
1559            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    ActivityRecord ar = (ActivityRecord)msg.obj;
1562                    if (mCompatModeDialog != null) {
1563                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1564                                ar.info.applicationInfo.packageName)) {
1565                            return;
1566                        }
1567                        mCompatModeDialog.dismiss();
1568                        mCompatModeDialog = null;
1569                    }
1570                    if (ar != null && false) {
1571                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1572                                ar.packageName)) {
1573                            int mode = mCompatModePackages.computeCompatModeLocked(
1574                                    ar.info.applicationInfo);
1575                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1576                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1577                                mCompatModeDialog = new CompatModeDialog(
1578                                        ActivityManagerService.this, mContext,
1579                                        ar.info.applicationInfo);
1580                                mCompatModeDialog.show();
1581                            }
1582                        }
1583                    }
1584                }
1585                break;
1586            }
1587            case DISPATCH_PROCESSES_CHANGED: {
1588                dispatchProcessesChanged();
1589                break;
1590            }
1591            case DISPATCH_PROCESS_DIED: {
1592                final int pid = msg.arg1;
1593                final int uid = msg.arg2;
1594                dispatchProcessDied(pid, uid);
1595                break;
1596            }
1597            case REPORT_MEM_USAGE_MSG: {
1598                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1599                Thread thread = new Thread() {
1600                    @Override public void run() {
1601                        final SparseArray<ProcessMemInfo> infoMap
1602                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1603                        for (int i=0, N=memInfos.size(); i<N; i++) {
1604                            ProcessMemInfo mi = memInfos.get(i);
1605                            infoMap.put(mi.pid, mi);
1606                        }
1607                        updateCpuStatsNow();
1608                        synchronized (mProcessCpuTracker) {
1609                            final int N = mProcessCpuTracker.countStats();
1610                            for (int i=0; i<N; i++) {
1611                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1612                                if (st.vsize > 0) {
1613                                    long pss = Debug.getPss(st.pid, null);
1614                                    if (pss > 0) {
1615                                        if (infoMap.indexOfKey(st.pid) < 0) {
1616                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1617                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1618                                            mi.pss = pss;
1619                                            memInfos.add(mi);
1620                                        }
1621                                    }
1622                                }
1623                            }
1624                        }
1625
1626                        long totalPss = 0;
1627                        for (int i=0, N=memInfos.size(); i<N; i++) {
1628                            ProcessMemInfo mi = memInfos.get(i);
1629                            if (mi.pss == 0) {
1630                                mi.pss = Debug.getPss(mi.pid, null);
1631                            }
1632                            totalPss += mi.pss;
1633                        }
1634                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1635                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1636                                if (lhs.oomAdj != rhs.oomAdj) {
1637                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1638                                }
1639                                if (lhs.pss != rhs.pss) {
1640                                    return lhs.pss < rhs.pss ? 1 : -1;
1641                                }
1642                                return 0;
1643                            }
1644                        });
1645
1646                        StringBuilder tag = new StringBuilder(128);
1647                        StringBuilder stack = new StringBuilder(128);
1648                        tag.append("Low on memory -- ");
1649                        appendMemBucket(tag, totalPss, "total", false);
1650                        appendMemBucket(stack, totalPss, "total", true);
1651
1652                        StringBuilder logBuilder = new StringBuilder(1024);
1653                        logBuilder.append("Low on memory:\n");
1654
1655                        boolean firstLine = true;
1656                        int lastOomAdj = Integer.MIN_VALUE;
1657                        for (int i=0, N=memInfos.size(); i<N; i++) {
1658                            ProcessMemInfo mi = memInfos.get(i);
1659
1660                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1661                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1662                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1663                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1664                                if (lastOomAdj != mi.oomAdj) {
1665                                    lastOomAdj = mi.oomAdj;
1666                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1667                                        tag.append(" / ");
1668                                    }
1669                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1670                                        if (firstLine) {
1671                                            stack.append(":");
1672                                            firstLine = false;
1673                                        }
1674                                        stack.append("\n\t at ");
1675                                    } else {
1676                                        stack.append("$");
1677                                    }
1678                                } else {
1679                                    tag.append(" ");
1680                                    stack.append("$");
1681                                }
1682                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1683                                    appendMemBucket(tag, mi.pss, mi.name, false);
1684                                }
1685                                appendMemBucket(stack, mi.pss, mi.name, true);
1686                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1687                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1688                                    stack.append("(");
1689                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1690                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1691                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1692                                            stack.append(":");
1693                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1694                                        }
1695                                    }
1696                                    stack.append(")");
1697                                }
1698                            }
1699
1700                            logBuilder.append("  ");
1701                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1702                            logBuilder.append(' ');
1703                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1704                            logBuilder.append(' ');
1705                            ProcessList.appendRamKb(logBuilder, mi.pss);
1706                            logBuilder.append(" kB: ");
1707                            logBuilder.append(mi.name);
1708                            logBuilder.append(" (");
1709                            logBuilder.append(mi.pid);
1710                            logBuilder.append(") ");
1711                            logBuilder.append(mi.adjType);
1712                            logBuilder.append('\n');
1713                            if (mi.adjReason != null) {
1714                                logBuilder.append("                      ");
1715                                logBuilder.append(mi.adjReason);
1716                                logBuilder.append('\n');
1717                            }
1718                        }
1719
1720                        logBuilder.append("           ");
1721                        ProcessList.appendRamKb(logBuilder, totalPss);
1722                        logBuilder.append(" kB: TOTAL\n");
1723
1724                        long[] infos = new long[Debug.MEMINFO_COUNT];
1725                        Debug.getMemInfo(infos);
1726                        logBuilder.append("  MemInfo: ");
1727                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1728                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1729                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1730                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1732                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1733                            logBuilder.append("  ZRAM: ");
1734                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1735                            logBuilder.append(" kB RAM, ");
1736                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1737                            logBuilder.append(" kB swap total, ");
1738                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1739                            logBuilder.append(" kB swap free\n");
1740                        }
1741                        Slog.i(TAG, logBuilder.toString());
1742
1743                        StringBuilder dropBuilder = new StringBuilder(1024);
1744                        /*
1745                        StringWriter oomSw = new StringWriter();
1746                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1747                        StringWriter catSw = new StringWriter();
1748                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1749                        String[] emptyArgs = new String[] { };
1750                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1751                        oomPw.flush();
1752                        String oomString = oomSw.toString();
1753                        */
1754                        dropBuilder.append(stack);
1755                        dropBuilder.append('\n');
1756                        dropBuilder.append('\n');
1757                        dropBuilder.append(logBuilder);
1758                        dropBuilder.append('\n');
1759                        /*
1760                        dropBuilder.append(oomString);
1761                        dropBuilder.append('\n');
1762                        */
1763                        StringWriter catSw = new StringWriter();
1764                        synchronized (ActivityManagerService.this) {
1765                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1766                            String[] emptyArgs = new String[] { };
1767                            catPw.println();
1768                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1769                            catPw.println();
1770                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1771                                    false, false, null);
1772                            catPw.println();
1773                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1774                            catPw.flush();
1775                        }
1776                        dropBuilder.append(catSw.toString());
1777                        addErrorToDropBox("lowmem", null, "system_server", null,
1778                                null, tag.toString(), dropBuilder.toString(), null, null);
1779                        //Slog.i(TAG, "Sent to dropbox:");
1780                        //Slog.i(TAG, dropBuilder.toString());
1781                        synchronized (ActivityManagerService.this) {
1782                            long now = SystemClock.uptimeMillis();
1783                            if (mLastMemUsageReportTime < now) {
1784                                mLastMemUsageReportTime = now;
1785                            }
1786                        }
1787                    }
1788                };
1789                thread.start();
1790                break;
1791            }
1792            case START_USER_SWITCH_MSG: {
1793                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1794                break;
1795            }
1796            case REPORT_USER_SWITCH_MSG: {
1797                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case CONTINUE_USER_SWITCH_MSG: {
1801                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1802                break;
1803            }
1804            case USER_SWITCH_TIMEOUT_MSG: {
1805                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1806                break;
1807            }
1808            case IMMERSIVE_MODE_LOCK_MSG: {
1809                final boolean nextState = (msg.arg1 != 0);
1810                if (mUpdateLock.isHeld() != nextState) {
1811                    if (DEBUG_IMMERSIVE) {
1812                        final ActivityRecord r = (ActivityRecord) msg.obj;
1813                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1814                    }
1815                    if (nextState) {
1816                        mUpdateLock.acquire();
1817                    } else {
1818                        mUpdateLock.release();
1819                    }
1820                }
1821                break;
1822            }
1823            case PERSIST_URI_GRANTS_MSG: {
1824                writeGrantedUriPermissions();
1825                break;
1826            }
1827            case REQUEST_ALL_PSS_MSG: {
1828                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1829                break;
1830            }
1831            case START_PROFILES_MSG: {
1832                synchronized (ActivityManagerService.this) {
1833                    startProfilesLocked();
1834                }
1835                break;
1836            }
1837            case UPDATE_TIME: {
1838                synchronized (ActivityManagerService.this) {
1839                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1840                        ProcessRecord r = mLruProcesses.get(i);
1841                        if (r.thread != null) {
1842                            try {
1843                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1844                            } catch (RemoteException ex) {
1845                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1846                            }
1847                        }
1848                    }
1849                }
1850                break;
1851            }
1852            case SYSTEM_USER_START_MSG: {
1853                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1854                        Integer.toString(msg.arg1), msg.arg1);
1855                mSystemServiceManager.startUser(msg.arg1);
1856                break;
1857            }
1858            case SYSTEM_USER_CURRENT_MSG: {
1859                mBatteryStatsService.noteEvent(
1860                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1861                        Integer.toString(msg.arg2), msg.arg2);
1862                mBatteryStatsService.noteEvent(
1863                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1864                        Integer.toString(msg.arg1), msg.arg1);
1865                mSystemServiceManager.switchUser(msg.arg1);
1866                mLockToAppRequest.clearPrompt();
1867                break;
1868            }
1869            case ENTER_ANIMATION_COMPLETE_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1872                    if (r != null && r.app != null && r.app.thread != null) {
1873                        try {
1874                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1875                        } catch (RemoteException e) {
1876                        }
1877                    }
1878                }
1879                break;
1880            }
1881            case FINISH_BOOTING_MSG: {
1882                if (msg.arg1 != 0) {
1883                    finishBooting();
1884                }
1885                if (msg.arg2 != 0) {
1886                    enableScreenAfterBoot();
1887                }
1888                break;
1889            }
1890            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1891                try {
1892                    Locale l = (Locale) msg.obj;
1893                    IBinder service = ServiceManager.getService("mount");
1894                    IMountService mountService = IMountService.Stub.asInterface(service);
1895                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1896                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1897                } catch (RemoteException e) {
1898                    Log.e(TAG, "Error storing locale for decryption UI", e);
1899                }
1900                break;
1901            }
1902            }
1903        }
1904    };
1905
1906    static final int COLLECT_PSS_BG_MSG = 1;
1907
1908    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1909        @Override
1910        public void handleMessage(Message msg) {
1911            switch (msg.what) {
1912            case COLLECT_PSS_BG_MSG: {
1913                long start = SystemClock.uptimeMillis();
1914                MemInfoReader memInfo = null;
1915                synchronized (ActivityManagerService.this) {
1916                    if (mFullPssPending) {
1917                        mFullPssPending = false;
1918                        memInfo = new MemInfoReader();
1919                    }
1920                }
1921                if (memInfo != null) {
1922                    updateCpuStatsNow();
1923                    long nativeTotalPss = 0;
1924                    synchronized (mProcessCpuTracker) {
1925                        final int N = mProcessCpuTracker.countStats();
1926                        for (int j=0; j<N; j++) {
1927                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1928                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1929                                // This is definitely an application process; skip it.
1930                                continue;
1931                            }
1932                            synchronized (mPidsSelfLocked) {
1933                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1934                                    // This is one of our own processes; skip it.
1935                                    continue;
1936                                }
1937                            }
1938                            nativeTotalPss += Debug.getPss(st.pid, null);
1939                        }
1940                    }
1941                    memInfo.readMemInfo();
1942                    synchronized (ActivityManagerService.this) {
1943                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1944                                + (SystemClock.uptimeMillis()-start) + "ms");
1945                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1946                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1947                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1948                                        +memInfo.getSlabSizeKb(),
1949                                nativeTotalPss);
1950                    }
1951                }
1952
1953                int i=0, num=0;
1954                long[] tmp = new long[1];
1955                do {
1956                    ProcessRecord proc;
1957                    int procState;
1958                    int pid;
1959                    synchronized (ActivityManagerService.this) {
1960                        if (i >= mPendingPssProcesses.size()) {
1961                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1962                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1963                            mPendingPssProcesses.clear();
1964                            return;
1965                        }
1966                        proc = mPendingPssProcesses.get(i);
1967                        procState = proc.pssProcState;
1968                        if (proc.thread != null && procState == proc.setProcState) {
1969                            pid = proc.pid;
1970                        } else {
1971                            proc = null;
1972                            pid = 0;
1973                        }
1974                        i++;
1975                    }
1976                    if (proc != null) {
1977                        long pss = Debug.getPss(pid, tmp);
1978                        synchronized (ActivityManagerService.this) {
1979                            if (proc.thread != null && proc.setProcState == procState
1980                                    && proc.pid == pid) {
1981                                num++;
1982                                proc.lastPssTime = SystemClock.uptimeMillis();
1983                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1984                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1985                                        + ": " + pss + " lastPss=" + proc.lastPss
1986                                        + " state=" + ProcessList.makeProcStateString(procState));
1987                                if (proc.initialIdlePss == 0) {
1988                                    proc.initialIdlePss = pss;
1989                                }
1990                                proc.lastPss = pss;
1991                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1992                                    proc.lastCachedPss = pss;
1993                                }
1994                            }
1995                        }
1996                    }
1997                } while (true);
1998            }
1999            }
2000        }
2001    };
2002
2003    /**
2004     * Monitor for package changes and update our internal state.
2005     */
2006    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2007        @Override
2008        public void onPackageRemoved(String packageName, int uid) {
2009            // Remove all tasks with activities in the specified package from the list of recent tasks
2010            final int eventUserId = getChangingUserId();
2011            synchronized (ActivityManagerService.this) {
2012                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2013                    TaskRecord tr = mRecentTasks.get(i);
2014                    if (tr.userId != eventUserId) continue;
2015
2016                    ComponentName cn = tr.intent.getComponent();
2017                    if (cn != null && cn.getPackageName().equals(packageName)) {
2018                        // If the package name matches, remove the task and kill the process
2019                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2020                    }
2021                }
2022            }
2023        }
2024
2025        @Override
2026        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2027            onPackageModified(packageName);
2028            return true;
2029        }
2030
2031        @Override
2032        public void onPackageModified(String packageName) {
2033            final int eventUserId = getChangingUserId();
2034            final IPackageManager pm = AppGlobals.getPackageManager();
2035            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2036                    new ArrayList<Pair<Intent, Integer>>();
2037            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2038            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2039            // Copy the list of recent tasks so that we don't hold onto the lock on
2040            // ActivityManagerService for long periods while checking if components exist.
2041            synchronized (ActivityManagerService.this) {
2042                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2043                    TaskRecord tr = mRecentTasks.get(i);
2044                    if (tr.userId != eventUserId) continue;
2045
2046                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2047                }
2048            }
2049            // Check the recent tasks and filter out all tasks with components that no longer exist.
2050            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2051                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2052                ComponentName cn = p.first.getComponent();
2053                if (cn != null && cn.getPackageName().equals(packageName)) {
2054                    if (componentsKnownToExist.contains(cn)) {
2055                        // If we know that the component still exists in the package, then skip
2056                        continue;
2057                    }
2058                    try {
2059                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2060                        if (info != null) {
2061                            componentsKnownToExist.add(cn);
2062                        } else {
2063                            tasksToRemove.add(p.second);
2064                        }
2065                    } catch (RemoteException e) {
2066                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2067                    }
2068                }
2069            }
2070            // Prune all the tasks with removed components from the list of recent tasks
2071            synchronized (ActivityManagerService.this) {
2072                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2073                    // Remove the task but don't kill the process (since other components in that
2074                    // package may still be running and in the background)
2075                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2076                }
2077            }
2078        }
2079
2080        @Override
2081        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2082            // Force stop the specified packages
2083            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2084            if (packages != null) {
2085                for (String pkg : packages) {
2086                    synchronized (ActivityManagerService.this) {
2087                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2088                                userId, "finished booting")) {
2089                            return true;
2090                        }
2091                    }
2092                }
2093            }
2094            return false;
2095        }
2096    };
2097
2098    public void setSystemProcess() {
2099        try {
2100            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2101            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2102            ServiceManager.addService("meminfo", new MemBinder(this));
2103            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2104            ServiceManager.addService("dbinfo", new DbBinder(this));
2105            if (MONITOR_CPU_USAGE) {
2106                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2107            }
2108            ServiceManager.addService("permission", new PermissionController(this));
2109
2110            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2111                    "android", STOCK_PM_FLAGS);
2112            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2113
2114            synchronized (this) {
2115                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2116                app.persistent = true;
2117                app.pid = MY_PID;
2118                app.maxAdj = ProcessList.SYSTEM_ADJ;
2119                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2120                mProcessNames.put(app.processName, app.uid, app);
2121                synchronized (mPidsSelfLocked) {
2122                    mPidsSelfLocked.put(app.pid, app);
2123                }
2124                updateLruProcessLocked(app, false, null);
2125                updateOomAdjLocked();
2126            }
2127        } catch (PackageManager.NameNotFoundException e) {
2128            throw new RuntimeException(
2129                    "Unable to find android system package", e);
2130        }
2131    }
2132
2133    public void setWindowManager(WindowManagerService wm) {
2134        mWindowManager = wm;
2135        mStackSupervisor.setWindowManager(wm);
2136    }
2137
2138    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2139        mUsageStatsService = usageStatsManager;
2140    }
2141
2142    public void startObservingNativeCrashes() {
2143        final NativeCrashListener ncl = new NativeCrashListener(this);
2144        ncl.start();
2145    }
2146
2147    public IAppOpsService getAppOpsService() {
2148        return mAppOpsService;
2149    }
2150
2151    static class MemBinder extends Binder {
2152        ActivityManagerService mActivityManagerService;
2153        MemBinder(ActivityManagerService activityManagerService) {
2154            mActivityManagerService = activityManagerService;
2155        }
2156
2157        @Override
2158        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2159            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2160                    != PackageManager.PERMISSION_GRANTED) {
2161                pw.println("Permission Denial: can't dump meminfo from from pid="
2162                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2163                        + " without permission " + android.Manifest.permission.DUMP);
2164                return;
2165            }
2166
2167            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2168        }
2169    }
2170
2171    static class GraphicsBinder extends Binder {
2172        ActivityManagerService mActivityManagerService;
2173        GraphicsBinder(ActivityManagerService activityManagerService) {
2174            mActivityManagerService = activityManagerService;
2175        }
2176
2177        @Override
2178        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2179            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2180                    != PackageManager.PERMISSION_GRANTED) {
2181                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2182                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2183                        + " without permission " + android.Manifest.permission.DUMP);
2184                return;
2185            }
2186
2187            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2188        }
2189    }
2190
2191    static class DbBinder extends Binder {
2192        ActivityManagerService mActivityManagerService;
2193        DbBinder(ActivityManagerService activityManagerService) {
2194            mActivityManagerService = activityManagerService;
2195        }
2196
2197        @Override
2198        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2199            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2200                    != PackageManager.PERMISSION_GRANTED) {
2201                pw.println("Permission Denial: can't dump dbinfo from from pid="
2202                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2203                        + " without permission " + android.Manifest.permission.DUMP);
2204                return;
2205            }
2206
2207            mActivityManagerService.dumpDbInfo(fd, pw, args);
2208        }
2209    }
2210
2211    static class CpuBinder extends Binder {
2212        ActivityManagerService mActivityManagerService;
2213        CpuBinder(ActivityManagerService activityManagerService) {
2214            mActivityManagerService = activityManagerService;
2215        }
2216
2217        @Override
2218        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2219            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2220                    != PackageManager.PERMISSION_GRANTED) {
2221                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2222                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2223                        + " without permission " + android.Manifest.permission.DUMP);
2224                return;
2225            }
2226
2227            synchronized (mActivityManagerService.mProcessCpuTracker) {
2228                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2229                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2230                        SystemClock.uptimeMillis()));
2231            }
2232        }
2233    }
2234
2235    public static final class Lifecycle extends SystemService {
2236        private final ActivityManagerService mService;
2237
2238        public Lifecycle(Context context) {
2239            super(context);
2240            mService = new ActivityManagerService(context);
2241        }
2242
2243        @Override
2244        public void onStart() {
2245            mService.start();
2246        }
2247
2248        public ActivityManagerService getService() {
2249            return mService;
2250        }
2251    }
2252
2253    // Note: This method is invoked on the main thread but may need to attach various
2254    // handlers to other threads.  So take care to be explicit about the looper.
2255    public ActivityManagerService(Context systemContext) {
2256        mContext = systemContext;
2257        mFactoryTest = FactoryTest.getMode();
2258        mSystemThread = ActivityThread.currentActivityThread();
2259
2260        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2261
2262        mHandlerThread = new ServiceThread(TAG,
2263                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2264        mHandlerThread.start();
2265        mHandler = new MainHandler(mHandlerThread.getLooper());
2266
2267        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2268                "foreground", BROADCAST_FG_TIMEOUT, false);
2269        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2270                "background", BROADCAST_BG_TIMEOUT, true);
2271        mBroadcastQueues[0] = mFgBroadcastQueue;
2272        mBroadcastQueues[1] = mBgBroadcastQueue;
2273
2274        mServices = new ActiveServices(this);
2275        mProviderMap = new ProviderMap(this);
2276
2277        // TODO: Move creation of battery stats service outside of activity manager service.
2278        File dataDir = Environment.getDataDirectory();
2279        File systemDir = new File(dataDir, "system");
2280        systemDir.mkdirs();
2281        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2282        mBatteryStatsService.getActiveStatistics().readLocked();
2283        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2284        mOnBattery = DEBUG_POWER ? true
2285                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2286        mBatteryStatsService.getActiveStatistics().setCallback(this);
2287
2288        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2289
2290        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2291
2292        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2293
2294        // User 0 is the first and only user that runs at boot.
2295        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2296        mUserLru.add(Integer.valueOf(0));
2297        updateStartedUserArrayLocked();
2298
2299        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2300            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2301
2302        mConfiguration.setToDefaults();
2303        mConfiguration.setLocale(Locale.getDefault());
2304
2305        mConfigurationSeq = mConfiguration.seq = 1;
2306        mProcessCpuTracker.init();
2307
2308        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2309        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2310        mStackSupervisor = new ActivityStackSupervisor(this);
2311        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2312
2313        mProcessCpuThread = new Thread("CpuTracker") {
2314            @Override
2315            public void run() {
2316                while (true) {
2317                    try {
2318                        try {
2319                            synchronized(this) {
2320                                final long now = SystemClock.uptimeMillis();
2321                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2322                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2323                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2324                                //        + ", write delay=" + nextWriteDelay);
2325                                if (nextWriteDelay < nextCpuDelay) {
2326                                    nextCpuDelay = nextWriteDelay;
2327                                }
2328                                if (nextCpuDelay > 0) {
2329                                    mProcessCpuMutexFree.set(true);
2330                                    this.wait(nextCpuDelay);
2331                                }
2332                            }
2333                        } catch (InterruptedException e) {
2334                        }
2335                        updateCpuStatsNow();
2336                    } catch (Exception e) {
2337                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2338                    }
2339                }
2340            }
2341        };
2342
2343        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2344
2345        Watchdog.getInstance().addMonitor(this);
2346        Watchdog.getInstance().addThread(mHandler);
2347    }
2348
2349    public void setSystemServiceManager(SystemServiceManager mgr) {
2350        mSystemServiceManager = mgr;
2351    }
2352
2353    private void start() {
2354        Process.removeAllProcessGroups();
2355        mProcessCpuThread.start();
2356
2357        mBatteryStatsService.publish(mContext);
2358        mAppOpsService.publish(mContext);
2359        Slog.d("AppOps", "AppOpsService published");
2360        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2361    }
2362
2363    public void initPowerManagement() {
2364        mStackSupervisor.initPowerManagement();
2365        mBatteryStatsService.initPowerManagement();
2366    }
2367
2368    @Override
2369    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2370            throws RemoteException {
2371        if (code == SYSPROPS_TRANSACTION) {
2372            // We need to tell all apps about the system property change.
2373            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2374            synchronized(this) {
2375                final int NP = mProcessNames.getMap().size();
2376                for (int ip=0; ip<NP; ip++) {
2377                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2378                    final int NA = apps.size();
2379                    for (int ia=0; ia<NA; ia++) {
2380                        ProcessRecord app = apps.valueAt(ia);
2381                        if (app.thread != null) {
2382                            procs.add(app.thread.asBinder());
2383                        }
2384                    }
2385                }
2386            }
2387
2388            int N = procs.size();
2389            for (int i=0; i<N; i++) {
2390                Parcel data2 = Parcel.obtain();
2391                try {
2392                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2393                } catch (RemoteException e) {
2394                }
2395                data2.recycle();
2396            }
2397        }
2398        try {
2399            return super.onTransact(code, data, reply, flags);
2400        } catch (RuntimeException e) {
2401            // The activity manager only throws security exceptions, so let's
2402            // log all others.
2403            if (!(e instanceof SecurityException)) {
2404                Slog.wtf(TAG, "Activity Manager Crash", e);
2405            }
2406            throw e;
2407        }
2408    }
2409
2410    void updateCpuStats() {
2411        final long now = SystemClock.uptimeMillis();
2412        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2413            return;
2414        }
2415        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2416            synchronized (mProcessCpuThread) {
2417                mProcessCpuThread.notify();
2418            }
2419        }
2420    }
2421
2422    void updateCpuStatsNow() {
2423        synchronized (mProcessCpuTracker) {
2424            mProcessCpuMutexFree.set(false);
2425            final long now = SystemClock.uptimeMillis();
2426            boolean haveNewCpuStats = false;
2427
2428            if (MONITOR_CPU_USAGE &&
2429                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2430                mLastCpuTime.set(now);
2431                haveNewCpuStats = true;
2432                mProcessCpuTracker.update();
2433                //Slog.i(TAG, mProcessCpu.printCurrentState());
2434                //Slog.i(TAG, "Total CPU usage: "
2435                //        + mProcessCpu.getTotalCpuPercent() + "%");
2436
2437                // Slog the cpu usage if the property is set.
2438                if ("true".equals(SystemProperties.get("events.cpu"))) {
2439                    int user = mProcessCpuTracker.getLastUserTime();
2440                    int system = mProcessCpuTracker.getLastSystemTime();
2441                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2442                    int irq = mProcessCpuTracker.getLastIrqTime();
2443                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2444                    int idle = mProcessCpuTracker.getLastIdleTime();
2445
2446                    int total = user + system + iowait + irq + softIrq + idle;
2447                    if (total == 0) total = 1;
2448
2449                    EventLog.writeEvent(EventLogTags.CPU,
2450                            ((user+system+iowait+irq+softIrq) * 100) / total,
2451                            (user * 100) / total,
2452                            (system * 100) / total,
2453                            (iowait * 100) / total,
2454                            (irq * 100) / total,
2455                            (softIrq * 100) / total);
2456                }
2457            }
2458
2459            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2460            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2461            synchronized(bstats) {
2462                synchronized(mPidsSelfLocked) {
2463                    if (haveNewCpuStats) {
2464                        if (mOnBattery) {
2465                            int perc = bstats.startAddingCpuLocked();
2466                            int totalUTime = 0;
2467                            int totalSTime = 0;
2468                            final int N = mProcessCpuTracker.countStats();
2469                            for (int i=0; i<N; i++) {
2470                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2471                                if (!st.working) {
2472                                    continue;
2473                                }
2474                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2475                                int otherUTime = (st.rel_utime*perc)/100;
2476                                int otherSTime = (st.rel_stime*perc)/100;
2477                                totalUTime += otherUTime;
2478                                totalSTime += otherSTime;
2479                                if (pr != null) {
2480                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2481                                    if (ps == null || !ps.isActive()) {
2482                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2483                                                pr.info.uid, pr.processName);
2484                                    }
2485                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2486                                            st.rel_stime-otherSTime);
2487                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2488                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2489                                } else {
2490                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2491                                    if (ps == null || !ps.isActive()) {
2492                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2493                                                bstats.mapUid(st.uid), st.name);
2494                                    }
2495                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2496                                            st.rel_stime-otherSTime);
2497                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2498                                }
2499                            }
2500                            bstats.finishAddingCpuLocked(perc, totalUTime,
2501                                    totalSTime, cpuSpeedTimes);
2502                        }
2503                    }
2504                }
2505
2506                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2507                    mLastWriteTime = now;
2508                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2509                }
2510            }
2511        }
2512    }
2513
2514    @Override
2515    public void batteryNeedsCpuUpdate() {
2516        updateCpuStatsNow();
2517    }
2518
2519    @Override
2520    public void batteryPowerChanged(boolean onBattery) {
2521        // When plugging in, update the CPU stats first before changing
2522        // the plug state.
2523        updateCpuStatsNow();
2524        synchronized (this) {
2525            synchronized(mPidsSelfLocked) {
2526                mOnBattery = DEBUG_POWER ? true : onBattery;
2527            }
2528        }
2529    }
2530
2531    /**
2532     * Initialize the application bind args. These are passed to each
2533     * process when the bindApplication() IPC is sent to the process. They're
2534     * lazily setup to make sure the services are running when they're asked for.
2535     */
2536    private HashMap<String, IBinder> getCommonServicesLocked() {
2537        if (mAppBindArgs == null) {
2538            mAppBindArgs = new HashMap<String, IBinder>();
2539
2540            // Setup the application init args
2541            mAppBindArgs.put("package", ServiceManager.getService("package"));
2542            mAppBindArgs.put("window", ServiceManager.getService("window"));
2543            mAppBindArgs.put(Context.ALARM_SERVICE,
2544                    ServiceManager.getService(Context.ALARM_SERVICE));
2545        }
2546        return mAppBindArgs;
2547    }
2548
2549    final void setFocusedActivityLocked(ActivityRecord r) {
2550        if (mFocusedActivity != r) {
2551            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2552            mFocusedActivity = r;
2553            if (r.task != null && r.task.voiceInteractor != null) {
2554                startRunningVoiceLocked();
2555            } else {
2556                finishRunningVoiceLocked();
2557            }
2558            mStackSupervisor.setFocusedStack(r);
2559            if (r != null) {
2560                mWindowManager.setFocusedApp(r.appToken, true);
2561            }
2562            applyUpdateLockStateLocked(r);
2563        }
2564    }
2565
2566    final void clearFocusedActivity(ActivityRecord r) {
2567        if (mFocusedActivity == r) {
2568            mFocusedActivity = null;
2569        }
2570    }
2571
2572    @Override
2573    public void setFocusedStack(int stackId) {
2574        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2575        synchronized (ActivityManagerService.this) {
2576            ActivityStack stack = mStackSupervisor.getStack(stackId);
2577            if (stack != null) {
2578                ActivityRecord r = stack.topRunningActivityLocked(null);
2579                if (r != null) {
2580                    setFocusedActivityLocked(r);
2581                }
2582            }
2583        }
2584    }
2585
2586    @Override
2587    public void notifyActivityDrawn(IBinder token) {
2588        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2589        synchronized (this) {
2590            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2591            if (r != null) {
2592                r.task.stack.notifyActivityDrawnLocked(r);
2593            }
2594        }
2595    }
2596
2597    final void applyUpdateLockStateLocked(ActivityRecord r) {
2598        // Modifications to the UpdateLock state are done on our handler, outside
2599        // the activity manager's locks.  The new state is determined based on the
2600        // state *now* of the relevant activity record.  The object is passed to
2601        // the handler solely for logging detail, not to be consulted/modified.
2602        final boolean nextState = r != null && r.immersive;
2603        mHandler.sendMessage(
2604                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2605    }
2606
2607    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2608        Message msg = Message.obtain();
2609        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2610        msg.obj = r.task.askedCompatMode ? null : r;
2611        mHandler.sendMessage(msg);
2612    }
2613
2614    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2615            String what, Object obj, ProcessRecord srcApp) {
2616        app.lastActivityTime = now;
2617
2618        if (app.activities.size() > 0) {
2619            // Don't want to touch dependent processes that are hosting activities.
2620            return index;
2621        }
2622
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624        if (lrui < 0) {
2625            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2626                    + what + " " + obj + " from " + srcApp);
2627            return index;
2628        }
2629
2630        if (lrui >= index) {
2631            // Don't want to cause this to move dependent processes *back* in the
2632            // list as if they were less frequently used.
2633            return index;
2634        }
2635
2636        if (lrui >= mLruProcessActivityStart) {
2637            // Don't want to touch dependent processes that are hosting activities.
2638            return index;
2639        }
2640
2641        mLruProcesses.remove(lrui);
2642        if (index > 0) {
2643            index--;
2644        }
2645        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2646                + " in LRU list: " + app);
2647        mLruProcesses.add(index, app);
2648        return index;
2649    }
2650
2651    final void removeLruProcessLocked(ProcessRecord app) {
2652        int lrui = mLruProcesses.lastIndexOf(app);
2653        if (lrui >= 0) {
2654            if (!app.killed) {
2655                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2656                Process.killProcessQuiet(app.pid);
2657                Process.killProcessGroup(app.info.uid, app.pid);
2658            }
2659            if (lrui <= mLruProcessActivityStart) {
2660                mLruProcessActivityStart--;
2661            }
2662            if (lrui <= mLruProcessServiceStart) {
2663                mLruProcessServiceStart--;
2664            }
2665            mLruProcesses.remove(lrui);
2666        }
2667    }
2668
2669    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2670            ProcessRecord client) {
2671        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2672                || app.treatLikeActivity;
2673        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2674        if (!activityChange && hasActivity) {
2675            // The process has activities, so we are only allowing activity-based adjustments
2676            // to move it.  It should be kept in the front of the list with other
2677            // processes that have activities, and we don't want those to change their
2678            // order except due to activity operations.
2679            return;
2680        }
2681
2682        mLruSeq++;
2683        final long now = SystemClock.uptimeMillis();
2684        app.lastActivityTime = now;
2685
2686        // First a quick reject: if the app is already at the position we will
2687        // put it, then there is nothing to do.
2688        if (hasActivity) {
2689            final int N = mLruProcesses.size();
2690            if (N > 0 && mLruProcesses.get(N-1) == app) {
2691                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2692                return;
2693            }
2694        } else {
2695            if (mLruProcessServiceStart > 0
2696                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2697                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2698                return;
2699            }
2700        }
2701
2702        int lrui = mLruProcesses.lastIndexOf(app);
2703
2704        if (app.persistent && lrui >= 0) {
2705            // We don't care about the position of persistent processes, as long as
2706            // they are in the list.
2707            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2708            return;
2709        }
2710
2711        /* In progress: compute new position first, so we can avoid doing work
2712           if the process is not actually going to move.  Not yet working.
2713        int addIndex;
2714        int nextIndex;
2715        boolean inActivity = false, inService = false;
2716        if (hasActivity) {
2717            // Process has activities, put it at the very tipsy-top.
2718            addIndex = mLruProcesses.size();
2719            nextIndex = mLruProcessServiceStart;
2720            inActivity = true;
2721        } else if (hasService) {
2722            // Process has services, put it at the top of the service list.
2723            addIndex = mLruProcessActivityStart;
2724            nextIndex = mLruProcessServiceStart;
2725            inActivity = true;
2726            inService = true;
2727        } else  {
2728            // Process not otherwise of interest, it goes to the top of the non-service area.
2729            addIndex = mLruProcessServiceStart;
2730            if (client != null) {
2731                int clientIndex = mLruProcesses.lastIndexOf(client);
2732                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2733                        + app);
2734                if (clientIndex >= 0 && addIndex > clientIndex) {
2735                    addIndex = clientIndex;
2736                }
2737            }
2738            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2739        }
2740
2741        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2742                + mLruProcessActivityStart + "): " + app);
2743        */
2744
2745        if (lrui >= 0) {
2746            if (lrui < mLruProcessActivityStart) {
2747                mLruProcessActivityStart--;
2748            }
2749            if (lrui < mLruProcessServiceStart) {
2750                mLruProcessServiceStart--;
2751            }
2752            /*
2753            if (addIndex > lrui) {
2754                addIndex--;
2755            }
2756            if (nextIndex > lrui) {
2757                nextIndex--;
2758            }
2759            */
2760            mLruProcesses.remove(lrui);
2761        }
2762
2763        /*
2764        mLruProcesses.add(addIndex, app);
2765        if (inActivity) {
2766            mLruProcessActivityStart++;
2767        }
2768        if (inService) {
2769            mLruProcessActivityStart++;
2770        }
2771        */
2772
2773        int nextIndex;
2774        if (hasActivity) {
2775            final int N = mLruProcesses.size();
2776            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2777                // Process doesn't have activities, but has clients with
2778                // activities...  move it up, but one below the top (the top
2779                // should always have a real activity).
2780                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2781                mLruProcesses.add(N-1, app);
2782                // To keep it from spamming the LRU list (by making a bunch of clients),
2783                // we will push down any other entries owned by the app.
2784                final int uid = app.info.uid;
2785                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2786                    ProcessRecord subProc = mLruProcesses.get(i);
2787                    if (subProc.info.uid == uid) {
2788                        // We want to push this one down the list.  If the process after
2789                        // it is for the same uid, however, don't do so, because we don't
2790                        // want them internally to be re-ordered.
2791                        if (mLruProcesses.get(i-1).info.uid != uid) {
2792                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2793                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2794                            ProcessRecord tmp = mLruProcesses.get(i);
2795                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2796                            mLruProcesses.set(i-1, tmp);
2797                            i--;
2798                        }
2799                    } else {
2800                        // A gap, we can stop here.
2801                        break;
2802                    }
2803                }
2804            } else {
2805                // Process has activities, put it at the very tipsy-top.
2806                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2807                mLruProcesses.add(app);
2808            }
2809            nextIndex = mLruProcessServiceStart;
2810        } else if (hasService) {
2811            // Process has services, put it at the top of the service list.
2812            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2813            mLruProcesses.add(mLruProcessActivityStart, app);
2814            nextIndex = mLruProcessServiceStart;
2815            mLruProcessActivityStart++;
2816        } else  {
2817            // Process not otherwise of interest, it goes to the top of the non-service area.
2818            int index = mLruProcessServiceStart;
2819            if (client != null) {
2820                // If there is a client, don't allow the process to be moved up higher
2821                // in the list than that client.
2822                int clientIndex = mLruProcesses.lastIndexOf(client);
2823                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2824                        + " when updating " + app);
2825                if (clientIndex <= lrui) {
2826                    // Don't allow the client index restriction to push it down farther in the
2827                    // list than it already is.
2828                    clientIndex = lrui;
2829                }
2830                if (clientIndex >= 0 && index > clientIndex) {
2831                    index = clientIndex;
2832                }
2833            }
2834            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2835            mLruProcesses.add(index, app);
2836            nextIndex = index-1;
2837            mLruProcessActivityStart++;
2838            mLruProcessServiceStart++;
2839        }
2840
2841        // If the app is currently using a content provider or service,
2842        // bump those processes as well.
2843        for (int j=app.connections.size()-1; j>=0; j--) {
2844            ConnectionRecord cr = app.connections.valueAt(j);
2845            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2846                    && cr.binding.service.app != null
2847                    && cr.binding.service.app.lruSeq != mLruSeq
2848                    && !cr.binding.service.app.persistent) {
2849                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2850                        "service connection", cr, app);
2851            }
2852        }
2853        for (int j=app.conProviders.size()-1; j>=0; j--) {
2854            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2855            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2856                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2857                        "provider reference", cpr, app);
2858            }
2859        }
2860    }
2861
2862    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2863        if (uid == Process.SYSTEM_UID) {
2864            // The system gets to run in any process.  If there are multiple
2865            // processes with the same uid, just pick the first (this
2866            // should never happen).
2867            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2868            if (procs == null) return null;
2869            final int N = procs.size();
2870            for (int i = 0; i < N; i++) {
2871                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2872            }
2873        }
2874        ProcessRecord proc = mProcessNames.get(processName, uid);
2875        if (false && proc != null && !keepIfLarge
2876                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2877                && proc.lastCachedPss >= 4000) {
2878            // Turn this condition on to cause killing to happen regularly, for testing.
2879            if (proc.baseProcessTracker != null) {
2880                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2881            }
2882            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2883        } else if (proc != null && !keepIfLarge
2884                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2885                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2886            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2887            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
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            }
2893        }
2894        return proc;
2895    }
2896
2897    void ensurePackageDexOpt(String packageName) {
2898        IPackageManager pm = AppGlobals.getPackageManager();
2899        try {
2900            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2901                mDidDexOpt = true;
2902            }
2903        } catch (RemoteException e) {
2904        }
2905    }
2906
2907    boolean isNextTransitionForward() {
2908        int transit = mWindowManager.getPendingAppTransition();
2909        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2910                || transit == AppTransition.TRANSIT_TASK_OPEN
2911                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2912    }
2913
2914    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2915            String processName, String abiOverride, int uid, Runnable crashHandler) {
2916        synchronized(this) {
2917            ApplicationInfo info = new ApplicationInfo();
2918            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2919            // For isolated processes, the former contains the parent's uid and the latter the
2920            // actual uid of the isolated process.
2921            // In the special case introduced by this method (which is, starting an isolated
2922            // process directly from the SystemServer without an actual parent app process) the
2923            // closest thing to a parent's uid is SYSTEM_UID.
2924            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2925            // the |isolated| logic in the ProcessRecord constructor.
2926            info.uid = Process.SYSTEM_UID;
2927            info.processName = processName;
2928            info.className = entryPoint;
2929            info.packageName = "android";
2930            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2931                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2932                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2933                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2934                    crashHandler);
2935            return proc != null ? proc.pid : 0;
2936        }
2937    }
2938
2939    final ProcessRecord startProcessLocked(String processName,
2940            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2941            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2942            boolean isolated, boolean keepIfLarge) {
2943        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2944                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2945                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2946                null /* crashHandler */);
2947    }
2948
2949    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2950            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2951            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2952            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2953        long startTime = SystemClock.elapsedRealtime();
2954        ProcessRecord app;
2955        if (!isolated) {
2956            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2957            checkTime(startTime, "startProcess: after getProcessRecord");
2958        } else {
2959            // If this is an isolated process, it can't re-use an existing process.
2960            app = null;
2961        }
2962        // We don't have to do anything more if:
2963        // (1) There is an existing application record; and
2964        // (2) The caller doesn't think it is dead, OR there is no thread
2965        //     object attached to it so we know it couldn't have crashed; and
2966        // (3) There is a pid assigned to it, so it is either starting or
2967        //     already running.
2968        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2969                + " app=" + app + " knownToBeDead=" + knownToBeDead
2970                + " thread=" + (app != null ? app.thread : null)
2971                + " pid=" + (app != null ? app.pid : -1));
2972        if (app != null && app.pid > 0) {
2973            if (!knownToBeDead || app.thread == null) {
2974                // We already have the app running, or are waiting for it to
2975                // come up (we have a pid but not yet its thread), so keep it.
2976                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2977                // If this is a new package in the process, add the package to the list
2978                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2979                checkTime(startTime, "startProcess: done, added package to proc");
2980                return app;
2981            }
2982
2983            // An application record is attached to a previous process,
2984            // clean it up now.
2985            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2986            checkTime(startTime, "startProcess: bad proc running, killing");
2987            Process.killProcessGroup(app.info.uid, app.pid);
2988            handleAppDiedLocked(app, true, true);
2989            checkTime(startTime, "startProcess: done killing old proc");
2990        }
2991
2992        String hostingNameStr = hostingName != null
2993                ? hostingName.flattenToShortString() : null;
2994
2995        if (!isolated) {
2996            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2997                // If we are in the background, then check to see if this process
2998                // is bad.  If so, we will just silently fail.
2999                if (mBadProcesses.get(info.processName, info.uid) != null) {
3000                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3001                            + "/" + info.processName);
3002                    return null;
3003                }
3004            } else {
3005                // When the user is explicitly starting a process, then clear its
3006                // crash count so that we won't make it bad until they see at
3007                // least one crash dialog again, and make the process good again
3008                // if it had been bad.
3009                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3010                        + "/" + info.processName);
3011                mProcessCrashTimes.remove(info.processName, info.uid);
3012                if (mBadProcesses.get(info.processName, info.uid) != null) {
3013                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3014                            UserHandle.getUserId(info.uid), info.uid,
3015                            info.processName);
3016                    mBadProcesses.remove(info.processName, info.uid);
3017                    if (app != null) {
3018                        app.bad = false;
3019                    }
3020                }
3021            }
3022        }
3023
3024        if (app == null) {
3025            checkTime(startTime, "startProcess: creating new process record");
3026            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3027            app.crashHandler = crashHandler;
3028            if (app == null) {
3029                Slog.w(TAG, "Failed making new process record for "
3030                        + processName + "/" + info.uid + " isolated=" + isolated);
3031                return null;
3032            }
3033            mProcessNames.put(processName, app.uid, app);
3034            if (isolated) {
3035                mIsolatedProcesses.put(app.uid, app);
3036            }
3037            checkTime(startTime, "startProcess: done creating new process record");
3038        } else {
3039            // If this is a new package in the process, add the package to the list
3040            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3041            checkTime(startTime, "startProcess: added package to existing proc");
3042        }
3043
3044        // If the system is not ready yet, then hold off on starting this
3045        // process until it is.
3046        if (!mProcessesReady
3047                && !isAllowedWhileBooting(info)
3048                && !allowWhileBooting) {
3049            if (!mProcessesOnHold.contains(app)) {
3050                mProcessesOnHold.add(app);
3051            }
3052            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3053            checkTime(startTime, "startProcess: returning with proc on hold");
3054            return app;
3055        }
3056
3057        checkTime(startTime, "startProcess: stepping in to startProcess");
3058        startProcessLocked(
3059                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3060        checkTime(startTime, "startProcess: done starting proc!");
3061        return (app.pid != 0) ? app : null;
3062    }
3063
3064    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3065        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3066    }
3067
3068    private final void startProcessLocked(ProcessRecord app,
3069            String hostingType, String hostingNameStr) {
3070        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3071                null /* entryPoint */, null /* entryPointArgs */);
3072    }
3073
3074    private final void startProcessLocked(ProcessRecord app, String hostingType,
3075            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3076        long startTime = SystemClock.elapsedRealtime();
3077        if (app.pid > 0 && app.pid != MY_PID) {
3078            checkTime(startTime, "startProcess: removing from pids map");
3079            synchronized (mPidsSelfLocked) {
3080                mPidsSelfLocked.remove(app.pid);
3081                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3082            }
3083            checkTime(startTime, "startProcess: done removing from pids map");
3084            app.setPid(0);
3085        }
3086
3087        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3088                "startProcessLocked removing on hold: " + app);
3089        mProcessesOnHold.remove(app);
3090
3091        checkTime(startTime, "startProcess: starting to update cpu stats");
3092        updateCpuStats();
3093        checkTime(startTime, "startProcess: done updating cpu stats");
3094
3095        try {
3096            int uid = app.uid;
3097
3098            int[] gids = null;
3099            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3100            if (!app.isolated) {
3101                int[] permGids = null;
3102                try {
3103                    checkTime(startTime, "startProcess: getting gids from package manager");
3104                    final PackageManager pm = mContext.getPackageManager();
3105                    permGids = pm.getPackageGids(app.info.packageName);
3106
3107                    if (Environment.isExternalStorageEmulated()) {
3108                        checkTime(startTime, "startProcess: checking external storage perm");
3109                        if (pm.checkPermission(
3110                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3111                                app.info.packageName) == PERMISSION_GRANTED) {
3112                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3113                        } else {
3114                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3115                        }
3116                    }
3117                } catch (PackageManager.NameNotFoundException e) {
3118                    Slog.w(TAG, "Unable to retrieve gids", e);
3119                }
3120
3121                /*
3122                 * Add shared application and profile GIDs so applications can share some
3123                 * resources like shared libraries and access user-wide resources
3124                 */
3125                if (permGids == null) {
3126                    gids = new int[2];
3127                } else {
3128                    gids = new int[permGids.length + 2];
3129                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3130                }
3131                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3132                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3133            }
3134            checkTime(startTime, "startProcess: building args");
3135            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3136                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3137                        && mTopComponent != null
3138                        && app.processName.equals(mTopComponent.getPackageName())) {
3139                    uid = 0;
3140                }
3141                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3142                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3143                    uid = 0;
3144                }
3145            }
3146            int debugFlags = 0;
3147            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3148                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3149                // Also turn on CheckJNI for debuggable apps. It's quite
3150                // awkward to turn on otherwise.
3151                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3152            }
3153            // Run the app in safe mode if its manifest requests so or the
3154            // system is booted in safe mode.
3155            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3156                mSafeMode == true) {
3157                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3158            }
3159            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3160                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3161            }
3162            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3163                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3164            }
3165            if ("1".equals(SystemProperties.get("debug.assert"))) {
3166                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3167            }
3168
3169            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3170            if (requiredAbi == null) {
3171                requiredAbi = Build.SUPPORTED_ABIS[0];
3172            }
3173
3174            String instructionSet = null;
3175            if (app.info.primaryCpuAbi != null) {
3176                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3177            }
3178
3179            // Start the process.  It will either succeed and return a result containing
3180            // the PID of the new process, or else throw a RuntimeException.
3181            boolean isActivityProcess = (entryPoint == null);
3182            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3183            checkTime(startTime, "startProcess: asking zygote to start proc");
3184            Process.ProcessStartResult startResult = Process.start(entryPoint,
3185                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3186                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3187                    app.info.dataDir, entryPointArgs);
3188            checkTime(startTime, "startProcess: returned from zygote!");
3189
3190            if (app.isolated) {
3191                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3192            }
3193            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3194            checkTime(startTime, "startProcess: done updating battery stats");
3195
3196            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3197                    UserHandle.getUserId(uid), startResult.pid, uid,
3198                    app.processName, hostingType,
3199                    hostingNameStr != null ? hostingNameStr : "");
3200
3201            if (app.persistent) {
3202                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3203            }
3204
3205            checkTime(startTime, "startProcess: building log message");
3206            StringBuilder buf = mStringBuilder;
3207            buf.setLength(0);
3208            buf.append("Start proc ");
3209            buf.append(app.processName);
3210            if (!isActivityProcess) {
3211                buf.append(" [");
3212                buf.append(entryPoint);
3213                buf.append("]");
3214            }
3215            buf.append(" for ");
3216            buf.append(hostingType);
3217            if (hostingNameStr != null) {
3218                buf.append(" ");
3219                buf.append(hostingNameStr);
3220            }
3221            buf.append(": pid=");
3222            buf.append(startResult.pid);
3223            buf.append(" uid=");
3224            buf.append(uid);
3225            buf.append(" gids={");
3226            if (gids != null) {
3227                for (int gi=0; gi<gids.length; gi++) {
3228                    if (gi != 0) buf.append(", ");
3229                    buf.append(gids[gi]);
3230
3231                }
3232            }
3233            buf.append("}");
3234            if (requiredAbi != null) {
3235                buf.append(" abi=");
3236                buf.append(requiredAbi);
3237            }
3238            Slog.i(TAG, buf.toString());
3239            app.setPid(startResult.pid);
3240            app.usingWrapper = startResult.usingWrapper;
3241            app.removed = false;
3242            app.killed = false;
3243            app.killedByAm = false;
3244            checkTime(startTime, "startProcess: starting to update pids map");
3245            synchronized (mPidsSelfLocked) {
3246                this.mPidsSelfLocked.put(startResult.pid, app);
3247                if (isActivityProcess) {
3248                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3249                    msg.obj = app;
3250                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3251                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3252                }
3253            }
3254            checkTime(startTime, "startProcess: done updating pids map");
3255        } catch (RuntimeException e) {
3256            // XXX do better error recovery.
3257            app.setPid(0);
3258            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3259            if (app.isolated) {
3260                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3261            }
3262            Slog.e(TAG, "Failure starting process " + app.processName, e);
3263        }
3264    }
3265
3266    void updateUsageStats(ActivityRecord component, boolean resumed) {
3267        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3268        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3269        if (resumed) {
3270            if (mUsageStatsService != null) {
3271                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3272                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3273            }
3274            synchronized (stats) {
3275                stats.noteActivityResumedLocked(component.app.uid);
3276            }
3277        } else {
3278            if (mUsageStatsService != null) {
3279                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3280                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3281            }
3282            synchronized (stats) {
3283                stats.noteActivityPausedLocked(component.app.uid);
3284            }
3285        }
3286    }
3287
3288    Intent getHomeIntent() {
3289        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3290        intent.setComponent(mTopComponent);
3291        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3292            intent.addCategory(Intent.CATEGORY_HOME);
3293        }
3294        return intent;
3295    }
3296
3297    boolean startHomeActivityLocked(int userId) {
3298        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3299                && mTopAction == null) {
3300            // We are running in factory test mode, but unable to find
3301            // the factory test app, so just sit around displaying the
3302            // error message and don't try to start anything.
3303            return false;
3304        }
3305        Intent intent = getHomeIntent();
3306        ActivityInfo aInfo =
3307            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3308        if (aInfo != null) {
3309            intent.setComponent(new ComponentName(
3310                    aInfo.applicationInfo.packageName, aInfo.name));
3311            // Don't do this if the home app is currently being
3312            // instrumented.
3313            aInfo = new ActivityInfo(aInfo);
3314            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3315            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3316                    aInfo.applicationInfo.uid, true);
3317            if (app == null || app.instrumentationClass == null) {
3318                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3319                mStackSupervisor.startHomeActivity(intent, aInfo);
3320            }
3321        }
3322
3323        return true;
3324    }
3325
3326    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3327        ActivityInfo ai = null;
3328        ComponentName comp = intent.getComponent();
3329        try {
3330            if (comp != null) {
3331                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3332            } else {
3333                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3334                        intent,
3335                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3336                            flags, userId);
3337
3338                if (info != null) {
3339                    ai = info.activityInfo;
3340                }
3341            }
3342        } catch (RemoteException e) {
3343            // ignore
3344        }
3345
3346        return ai;
3347    }
3348
3349    /**
3350     * Starts the "new version setup screen" if appropriate.
3351     */
3352    void startSetupActivityLocked() {
3353        // Only do this once per boot.
3354        if (mCheckedForSetup) {
3355            return;
3356        }
3357
3358        // We will show this screen if the current one is a different
3359        // version than the last one shown, and we are not running in
3360        // low-level factory test mode.
3361        final ContentResolver resolver = mContext.getContentResolver();
3362        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3363                Settings.Global.getInt(resolver,
3364                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3365            mCheckedForSetup = true;
3366
3367            // See if we should be showing the platform update setup UI.
3368            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3369            List<ResolveInfo> ris = mContext.getPackageManager()
3370                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3371
3372            // We don't allow third party apps to replace this.
3373            ResolveInfo ri = null;
3374            for (int i=0; ris != null && i<ris.size(); i++) {
3375                if ((ris.get(i).activityInfo.applicationInfo.flags
3376                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3377                    ri = ris.get(i);
3378                    break;
3379                }
3380            }
3381
3382            if (ri != null) {
3383                String vers = ri.activityInfo.metaData != null
3384                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3385                        : null;
3386                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3387                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3388                            Intent.METADATA_SETUP_VERSION);
3389                }
3390                String lastVers = Settings.Secure.getString(
3391                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3392                if (vers != null && !vers.equals(lastVers)) {
3393                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3394                    intent.setComponent(new ComponentName(
3395                            ri.activityInfo.packageName, ri.activityInfo.name));
3396                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3397                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3398                            null);
3399                }
3400            }
3401        }
3402    }
3403
3404    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3405        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3406    }
3407
3408    void enforceNotIsolatedCaller(String caller) {
3409        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3410            throw new SecurityException("Isolated process not allowed to call " + caller);
3411        }
3412    }
3413
3414    void enforceShellRestriction(String restriction, int userHandle) {
3415        if (Binder.getCallingUid() == Process.SHELL_UID) {
3416            if (userHandle < 0
3417                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3418                throw new SecurityException("Shell does not have permission to access user "
3419                        + userHandle);
3420            }
3421        }
3422    }
3423
3424    @Override
3425    public int getFrontActivityScreenCompatMode() {
3426        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3427        synchronized (this) {
3428            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3429        }
3430    }
3431
3432    @Override
3433    public void setFrontActivityScreenCompatMode(int mode) {
3434        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3435                "setFrontActivityScreenCompatMode");
3436        synchronized (this) {
3437            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3438        }
3439    }
3440
3441    @Override
3442    public int getPackageScreenCompatMode(String packageName) {
3443        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3444        synchronized (this) {
3445            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3446        }
3447    }
3448
3449    @Override
3450    public void setPackageScreenCompatMode(String packageName, int mode) {
3451        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3452                "setPackageScreenCompatMode");
3453        synchronized (this) {
3454            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3455        }
3456    }
3457
3458    @Override
3459    public boolean getPackageAskScreenCompat(String packageName) {
3460        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3461        synchronized (this) {
3462            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3463        }
3464    }
3465
3466    @Override
3467    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3468        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3469                "setPackageAskScreenCompat");
3470        synchronized (this) {
3471            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3472        }
3473    }
3474
3475    private void dispatchProcessesChanged() {
3476        int N;
3477        synchronized (this) {
3478            N = mPendingProcessChanges.size();
3479            if (mActiveProcessChanges.length < N) {
3480                mActiveProcessChanges = new ProcessChangeItem[N];
3481            }
3482            mPendingProcessChanges.toArray(mActiveProcessChanges);
3483            mAvailProcessChanges.addAll(mPendingProcessChanges);
3484            mPendingProcessChanges.clear();
3485            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3486        }
3487
3488        int i = mProcessObservers.beginBroadcast();
3489        while (i > 0) {
3490            i--;
3491            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3492            if (observer != null) {
3493                try {
3494                    for (int j=0; j<N; j++) {
3495                        ProcessChangeItem item = mActiveProcessChanges[j];
3496                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3497                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3498                                    + item.pid + " uid=" + item.uid + ": "
3499                                    + item.foregroundActivities);
3500                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3501                                    item.foregroundActivities);
3502                        }
3503                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3504                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3505                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3506                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3507                        }
3508                    }
3509                } catch (RemoteException e) {
3510                }
3511            }
3512        }
3513        mProcessObservers.finishBroadcast();
3514    }
3515
3516    private void dispatchProcessDied(int pid, int uid) {
3517        int i = mProcessObservers.beginBroadcast();
3518        while (i > 0) {
3519            i--;
3520            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3521            if (observer != null) {
3522                try {
3523                    observer.onProcessDied(pid, uid);
3524                } catch (RemoteException e) {
3525                }
3526            }
3527        }
3528        mProcessObservers.finishBroadcast();
3529    }
3530
3531    @Override
3532    public final int startActivity(IApplicationThread caller, String callingPackage,
3533            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3534            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3535        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3536            resultWho, requestCode, startFlags, profilerInfo, options,
3537            UserHandle.getCallingUserId());
3538    }
3539
3540    @Override
3541    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3542            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3543            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3544        enforceNotIsolatedCaller("startActivity");
3545        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3546                false, ALLOW_FULL_ONLY, "startActivity", null);
3547        // TODO: Switch to user app stacks here.
3548        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3549                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3550                profilerInfo, null, null, options, userId, null, null);
3551    }
3552
3553    @Override
3554    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3555            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3556            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3557
3558        // This is very dangerous -- it allows you to perform a start activity (including
3559        // permission grants) as any app that may launch one of your own activities.  So
3560        // we will only allow this to be done from activities that are part of the core framework,
3561        // and then only when they are running as the system.
3562        final ActivityRecord sourceRecord;
3563        final int targetUid;
3564        final String targetPackage;
3565        synchronized (this) {
3566            if (resultTo == null) {
3567                throw new SecurityException("Must be called from an activity");
3568            }
3569            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3570            if (sourceRecord == null) {
3571                throw new SecurityException("Called with bad activity token: " + resultTo);
3572            }
3573            if (!sourceRecord.info.packageName.equals("android")) {
3574                throw new SecurityException(
3575                        "Must be called from an activity that is declared in the android package");
3576            }
3577            if (sourceRecord.app == null) {
3578                throw new SecurityException("Called without a process attached to activity");
3579            }
3580            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3581                // This is still okay, as long as this activity is running under the
3582                // uid of the original calling activity.
3583                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3584                    throw new SecurityException(
3585                            "Calling activity in uid " + sourceRecord.app.uid
3586                                    + " must be system uid or original calling uid "
3587                                    + sourceRecord.launchedFromUid);
3588                }
3589            }
3590            targetUid = sourceRecord.launchedFromUid;
3591            targetPackage = sourceRecord.launchedFromPackage;
3592        }
3593
3594        // TODO: Switch to user app stacks here.
3595        try {
3596            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3597                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3598                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3599            return ret;
3600        } catch (SecurityException e) {
3601            // XXX need to figure out how to propagate to original app.
3602            // A SecurityException here is generally actually a fault of the original
3603            // calling activity (such as a fairly granting permissions), so propagate it
3604            // back to them.
3605            /*
3606            StringBuilder msg = new StringBuilder();
3607            msg.append("While launching");
3608            msg.append(intent.toString());
3609            msg.append(": ");
3610            msg.append(e.getMessage());
3611            */
3612            throw e;
3613        }
3614    }
3615
3616    @Override
3617    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3618            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3619            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3620        enforceNotIsolatedCaller("startActivityAndWait");
3621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3622                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3623        WaitResult res = new WaitResult();
3624        // TODO: Switch to user app stacks here.
3625        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3626                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3627                options, userId, null, null);
3628        return res;
3629    }
3630
3631    @Override
3632    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3634            int startFlags, Configuration config, Bundle options, int userId) {
3635        enforceNotIsolatedCaller("startActivityWithConfig");
3636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3637                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3638        // TODO: Switch to user app stacks here.
3639        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3641                null, null, config, options, userId, null, null);
3642        return ret;
3643    }
3644
3645    @Override
3646    public int startActivityIntentSender(IApplicationThread caller,
3647            IntentSender intent, Intent fillInIntent, String resolvedType,
3648            IBinder resultTo, String resultWho, int requestCode,
3649            int flagsMask, int flagsValues, Bundle options) {
3650        enforceNotIsolatedCaller("startActivityIntentSender");
3651        // Refuse possible leaked file descriptors
3652        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3653            throw new IllegalArgumentException("File descriptors passed in Intent");
3654        }
3655
3656        IIntentSender sender = intent.getTarget();
3657        if (!(sender instanceof PendingIntentRecord)) {
3658            throw new IllegalArgumentException("Bad PendingIntent object");
3659        }
3660
3661        PendingIntentRecord pir = (PendingIntentRecord)sender;
3662
3663        synchronized (this) {
3664            // If this is coming from the currently resumed activity, it is
3665            // effectively saying that app switches are allowed at this point.
3666            final ActivityStack stack = getFocusedStack();
3667            if (stack.mResumedActivity != null &&
3668                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3669                mAppSwitchesAllowedTime = 0;
3670            }
3671        }
3672        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3673                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3674        return ret;
3675    }
3676
3677    @Override
3678    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3679            Intent intent, String resolvedType, IVoiceInteractionSession session,
3680            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3681            Bundle options, int userId) {
3682        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3683                != PackageManager.PERMISSION_GRANTED) {
3684            String msg = "Permission Denial: startVoiceActivity() from pid="
3685                    + Binder.getCallingPid()
3686                    + ", uid=" + Binder.getCallingUid()
3687                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3688            Slog.w(TAG, msg);
3689            throw new SecurityException(msg);
3690        }
3691        if (session == null || interactor == null) {
3692            throw new NullPointerException("null session or interactor");
3693        }
3694        userId = handleIncomingUser(callingPid, callingUid, userId,
3695                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3696        // TODO: Switch to user app stacks here.
3697        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3698                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3699                null, options, userId, null, null);
3700    }
3701
3702    @Override
3703    public boolean startNextMatchingActivity(IBinder callingActivity,
3704            Intent intent, Bundle options) {
3705        // Refuse possible leaked file descriptors
3706        if (intent != null && intent.hasFileDescriptors() == true) {
3707            throw new IllegalArgumentException("File descriptors passed in Intent");
3708        }
3709
3710        synchronized (this) {
3711            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3712            if (r == null) {
3713                ActivityOptions.abort(options);
3714                return false;
3715            }
3716            if (r.app == null || r.app.thread == null) {
3717                // The caller is not running...  d'oh!
3718                ActivityOptions.abort(options);
3719                return false;
3720            }
3721            intent = new Intent(intent);
3722            // The caller is not allowed to change the data.
3723            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3724            // And we are resetting to find the next component...
3725            intent.setComponent(null);
3726
3727            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3728
3729            ActivityInfo aInfo = null;
3730            try {
3731                List<ResolveInfo> resolves =
3732                    AppGlobals.getPackageManager().queryIntentActivities(
3733                            intent, r.resolvedType,
3734                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3735                            UserHandle.getCallingUserId());
3736
3737                // Look for the original activity in the list...
3738                final int N = resolves != null ? resolves.size() : 0;
3739                for (int i=0; i<N; i++) {
3740                    ResolveInfo rInfo = resolves.get(i);
3741                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3742                            && rInfo.activityInfo.name.equals(r.info.name)) {
3743                        // We found the current one...  the next matching is
3744                        // after it.
3745                        i++;
3746                        if (i<N) {
3747                            aInfo = resolves.get(i).activityInfo;
3748                        }
3749                        if (debug) {
3750                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3751                                    + "/" + r.info.name);
3752                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3753                                    + "/" + aInfo.name);
3754                        }
3755                        break;
3756                    }
3757                }
3758            } catch (RemoteException e) {
3759            }
3760
3761            if (aInfo == null) {
3762                // Nobody who is next!
3763                ActivityOptions.abort(options);
3764                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3765                return false;
3766            }
3767
3768            intent.setComponent(new ComponentName(
3769                    aInfo.applicationInfo.packageName, aInfo.name));
3770            intent.setFlags(intent.getFlags()&~(
3771                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3772                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3773                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3774                    Intent.FLAG_ACTIVITY_NEW_TASK));
3775
3776            // Okay now we need to start the new activity, replacing the
3777            // currently running activity.  This is a little tricky because
3778            // we want to start the new one as if the current one is finished,
3779            // but not finish the current one first so that there is no flicker.
3780            // And thus...
3781            final boolean wasFinishing = r.finishing;
3782            r.finishing = true;
3783
3784            // Propagate reply information over to the new activity.
3785            final ActivityRecord resultTo = r.resultTo;
3786            final String resultWho = r.resultWho;
3787            final int requestCode = r.requestCode;
3788            r.resultTo = null;
3789            if (resultTo != null) {
3790                resultTo.removeResultsLocked(r, resultWho, requestCode);
3791            }
3792
3793            final long origId = Binder.clearCallingIdentity();
3794            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3795                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3796                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3797                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3798            Binder.restoreCallingIdentity(origId);
3799
3800            r.finishing = wasFinishing;
3801            if (res != ActivityManager.START_SUCCESS) {
3802                return false;
3803            }
3804            return true;
3805        }
3806    }
3807
3808    @Override
3809    public final int startActivityFromRecents(int taskId, Bundle options) {
3810        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3811            String msg = "Permission Denial: startActivityFromRecents called without " +
3812                    START_TASKS_FROM_RECENTS;
3813            Slog.w(TAG, msg);
3814            throw new SecurityException(msg);
3815        }
3816        return startActivityFromRecentsInner(taskId, options);
3817    }
3818
3819    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3820        final TaskRecord task;
3821        final int callingUid;
3822        final String callingPackage;
3823        final Intent intent;
3824        final int userId;
3825        synchronized (this) {
3826            task = recentTaskForIdLocked(taskId);
3827            if (task == null) {
3828                throw new IllegalArgumentException("Task " + taskId + " not found.");
3829            }
3830            callingUid = task.mCallingUid;
3831            callingPackage = task.mCallingPackage;
3832            intent = task.intent;
3833            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3834            userId = task.userId;
3835        }
3836        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3837                options, userId, null, task);
3838    }
3839
3840    final int startActivityInPackage(int uid, String callingPackage,
3841            Intent intent, String resolvedType, IBinder resultTo,
3842            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3843            IActivityContainer container, TaskRecord inTask) {
3844
3845        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3846                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3847
3848        // TODO: Switch to user app stacks here.
3849        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3850                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3851                null, null, null, options, userId, container, inTask);
3852        return ret;
3853    }
3854
3855    @Override
3856    public final int startActivities(IApplicationThread caller, String callingPackage,
3857            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3858            int userId) {
3859        enforceNotIsolatedCaller("startActivities");
3860        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3861                false, ALLOW_FULL_ONLY, "startActivity", null);
3862        // TODO: Switch to user app stacks here.
3863        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3864                resolvedTypes, resultTo, options, userId);
3865        return ret;
3866    }
3867
3868    final int startActivitiesInPackage(int uid, String callingPackage,
3869            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3870            Bundle options, int userId) {
3871
3872        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3873                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3874        // TODO: Switch to user app stacks here.
3875        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3876                resultTo, options, userId);
3877        return ret;
3878    }
3879
3880    //explicitly remove thd old information in mRecentTasks when removing existing user.
3881    private void removeRecentTasksForUserLocked(int userId) {
3882        if(userId <= 0) {
3883            Slog.i(TAG, "Can't remove recent task on user " + userId);
3884            return;
3885        }
3886
3887        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3888            TaskRecord tr = mRecentTasks.get(i);
3889            if (tr.userId == userId) {
3890                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3891                        + " when finishing user" + userId);
3892                mRecentTasks.remove(i);
3893                tr.removedFromRecents(mTaskPersister);
3894            }
3895        }
3896
3897        // Remove tasks from persistent storage.
3898        mTaskPersister.wakeup(null, true);
3899    }
3900
3901    // Sort by taskId
3902    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3903        @Override
3904        public int compare(TaskRecord lhs, TaskRecord rhs) {
3905            return rhs.taskId - lhs.taskId;
3906        }
3907    };
3908
3909    // Extract the affiliates of the chain containing mRecentTasks[start].
3910    private int processNextAffiliateChain(int start) {
3911        final TaskRecord startTask = mRecentTasks.get(start);
3912        final int affiliateId = startTask.mAffiliatedTaskId;
3913
3914        // Quick identification of isolated tasks. I.e. those not launched behind.
3915        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3916                startTask.mNextAffiliate == null) {
3917            // There is still a slim chance that there are other tasks that point to this task
3918            // and that the chain is so messed up that this task no longer points to them but
3919            // the gain of this optimization outweighs the risk.
3920            startTask.inRecents = true;
3921            return start + 1;
3922        }
3923
3924        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3925        mTmpRecents.clear();
3926        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3927            final TaskRecord task = mRecentTasks.get(i);
3928            if (task.mAffiliatedTaskId == affiliateId) {
3929                mRecentTasks.remove(i);
3930                mTmpRecents.add(task);
3931            }
3932        }
3933
3934        // Sort them all by taskId. That is the order they were create in and that order will
3935        // always be correct.
3936        Collections.sort(mTmpRecents, mTaskRecordComparator);
3937
3938        // Go through and fix up the linked list.
3939        // The first one is the end of the chain and has no next.
3940        final TaskRecord first = mTmpRecents.get(0);
3941        first.inRecents = true;
3942        if (first.mNextAffiliate != null) {
3943            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3944            first.setNextAffiliate(null);
3945            mTaskPersister.wakeup(first, false);
3946        }
3947        // Everything in the middle is doubly linked from next to prev.
3948        final int tmpSize = mTmpRecents.size();
3949        for (int i = 0; i < tmpSize - 1; ++i) {
3950            final TaskRecord next = mTmpRecents.get(i);
3951            final TaskRecord prev = mTmpRecents.get(i + 1);
3952            if (next.mPrevAffiliate != prev) {
3953                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3954                        " setting prev=" + prev);
3955                next.setPrevAffiliate(prev);
3956                mTaskPersister.wakeup(next, false);
3957            }
3958            if (prev.mNextAffiliate != next) {
3959                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3960                        " setting next=" + next);
3961                prev.setNextAffiliate(next);
3962                mTaskPersister.wakeup(prev, false);
3963            }
3964            prev.inRecents = true;
3965        }
3966        // The last one is the beginning of the list and has no prev.
3967        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3968        if (last.mPrevAffiliate != null) {
3969            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3970            last.setPrevAffiliate(null);
3971            mTaskPersister.wakeup(last, false);
3972        }
3973
3974        // Insert the group back into mRecentTasks at start.
3975        mRecentTasks.addAll(start, mTmpRecents);
3976
3977        // Let the caller know where we left off.
3978        return start + tmpSize;
3979    }
3980
3981    /**
3982     * Update the recent tasks lists: make sure tasks should still be here (their
3983     * applications / activities still exist), update their availability, fixup ordering
3984     * of affiliations.
3985     */
3986    void cleanupRecentTasksLocked(int userId) {
3987        if (mRecentTasks == null) {
3988            // Happens when called from the packagemanager broadcast before boot.
3989            return;
3990        }
3991
3992        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3993        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3994        final IPackageManager pm = AppGlobals.getPackageManager();
3995        final ActivityInfo dummyAct = new ActivityInfo();
3996        final ApplicationInfo dummyApp = new ApplicationInfo();
3997
3998        int N = mRecentTasks.size();
3999
4000        int[] users = userId == UserHandle.USER_ALL
4001                ? getUsersLocked() : new int[] { userId };
4002        for (int user : users) {
4003            for (int i = 0; i < N; i++) {
4004                TaskRecord task = mRecentTasks.get(i);
4005                if (task.userId != user) {
4006                    // Only look at tasks for the user ID of interest.
4007                    continue;
4008                }
4009                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4010                    // This situation is broken, and we should just get rid of it now.
4011                    mRecentTasks.remove(i);
4012                    task.removedFromRecents(mTaskPersister);
4013                    i--;
4014                    N--;
4015                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4016                    continue;
4017                }
4018                // Check whether this activity is currently available.
4019                if (task.realActivity != null) {
4020                    ActivityInfo ai = availActCache.get(task.realActivity);
4021                    if (ai == null) {
4022                        try {
4023                            ai = pm.getActivityInfo(task.realActivity,
4024                                    PackageManager.GET_UNINSTALLED_PACKAGES
4025                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4026                        } catch (RemoteException e) {
4027                            // Will never happen.
4028                            continue;
4029                        }
4030                        if (ai == null) {
4031                            ai = dummyAct;
4032                        }
4033                        availActCache.put(task.realActivity, ai);
4034                    }
4035                    if (ai == dummyAct) {
4036                        // This could be either because the activity no longer exists, or the
4037                        // app is temporarily gone.  For the former we want to remove the recents
4038                        // entry; for the latter we want to mark it as unavailable.
4039                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4040                        if (app == null) {
4041                            try {
4042                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4043                                        PackageManager.GET_UNINSTALLED_PACKAGES
4044                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4045                            } catch (RemoteException e) {
4046                                // Will never happen.
4047                                continue;
4048                            }
4049                            if (app == null) {
4050                                app = dummyApp;
4051                            }
4052                            availAppCache.put(task.realActivity.getPackageName(), app);
4053                        }
4054                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4055                            // Doesn't exist any more!  Good-bye.
4056                            mRecentTasks.remove(i);
4057                            task.removedFromRecents(mTaskPersister);
4058                            i--;
4059                            N--;
4060                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4061                            continue;
4062                        } else {
4063                            // Otherwise just not available for now.
4064                            if (task.isAvailable) {
4065                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4066                                        + task);
4067                            }
4068                            task.isAvailable = false;
4069                        }
4070                    } else {
4071                        if (!ai.enabled || !ai.applicationInfo.enabled
4072                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4073                            if (task.isAvailable) {
4074                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4075                                        + task + " (enabled=" + ai.enabled + "/"
4076                                        + ai.applicationInfo.enabled +  " flags="
4077                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4078                            }
4079                            task.isAvailable = false;
4080                        } else {
4081                            if (!task.isAvailable) {
4082                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4083                                        + task);
4084                            }
4085                            task.isAvailable = true;
4086                        }
4087                    }
4088                }
4089            }
4090        }
4091
4092        // Verify the affiliate chain for each task.
4093        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4094        }
4095
4096        mTmpRecents.clear();
4097        // mRecentTasks is now in sorted, affiliated order.
4098    }
4099
4100    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4101        int N = mRecentTasks.size();
4102        TaskRecord top = task;
4103        int topIndex = taskIndex;
4104        while (top.mNextAffiliate != null && topIndex > 0) {
4105            top = top.mNextAffiliate;
4106            topIndex--;
4107        }
4108        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4109                + topIndex + " from intial " + taskIndex);
4110        // Find the end of the chain, doing a sanity check along the way.
4111        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4112        int endIndex = topIndex;
4113        TaskRecord prev = top;
4114        while (endIndex < N) {
4115            TaskRecord cur = mRecentTasks.get(endIndex);
4116            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4117                    + endIndex + " " + cur);
4118            if (cur == top) {
4119                // Verify start of the chain.
4120                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4121                    Slog.wtf(TAG, "Bad chain @" + endIndex
4122                            + ": first task has next affiliate: " + prev);
4123                    sane = false;
4124                    break;
4125                }
4126            } else {
4127                // Verify middle of the chain's next points back to the one before.
4128                if (cur.mNextAffiliate != prev
4129                        || cur.mNextAffiliateTaskId != prev.taskId) {
4130                    Slog.wtf(TAG, "Bad chain @" + endIndex
4131                            + ": middle task " + cur + " @" + endIndex
4132                            + " has bad next affiliate "
4133                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4134                            + ", expected " + prev);
4135                    sane = false;
4136                    break;
4137                }
4138            }
4139            if (cur.mPrevAffiliateTaskId == -1) {
4140                // Chain ends here.
4141                if (cur.mPrevAffiliate != null) {
4142                    Slog.wtf(TAG, "Bad chain @" + endIndex
4143                            + ": last task " + cur + " has previous affiliate "
4144                            + cur.mPrevAffiliate);
4145                    sane = false;
4146                }
4147                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4148                break;
4149            } else {
4150                // Verify middle of the chain's prev points to a valid item.
4151                if (cur.mPrevAffiliate == null) {
4152                    Slog.wtf(TAG, "Bad chain @" + endIndex
4153                            + ": task " + cur + " has previous affiliate "
4154                            + cur.mPrevAffiliate + " but should be id "
4155                            + cur.mPrevAffiliate);
4156                    sane = false;
4157                    break;
4158                }
4159            }
4160            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4161                Slog.wtf(TAG, "Bad chain @" + endIndex
4162                        + ": task " + cur + " has affiliated id "
4163                        + cur.mAffiliatedTaskId + " but should be "
4164                        + task.mAffiliatedTaskId);
4165                sane = false;
4166                break;
4167            }
4168            prev = cur;
4169            endIndex++;
4170            if (endIndex >= N) {
4171                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4172                        + ": last task " + prev);
4173                sane = false;
4174                break;
4175            }
4176        }
4177        if (sane) {
4178            if (endIndex < taskIndex) {
4179                Slog.wtf(TAG, "Bad chain @" + endIndex
4180                        + ": did not extend to task " + task + " @" + taskIndex);
4181                sane = false;
4182            }
4183        }
4184        if (sane) {
4185            // All looks good, we can just move all of the affiliated tasks
4186            // to the top.
4187            for (int i=topIndex; i<=endIndex; i++) {
4188                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4189                        + " from " + i + " to " + (i-topIndex));
4190                TaskRecord cur = mRecentTasks.remove(i);
4191                mRecentTasks.add(i-topIndex, cur);
4192            }
4193            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4194                    + " to " + endIndex);
4195            return true;
4196        }
4197
4198        // Whoops, couldn't do it.
4199        return false;
4200    }
4201
4202    final void addRecentTaskLocked(TaskRecord task) {
4203        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4204                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4205
4206        int N = mRecentTasks.size();
4207        // Quick case: check if the top-most recent task is the same.
4208        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4209            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4210            return;
4211        }
4212        // Another quick case: check if this is part of a set of affiliated
4213        // tasks that are at the top.
4214        if (isAffiliated && N > 0 && task.inRecents
4215                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4216            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4217                    + " at top when adding " + task);
4218            return;
4219        }
4220        // Another quick case: never add voice sessions.
4221        if (task.voiceSession != null) {
4222            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4223            return;
4224        }
4225
4226        boolean needAffiliationFix = false;
4227
4228        // Slightly less quick case: the task is already in recents, so all we need
4229        // to do is move it.
4230        if (task.inRecents) {
4231            int taskIndex = mRecentTasks.indexOf(task);
4232            if (taskIndex >= 0) {
4233                if (!isAffiliated) {
4234                    // Simple case: this is not an affiliated task, so we just move it to the front.
4235                    mRecentTasks.remove(taskIndex);
4236                    mRecentTasks.add(0, task);
4237                    notifyTaskPersisterLocked(task, false);
4238                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4239                            + " from " + taskIndex);
4240                    return;
4241                } else {
4242                    // More complicated: need to keep all affiliated tasks together.
4243                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4244                        // All went well.
4245                        return;
4246                    }
4247
4248                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4249                    // everything and then go through our general path of adding a new task.
4250                    needAffiliationFix = true;
4251                }
4252            } else {
4253                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4254                needAffiliationFix = true;
4255            }
4256        }
4257
4258        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4259        trimRecentsForTask(task, true);
4260
4261        N = mRecentTasks.size();
4262        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4263            final TaskRecord tr = mRecentTasks.remove(N - 1);
4264            tr.removedFromRecents(mTaskPersister);
4265            N--;
4266        }
4267        task.inRecents = true;
4268        if (!isAffiliated || needAffiliationFix) {
4269            // If this is a simple non-affiliated task, or we had some failure trying to
4270            // handle it as part of an affilated task, then just place it at the top.
4271            mRecentTasks.add(0, task);
4272        } else if (isAffiliated) {
4273            // If this is a new affiliated task, then move all of the affiliated tasks
4274            // to the front and insert this new one.
4275            TaskRecord other = task.mNextAffiliate;
4276            if (other == null) {
4277                other = task.mPrevAffiliate;
4278            }
4279            if (other != null) {
4280                int otherIndex = mRecentTasks.indexOf(other);
4281                if (otherIndex >= 0) {
4282                    // Insert new task at appropriate location.
4283                    int taskIndex;
4284                    if (other == task.mNextAffiliate) {
4285                        // We found the index of our next affiliation, which is who is
4286                        // before us in the list, so add after that point.
4287                        taskIndex = otherIndex+1;
4288                    } else {
4289                        // We found the index of our previous affiliation, which is who is
4290                        // after us in the list, so add at their position.
4291                        taskIndex = otherIndex;
4292                    }
4293                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4294                            + taskIndex + ": " + task);
4295                    mRecentTasks.add(taskIndex, task);
4296
4297                    // Now move everything to the front.
4298                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4299                        // All went well.
4300                        return;
4301                    }
4302
4303                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4304                    // everything and then go through our general path of adding a new task.
4305                    needAffiliationFix = true;
4306                } else {
4307                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4308                            + other);
4309                    needAffiliationFix = true;
4310                }
4311            } else {
4312                if (DEBUG_RECENTS) Slog.d(TAG,
4313                        "addRecent: adding affiliated task without next/prev:" + task);
4314                needAffiliationFix = true;
4315            }
4316        }
4317        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4318
4319        if (needAffiliationFix) {
4320            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4321            cleanupRecentTasksLocked(task.userId);
4322        }
4323    }
4324
4325    /**
4326     * If needed, remove oldest existing entries in recents that are for the same kind
4327     * of task as the given one.
4328     */
4329    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4330        int N = mRecentTasks.size();
4331        final Intent intent = task.intent;
4332        final boolean document = intent != null && intent.isDocument();
4333
4334        int maxRecents = task.maxRecents - 1;
4335        for (int i=0; i<N; i++) {
4336            final TaskRecord tr = mRecentTasks.get(i);
4337            if (task != tr) {
4338                if (task.userId != tr.userId) {
4339                    continue;
4340                }
4341                if (i > MAX_RECENT_BITMAPS) {
4342                    tr.freeLastThumbnail();
4343                }
4344                final Intent trIntent = tr.intent;
4345                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4346                    (intent == null || !intent.filterEquals(trIntent))) {
4347                    continue;
4348                }
4349                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4350                if (document && trIsDocument) {
4351                    // These are the same document activity (not necessarily the same doc).
4352                    if (maxRecents > 0) {
4353                        --maxRecents;
4354                        continue;
4355                    }
4356                    // Hit the maximum number of documents for this task. Fall through
4357                    // and remove this document from recents.
4358                } else if (document || trIsDocument) {
4359                    // Only one of these is a document. Not the droid we're looking for.
4360                    continue;
4361                }
4362            }
4363
4364            if (!doTrim) {
4365                // If the caller is not actually asking for a trim, just tell them we reached
4366                // a point where the trim would happen.
4367                return i;
4368            }
4369
4370            // Either task and tr are the same or, their affinities match or their intents match
4371            // and neither of them is a document, or they are documents using the same activity
4372            // and their maxRecents has been reached.
4373            tr.disposeThumbnail();
4374            mRecentTasks.remove(i);
4375            if (task != tr) {
4376                tr.removedFromRecents(mTaskPersister);
4377            }
4378            i--;
4379            N--;
4380            if (task.intent == null) {
4381                // If the new recent task we are adding is not fully
4382                // specified, then replace it with the existing recent task.
4383                task = tr;
4384            }
4385            notifyTaskPersisterLocked(tr, false);
4386        }
4387
4388        return -1;
4389    }
4390
4391    @Override
4392    public void reportActivityFullyDrawn(IBinder token) {
4393        synchronized (this) {
4394            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4395            if (r == null) {
4396                return;
4397            }
4398            r.reportFullyDrawnLocked();
4399        }
4400    }
4401
4402    @Override
4403    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4404        synchronized (this) {
4405            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4406            if (r == null) {
4407                return;
4408            }
4409            final long origId = Binder.clearCallingIdentity();
4410            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4411            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4412                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4413            if (config != null) {
4414                r.frozenBeforeDestroy = true;
4415                if (!updateConfigurationLocked(config, r, false, false)) {
4416                    mStackSupervisor.resumeTopActivitiesLocked();
4417                }
4418            }
4419            Binder.restoreCallingIdentity(origId);
4420        }
4421    }
4422
4423    @Override
4424    public int getRequestedOrientation(IBinder token) {
4425        synchronized (this) {
4426            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4427            if (r == null) {
4428                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4429            }
4430            return mWindowManager.getAppOrientation(r.appToken);
4431        }
4432    }
4433
4434    /**
4435     * This is the internal entry point for handling Activity.finish().
4436     *
4437     * @param token The Binder token referencing the Activity we want to finish.
4438     * @param resultCode Result code, if any, from this Activity.
4439     * @param resultData Result data (Intent), if any, from this Activity.
4440     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4441     *            the root Activity in the task.
4442     *
4443     * @return Returns true if the activity successfully finished, or false if it is still running.
4444     */
4445    @Override
4446    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4447            boolean finishTask) {
4448        // Refuse possible leaked file descriptors
4449        if (resultData != null && resultData.hasFileDescriptors() == true) {
4450            throw new IllegalArgumentException("File descriptors passed in Intent");
4451        }
4452
4453        synchronized(this) {
4454            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455            if (r == null) {
4456                return true;
4457            }
4458            // Keep track of the root activity of the task before we finish it
4459            TaskRecord tr = r.task;
4460            ActivityRecord rootR = tr.getRootActivity();
4461            // Do not allow task to finish in Lock Task mode.
4462            if (tr == mStackSupervisor.mLockTaskModeTask) {
4463                if (rootR == r) {
4464                    mStackSupervisor.showLockTaskToast();
4465                    return false;
4466                }
4467            }
4468            if (mController != null) {
4469                // Find the first activity that is not finishing.
4470                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4471                if (next != null) {
4472                    // ask watcher if this is allowed
4473                    boolean resumeOK = true;
4474                    try {
4475                        resumeOK = mController.activityResuming(next.packageName);
4476                    } catch (RemoteException e) {
4477                        mController = null;
4478                        Watchdog.getInstance().setActivityController(null);
4479                    }
4480
4481                    if (!resumeOK) {
4482                        return false;
4483                    }
4484                }
4485            }
4486            final long origId = Binder.clearCallingIdentity();
4487            try {
4488                boolean res;
4489                if (finishTask && r == rootR) {
4490                    // If requested, remove the task that is associated to this activity only if it
4491                    // was the root activity in the task.  The result code and data is ignored because
4492                    // we don't support returning them across task boundaries.
4493                    res = removeTaskByIdLocked(tr.taskId, 0);
4494                } else {
4495                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4496                            resultData, "app-request", true);
4497                }
4498                return res;
4499            } finally {
4500                Binder.restoreCallingIdentity(origId);
4501            }
4502        }
4503    }
4504
4505    @Override
4506    public final void finishHeavyWeightApp() {
4507        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4508                != PackageManager.PERMISSION_GRANTED) {
4509            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4510                    + Binder.getCallingPid()
4511                    + ", uid=" + Binder.getCallingUid()
4512                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4513            Slog.w(TAG, msg);
4514            throw new SecurityException(msg);
4515        }
4516
4517        synchronized(this) {
4518            if (mHeavyWeightProcess == null) {
4519                return;
4520            }
4521
4522            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4523                    mHeavyWeightProcess.activities);
4524            for (int i=0; i<activities.size(); i++) {
4525                ActivityRecord r = activities.get(i);
4526                if (!r.finishing) {
4527                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4528                            null, "finish-heavy", true);
4529                }
4530            }
4531
4532            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4533                    mHeavyWeightProcess.userId, 0));
4534            mHeavyWeightProcess = null;
4535        }
4536    }
4537
4538    @Override
4539    public void crashApplication(int uid, int initialPid, String packageName,
4540            String message) {
4541        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4542                != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: crashApplication() from pid="
4544                    + Binder.getCallingPid()
4545                    + ", uid=" + Binder.getCallingUid()
4546                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4547            Slog.w(TAG, msg);
4548            throw new SecurityException(msg);
4549        }
4550
4551        synchronized(this) {
4552            ProcessRecord proc = null;
4553
4554            // Figure out which process to kill.  We don't trust that initialPid
4555            // still has any relation to current pids, so must scan through the
4556            // list.
4557            synchronized (mPidsSelfLocked) {
4558                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4559                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4560                    if (p.uid != uid) {
4561                        continue;
4562                    }
4563                    if (p.pid == initialPid) {
4564                        proc = p;
4565                        break;
4566                    }
4567                    if (p.pkgList.containsKey(packageName)) {
4568                        proc = p;
4569                    }
4570                }
4571            }
4572
4573            if (proc == null) {
4574                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4575                        + " initialPid=" + initialPid
4576                        + " packageName=" + packageName);
4577                return;
4578            }
4579
4580            if (proc.thread != null) {
4581                if (proc.pid == Process.myPid()) {
4582                    Log.w(TAG, "crashApplication: trying to crash self!");
4583                    return;
4584                }
4585                long ident = Binder.clearCallingIdentity();
4586                try {
4587                    proc.thread.scheduleCrash(message);
4588                } catch (RemoteException e) {
4589                }
4590                Binder.restoreCallingIdentity(ident);
4591            }
4592        }
4593    }
4594
4595    @Override
4596    public final void finishSubActivity(IBinder token, String resultWho,
4597            int requestCode) {
4598        synchronized(this) {
4599            final long origId = Binder.clearCallingIdentity();
4600            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4601            if (r != null) {
4602                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4603            }
4604            Binder.restoreCallingIdentity(origId);
4605        }
4606    }
4607
4608    @Override
4609    public boolean finishActivityAffinity(IBinder token) {
4610        synchronized(this) {
4611            final long origId = Binder.clearCallingIdentity();
4612            try {
4613                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4614
4615                ActivityRecord rootR = r.task.getRootActivity();
4616                // Do not allow task to finish in Lock Task mode.
4617                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4618                    if (rootR == r) {
4619                        mStackSupervisor.showLockTaskToast();
4620                        return false;
4621                    }
4622                }
4623                boolean res = false;
4624                if (r != null) {
4625                    res = r.task.stack.finishActivityAffinityLocked(r);
4626                }
4627                return res;
4628            } finally {
4629                Binder.restoreCallingIdentity(origId);
4630            }
4631        }
4632    }
4633
4634    @Override
4635    public void finishVoiceTask(IVoiceInteractionSession session) {
4636        synchronized(this) {
4637            final long origId = Binder.clearCallingIdentity();
4638            try {
4639                mStackSupervisor.finishVoiceTask(session);
4640            } finally {
4641                Binder.restoreCallingIdentity(origId);
4642            }
4643        }
4644
4645    }
4646
4647    @Override
4648    public boolean releaseActivityInstance(IBinder token) {
4649        synchronized(this) {
4650            final long origId = Binder.clearCallingIdentity();
4651            try {
4652                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4653                if (r.task == null || r.task.stack == null) {
4654                    return false;
4655                }
4656                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4657            } finally {
4658                Binder.restoreCallingIdentity(origId);
4659            }
4660        }
4661    }
4662
4663    @Override
4664    public void releaseSomeActivities(IApplicationThread appInt) {
4665        synchronized(this) {
4666            final long origId = Binder.clearCallingIdentity();
4667            try {
4668                ProcessRecord app = getRecordForAppLocked(appInt);
4669                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4670            } finally {
4671                Binder.restoreCallingIdentity(origId);
4672            }
4673        }
4674    }
4675
4676    @Override
4677    public boolean willActivityBeVisible(IBinder token) {
4678        synchronized(this) {
4679            ActivityStack stack = ActivityRecord.getStackLocked(token);
4680            if (stack != null) {
4681                return stack.willActivityBeVisibleLocked(token);
4682            }
4683            return false;
4684        }
4685    }
4686
4687    @Override
4688    public void overridePendingTransition(IBinder token, String packageName,
4689            int enterAnim, int exitAnim) {
4690        synchronized(this) {
4691            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4692            if (self == null) {
4693                return;
4694            }
4695
4696            final long origId = Binder.clearCallingIdentity();
4697
4698            if (self.state == ActivityState.RESUMED
4699                    || self.state == ActivityState.PAUSING) {
4700                mWindowManager.overridePendingAppTransition(packageName,
4701                        enterAnim, exitAnim, null);
4702            }
4703
4704            Binder.restoreCallingIdentity(origId);
4705        }
4706    }
4707
4708    /**
4709     * Main function for removing an existing process from the activity manager
4710     * as a result of that process going away.  Clears out all connections
4711     * to the process.
4712     */
4713    private final void handleAppDiedLocked(ProcessRecord app,
4714            boolean restarting, boolean allowRestart) {
4715        int pid = app.pid;
4716        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4717        if (!kept && !restarting) {
4718            removeLruProcessLocked(app);
4719            if (pid > 0) {
4720                ProcessList.remove(pid);
4721            }
4722        }
4723
4724        if (mProfileProc == app) {
4725            clearProfilerLocked();
4726        }
4727
4728        // Remove this application's activities from active lists.
4729        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4730
4731        app.activities.clear();
4732
4733        if (app.instrumentationClass != null) {
4734            Slog.w(TAG, "Crash of app " + app.processName
4735                  + " running instrumentation " + app.instrumentationClass);
4736            Bundle info = new Bundle();
4737            info.putString("shortMsg", "Process crashed.");
4738            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4739        }
4740
4741        if (!restarting) {
4742            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4743                // If there was nothing to resume, and we are not already
4744                // restarting this process, but there is a visible activity that
4745                // is hosted by the process...  then make sure all visible
4746                // activities are running, taking care of restarting this
4747                // process.
4748                if (hasVisibleActivities) {
4749                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4750                }
4751            }
4752        }
4753    }
4754
4755    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4756        IBinder threadBinder = thread.asBinder();
4757        // Find the application record.
4758        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4759            ProcessRecord rec = mLruProcesses.get(i);
4760            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4761                return i;
4762            }
4763        }
4764        return -1;
4765    }
4766
4767    final ProcessRecord getRecordForAppLocked(
4768            IApplicationThread thread) {
4769        if (thread == null) {
4770            return null;
4771        }
4772
4773        int appIndex = getLRURecordIndexForAppLocked(thread);
4774        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4775    }
4776
4777    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4778        // If there are no longer any background processes running,
4779        // and the app that died was not running instrumentation,
4780        // then tell everyone we are now low on memory.
4781        boolean haveBg = false;
4782        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4783            ProcessRecord rec = mLruProcesses.get(i);
4784            if (rec.thread != null
4785                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4786                haveBg = true;
4787                break;
4788            }
4789        }
4790
4791        if (!haveBg) {
4792            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4793            if (doReport) {
4794                long now = SystemClock.uptimeMillis();
4795                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4796                    doReport = false;
4797                } else {
4798                    mLastMemUsageReportTime = now;
4799                }
4800            }
4801            final ArrayList<ProcessMemInfo> memInfos
4802                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4803            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4804            long now = SystemClock.uptimeMillis();
4805            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4806                ProcessRecord rec = mLruProcesses.get(i);
4807                if (rec == dyingProc || rec.thread == null) {
4808                    continue;
4809                }
4810                if (doReport) {
4811                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4812                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4813                }
4814                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4815                    // The low memory report is overriding any current
4816                    // state for a GC request.  Make sure to do
4817                    // heavy/important/visible/foreground processes first.
4818                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4819                        rec.lastRequestedGc = 0;
4820                    } else {
4821                        rec.lastRequestedGc = rec.lastLowMemory;
4822                    }
4823                    rec.reportLowMemory = true;
4824                    rec.lastLowMemory = now;
4825                    mProcessesToGc.remove(rec);
4826                    addProcessToGcListLocked(rec);
4827                }
4828            }
4829            if (doReport) {
4830                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4831                mHandler.sendMessage(msg);
4832            }
4833            scheduleAppGcsLocked();
4834        }
4835    }
4836
4837    final void appDiedLocked(ProcessRecord app) {
4838       appDiedLocked(app, app.pid, app.thread);
4839    }
4840
4841    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4842        // First check if this ProcessRecord is actually active for the pid.
4843        synchronized (mPidsSelfLocked) {
4844            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4845            if (curProc != app) {
4846                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4847                return;
4848            }
4849        }
4850
4851        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4852        synchronized (stats) {
4853            stats.noteProcessDiedLocked(app.info.uid, pid);
4854        }
4855
4856        Process.killProcessQuiet(pid);
4857        Process.killProcessGroup(app.info.uid, pid);
4858        app.killed = true;
4859
4860        // Clean up already done if the process has been re-started.
4861        if (app.pid == pid && app.thread != null &&
4862                app.thread.asBinder() == thread.asBinder()) {
4863            boolean doLowMem = app.instrumentationClass == null;
4864            boolean doOomAdj = doLowMem;
4865            if (!app.killedByAm) {
4866                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4867                        + ") has died");
4868                mAllowLowerMemLevel = true;
4869            } else {
4870                // Note that we always want to do oom adj to update our state with the
4871                // new number of procs.
4872                mAllowLowerMemLevel = false;
4873                doLowMem = false;
4874            }
4875            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4876            if (DEBUG_CLEANUP) Slog.v(
4877                TAG, "Dying app: " + app + ", pid: " + pid
4878                + ", thread: " + thread.asBinder());
4879            handleAppDiedLocked(app, false, true);
4880
4881            if (doOomAdj) {
4882                updateOomAdjLocked();
4883            }
4884            if (doLowMem) {
4885                doLowMemReportIfNeededLocked(app);
4886            }
4887        } else if (app.pid != pid) {
4888            // A new process has already been started.
4889            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4890                    + ") has died and restarted (pid " + app.pid + ").");
4891            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4892        } else if (DEBUG_PROCESSES) {
4893            Slog.d(TAG, "Received spurious death notification for thread "
4894                    + thread.asBinder());
4895        }
4896    }
4897
4898    /**
4899     * If a stack trace dump file is configured, dump process stack traces.
4900     * @param clearTraces causes the dump file to be erased prior to the new
4901     *    traces being written, if true; when false, the new traces will be
4902     *    appended to any existing file content.
4903     * @param firstPids of dalvik VM processes to dump stack traces for first
4904     * @param lastPids of dalvik VM processes to dump stack traces for last
4905     * @param nativeProcs optional list of native process names to dump stack crawls
4906     * @return file containing stack traces, or null if no dump file is configured
4907     */
4908    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4909            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4910        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4911        if (tracesPath == null || tracesPath.length() == 0) {
4912            return null;
4913        }
4914
4915        File tracesFile = new File(tracesPath);
4916        try {
4917            File tracesDir = tracesFile.getParentFile();
4918            if (!tracesDir.exists()) {
4919                tracesDir.mkdirs();
4920                if (!SELinux.restorecon(tracesDir)) {
4921                    return null;
4922                }
4923            }
4924            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4925
4926            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4927            tracesFile.createNewFile();
4928            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4929        } catch (IOException e) {
4930            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4931            return null;
4932        }
4933
4934        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4935        return tracesFile;
4936    }
4937
4938    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4939            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4940        // Use a FileObserver to detect when traces finish writing.
4941        // The order of traces is considered important to maintain for legibility.
4942        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4943            @Override
4944            public synchronized void onEvent(int event, String path) { notify(); }
4945        };
4946
4947        try {
4948            observer.startWatching();
4949
4950            // First collect all of the stacks of the most important pids.
4951            if (firstPids != null) {
4952                try {
4953                    int num = firstPids.size();
4954                    for (int i = 0; i < num; i++) {
4955                        synchronized (observer) {
4956                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4957                            observer.wait(200);  // Wait for write-close, give up after 200msec
4958                        }
4959                    }
4960                } catch (InterruptedException e) {
4961                    Log.wtf(TAG, e);
4962                }
4963            }
4964
4965            // Next collect the stacks of the native pids
4966            if (nativeProcs != null) {
4967                int[] pids = Process.getPidsForCommands(nativeProcs);
4968                if (pids != null) {
4969                    for (int pid : pids) {
4970                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4971                    }
4972                }
4973            }
4974
4975            // Lastly, measure CPU usage.
4976            if (processCpuTracker != null) {
4977                processCpuTracker.init();
4978                System.gc();
4979                processCpuTracker.update();
4980                try {
4981                    synchronized (processCpuTracker) {
4982                        processCpuTracker.wait(500); // measure over 1/2 second.
4983                    }
4984                } catch (InterruptedException e) {
4985                }
4986                processCpuTracker.update();
4987
4988                // We'll take the stack crawls of just the top apps using CPU.
4989                final int N = processCpuTracker.countWorkingStats();
4990                int numProcs = 0;
4991                for (int i=0; i<N && numProcs<5; i++) {
4992                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4993                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4994                        numProcs++;
4995                        try {
4996                            synchronized (observer) {
4997                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4998                                observer.wait(200);  // Wait for write-close, give up after 200msec
4999                            }
5000                        } catch (InterruptedException e) {
5001                            Log.wtf(TAG, e);
5002                        }
5003
5004                    }
5005                }
5006            }
5007        } finally {
5008            observer.stopWatching();
5009        }
5010    }
5011
5012    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5013        if (true || IS_USER_BUILD) {
5014            return;
5015        }
5016        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5017        if (tracesPath == null || tracesPath.length() == 0) {
5018            return;
5019        }
5020
5021        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5022        StrictMode.allowThreadDiskWrites();
5023        try {
5024            final File tracesFile = new File(tracesPath);
5025            final File tracesDir = tracesFile.getParentFile();
5026            final File tracesTmp = new File(tracesDir, "__tmp__");
5027            try {
5028                if (!tracesDir.exists()) {
5029                    tracesDir.mkdirs();
5030                    if (!SELinux.restorecon(tracesDir.getPath())) {
5031                        return;
5032                    }
5033                }
5034                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5035
5036                if (tracesFile.exists()) {
5037                    tracesTmp.delete();
5038                    tracesFile.renameTo(tracesTmp);
5039                }
5040                StringBuilder sb = new StringBuilder();
5041                Time tobj = new Time();
5042                tobj.set(System.currentTimeMillis());
5043                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5044                sb.append(": ");
5045                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5046                sb.append(" since ");
5047                sb.append(msg);
5048                FileOutputStream fos = new FileOutputStream(tracesFile);
5049                fos.write(sb.toString().getBytes());
5050                if (app == null) {
5051                    fos.write("\n*** No application process!".getBytes());
5052                }
5053                fos.close();
5054                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5055            } catch (IOException e) {
5056                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5057                return;
5058            }
5059
5060            if (app != null) {
5061                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5062                firstPids.add(app.pid);
5063                dumpStackTraces(tracesPath, firstPids, null, null, null);
5064            }
5065
5066            File lastTracesFile = null;
5067            File curTracesFile = null;
5068            for (int i=9; i>=0; i--) {
5069                String name = String.format(Locale.US, "slow%02d.txt", i);
5070                curTracesFile = new File(tracesDir, name);
5071                if (curTracesFile.exists()) {
5072                    if (lastTracesFile != null) {
5073                        curTracesFile.renameTo(lastTracesFile);
5074                    } else {
5075                        curTracesFile.delete();
5076                    }
5077                }
5078                lastTracesFile = curTracesFile;
5079            }
5080            tracesFile.renameTo(curTracesFile);
5081            if (tracesTmp.exists()) {
5082                tracesTmp.renameTo(tracesFile);
5083            }
5084        } finally {
5085            StrictMode.setThreadPolicy(oldPolicy);
5086        }
5087    }
5088
5089    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5090            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5091        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5092        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5093
5094        if (mController != null) {
5095            try {
5096                // 0 == continue, -1 = kill process immediately
5097                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5098                if (res < 0 && app.pid != MY_PID) {
5099                    app.kill("anr", true);
5100                }
5101            } catch (RemoteException e) {
5102                mController = null;
5103                Watchdog.getInstance().setActivityController(null);
5104            }
5105        }
5106
5107        long anrTime = SystemClock.uptimeMillis();
5108        if (MONITOR_CPU_USAGE) {
5109            updateCpuStatsNow();
5110        }
5111
5112        synchronized (this) {
5113            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5114            if (mShuttingDown) {
5115                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5116                return;
5117            } else if (app.notResponding) {
5118                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5119                return;
5120            } else if (app.crashing) {
5121                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5122                return;
5123            }
5124
5125            // In case we come through here for the same app before completing
5126            // this one, mark as anring now so we will bail out.
5127            app.notResponding = true;
5128
5129            // Log the ANR to the event log.
5130            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5131                    app.processName, app.info.flags, annotation);
5132
5133            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5134            firstPids.add(app.pid);
5135
5136            int parentPid = app.pid;
5137            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5138            if (parentPid != app.pid) firstPids.add(parentPid);
5139
5140            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5141
5142            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5143                ProcessRecord r = mLruProcesses.get(i);
5144                if (r != null && r.thread != null) {
5145                    int pid = r.pid;
5146                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5147                        if (r.persistent) {
5148                            firstPids.add(pid);
5149                        } else {
5150                            lastPids.put(pid, Boolean.TRUE);
5151                        }
5152                    }
5153                }
5154            }
5155        }
5156
5157        // Log the ANR to the main log.
5158        StringBuilder info = new StringBuilder();
5159        info.setLength(0);
5160        info.append("ANR in ").append(app.processName);
5161        if (activity != null && activity.shortComponentName != null) {
5162            info.append(" (").append(activity.shortComponentName).append(")");
5163        }
5164        info.append("\n");
5165        info.append("PID: ").append(app.pid).append("\n");
5166        if (annotation != null) {
5167            info.append("Reason: ").append(annotation).append("\n");
5168        }
5169        if (parent != null && parent != activity) {
5170            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5171        }
5172
5173        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5174
5175        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5176                NATIVE_STACKS_OF_INTEREST);
5177
5178        String cpuInfo = null;
5179        if (MONITOR_CPU_USAGE) {
5180            updateCpuStatsNow();
5181            synchronized (mProcessCpuTracker) {
5182                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5183            }
5184            info.append(processCpuTracker.printCurrentLoad());
5185            info.append(cpuInfo);
5186        }
5187
5188        info.append(processCpuTracker.printCurrentState(anrTime));
5189
5190        Slog.e(TAG, info.toString());
5191        if (tracesFile == null) {
5192            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5193            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5194        }
5195
5196        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5197                cpuInfo, tracesFile, null);
5198
5199        if (mController != null) {
5200            try {
5201                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5202                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5203                if (res != 0) {
5204                    if (res < 0 && app.pid != MY_PID) {
5205                        app.kill("anr", true);
5206                    } else {
5207                        synchronized (this) {
5208                            mServices.scheduleServiceTimeoutLocked(app);
5209                        }
5210                    }
5211                    return;
5212                }
5213            } catch (RemoteException e) {
5214                mController = null;
5215                Watchdog.getInstance().setActivityController(null);
5216            }
5217        }
5218
5219        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5220        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5221                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5222
5223        synchronized (this) {
5224            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5225                app.kill("bg anr", true);
5226                return;
5227            }
5228
5229            // Set the app's notResponding state, and look up the errorReportReceiver
5230            makeAppNotRespondingLocked(app,
5231                    activity != null ? activity.shortComponentName : null,
5232                    annotation != null ? "ANR " + annotation : "ANR",
5233                    info.toString());
5234
5235            // Bring up the infamous App Not Responding dialog
5236            Message msg = Message.obtain();
5237            HashMap<String, Object> map = new HashMap<String, Object>();
5238            msg.what = SHOW_NOT_RESPONDING_MSG;
5239            msg.obj = map;
5240            msg.arg1 = aboveSystem ? 1 : 0;
5241            map.put("app", app);
5242            if (activity != null) {
5243                map.put("activity", activity);
5244            }
5245
5246            mHandler.sendMessage(msg);
5247        }
5248    }
5249
5250    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5251        if (!mLaunchWarningShown) {
5252            mLaunchWarningShown = true;
5253            mHandler.post(new Runnable() {
5254                @Override
5255                public void run() {
5256                    synchronized (ActivityManagerService.this) {
5257                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5258                        d.show();
5259                        mHandler.postDelayed(new Runnable() {
5260                            @Override
5261                            public void run() {
5262                                synchronized (ActivityManagerService.this) {
5263                                    d.dismiss();
5264                                    mLaunchWarningShown = false;
5265                                }
5266                            }
5267                        }, 4000);
5268                    }
5269                }
5270            });
5271        }
5272    }
5273
5274    @Override
5275    public boolean clearApplicationUserData(final String packageName,
5276            final IPackageDataObserver observer, int userId) {
5277        enforceNotIsolatedCaller("clearApplicationUserData");
5278        int uid = Binder.getCallingUid();
5279        int pid = Binder.getCallingPid();
5280        userId = handleIncomingUser(pid, uid,
5281                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5282        long callingId = Binder.clearCallingIdentity();
5283        try {
5284            IPackageManager pm = AppGlobals.getPackageManager();
5285            int pkgUid = -1;
5286            synchronized(this) {
5287                try {
5288                    pkgUid = pm.getPackageUid(packageName, userId);
5289                } catch (RemoteException e) {
5290                }
5291                if (pkgUid == -1) {
5292                    Slog.w(TAG, "Invalid packageName: " + packageName);
5293                    if (observer != null) {
5294                        try {
5295                            observer.onRemoveCompleted(packageName, false);
5296                        } catch (RemoteException e) {
5297                            Slog.i(TAG, "Observer no longer exists.");
5298                        }
5299                    }
5300                    return false;
5301                }
5302                if (uid == pkgUid || checkComponentPermission(
5303                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5304                        pid, uid, -1, true)
5305                        == PackageManager.PERMISSION_GRANTED) {
5306                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5307                } else {
5308                    throw new SecurityException("PID " + pid + " does not have permission "
5309                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5310                                    + " of package " + packageName);
5311                }
5312
5313                // Remove all tasks match the cleared application package and user
5314                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5315                    final TaskRecord tr = mRecentTasks.get(i);
5316                    final String taskPackageName =
5317                            tr.getBaseIntent().getComponent().getPackageName();
5318                    if (tr.userId != userId) continue;
5319                    if (!taskPackageName.equals(packageName)) continue;
5320                    removeTaskByIdLocked(tr.taskId, 0);
5321                }
5322            }
5323
5324            try {
5325                // Clear application user data
5326                pm.clearApplicationUserData(packageName, observer, userId);
5327
5328                synchronized(this) {
5329                    // Remove all permissions granted from/to this package
5330                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5331                }
5332
5333                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5334                        Uri.fromParts("package", packageName, null));
5335                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5336                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5337                        null, null, 0, null, null, null, false, false, userId);
5338            } catch (RemoteException e) {
5339            }
5340        } finally {
5341            Binder.restoreCallingIdentity(callingId);
5342        }
5343        return true;
5344    }
5345
5346    @Override
5347    public void killBackgroundProcesses(final String packageName, int userId) {
5348        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5349                != PackageManager.PERMISSION_GRANTED &&
5350                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5351                        != PackageManager.PERMISSION_GRANTED) {
5352            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5353                    + Binder.getCallingPid()
5354                    + ", uid=" + Binder.getCallingUid()
5355                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5356            Slog.w(TAG, msg);
5357            throw new SecurityException(msg);
5358        }
5359
5360        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5361                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5362        long callingId = Binder.clearCallingIdentity();
5363        try {
5364            IPackageManager pm = AppGlobals.getPackageManager();
5365            synchronized(this) {
5366                int appId = -1;
5367                try {
5368                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5369                } catch (RemoteException e) {
5370                }
5371                if (appId == -1) {
5372                    Slog.w(TAG, "Invalid packageName: " + packageName);
5373                    return;
5374                }
5375                killPackageProcessesLocked(packageName, appId, userId,
5376                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5377            }
5378        } finally {
5379            Binder.restoreCallingIdentity(callingId);
5380        }
5381    }
5382
5383    @Override
5384    public void killAllBackgroundProcesses() {
5385        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5386                != PackageManager.PERMISSION_GRANTED) {
5387            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5388                    + Binder.getCallingPid()
5389                    + ", uid=" + Binder.getCallingUid()
5390                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5391            Slog.w(TAG, msg);
5392            throw new SecurityException(msg);
5393        }
5394
5395        long callingId = Binder.clearCallingIdentity();
5396        try {
5397            synchronized(this) {
5398                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5399                final int NP = mProcessNames.getMap().size();
5400                for (int ip=0; ip<NP; ip++) {
5401                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5402                    final int NA = apps.size();
5403                    for (int ia=0; ia<NA; ia++) {
5404                        ProcessRecord app = apps.valueAt(ia);
5405                        if (app.persistent) {
5406                            // we don't kill persistent processes
5407                            continue;
5408                        }
5409                        if (app.removed) {
5410                            procs.add(app);
5411                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5412                            app.removed = true;
5413                            procs.add(app);
5414                        }
5415                    }
5416                }
5417
5418                int N = procs.size();
5419                for (int i=0; i<N; i++) {
5420                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5421                }
5422                mAllowLowerMemLevel = true;
5423                updateOomAdjLocked();
5424                doLowMemReportIfNeededLocked(null);
5425            }
5426        } finally {
5427            Binder.restoreCallingIdentity(callingId);
5428        }
5429    }
5430
5431    @Override
5432    public void forceStopPackage(final String packageName, int userId) {
5433        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5434                != PackageManager.PERMISSION_GRANTED) {
5435            String msg = "Permission Denial: forceStopPackage() from pid="
5436                    + Binder.getCallingPid()
5437                    + ", uid=" + Binder.getCallingUid()
5438                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5439            Slog.w(TAG, msg);
5440            throw new SecurityException(msg);
5441        }
5442        final int callingPid = Binder.getCallingPid();
5443        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5444                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5445        long callingId = Binder.clearCallingIdentity();
5446        try {
5447            IPackageManager pm = AppGlobals.getPackageManager();
5448            synchronized(this) {
5449                int[] users = userId == UserHandle.USER_ALL
5450                        ? getUsersLocked() : new int[] { userId };
5451                for (int user : users) {
5452                    int pkgUid = -1;
5453                    try {
5454                        pkgUid = pm.getPackageUid(packageName, user);
5455                    } catch (RemoteException e) {
5456                    }
5457                    if (pkgUid == -1) {
5458                        Slog.w(TAG, "Invalid packageName: " + packageName);
5459                        continue;
5460                    }
5461                    try {
5462                        pm.setPackageStoppedState(packageName, true, user);
5463                    } catch (RemoteException e) {
5464                    } catch (IllegalArgumentException e) {
5465                        Slog.w(TAG, "Failed trying to unstop package "
5466                                + packageName + ": " + e);
5467                    }
5468                    if (isUserRunningLocked(user, false)) {
5469                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5470                    }
5471                }
5472            }
5473        } finally {
5474            Binder.restoreCallingIdentity(callingId);
5475        }
5476    }
5477
5478    @Override
5479    public void addPackageDependency(String packageName) {
5480        synchronized (this) {
5481            int callingPid = Binder.getCallingPid();
5482            if (callingPid == Process.myPid()) {
5483                //  Yeah, um, no.
5484                Slog.w(TAG, "Can't addPackageDependency on system process");
5485                return;
5486            }
5487            ProcessRecord proc;
5488            synchronized (mPidsSelfLocked) {
5489                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5490            }
5491            if (proc != null) {
5492                if (proc.pkgDeps == null) {
5493                    proc.pkgDeps = new ArraySet<String>(1);
5494                }
5495                proc.pkgDeps.add(packageName);
5496            }
5497        }
5498    }
5499
5500    /*
5501     * The pkg name and app id have to be specified.
5502     */
5503    @Override
5504    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5505        if (pkg == null) {
5506            return;
5507        }
5508        // Make sure the uid is valid.
5509        if (appid < 0) {
5510            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5511            return;
5512        }
5513        int callerUid = Binder.getCallingUid();
5514        // Only the system server can kill an application
5515        if (callerUid == Process.SYSTEM_UID) {
5516            // Post an aysnc message to kill the application
5517            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5518            msg.arg1 = appid;
5519            msg.arg2 = 0;
5520            Bundle bundle = new Bundle();
5521            bundle.putString("pkg", pkg);
5522            bundle.putString("reason", reason);
5523            msg.obj = bundle;
5524            mHandler.sendMessage(msg);
5525        } else {
5526            throw new SecurityException(callerUid + " cannot kill pkg: " +
5527                    pkg);
5528        }
5529    }
5530
5531    @Override
5532    public void closeSystemDialogs(String reason) {
5533        enforceNotIsolatedCaller("closeSystemDialogs");
5534
5535        final int pid = Binder.getCallingPid();
5536        final int uid = Binder.getCallingUid();
5537        final long origId = Binder.clearCallingIdentity();
5538        try {
5539            synchronized (this) {
5540                // Only allow this from foreground processes, so that background
5541                // applications can't abuse it to prevent system UI from being shown.
5542                if (uid >= Process.FIRST_APPLICATION_UID) {
5543                    ProcessRecord proc;
5544                    synchronized (mPidsSelfLocked) {
5545                        proc = mPidsSelfLocked.get(pid);
5546                    }
5547                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5548                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5549                                + " from background process " + proc);
5550                        return;
5551                    }
5552                }
5553                closeSystemDialogsLocked(reason);
5554            }
5555        } finally {
5556            Binder.restoreCallingIdentity(origId);
5557        }
5558    }
5559
5560    void closeSystemDialogsLocked(String reason) {
5561        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5562        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5563                | Intent.FLAG_RECEIVER_FOREGROUND);
5564        if (reason != null) {
5565            intent.putExtra("reason", reason);
5566        }
5567        mWindowManager.closeSystemDialogs(reason);
5568
5569        mStackSupervisor.closeSystemDialogsLocked();
5570
5571        broadcastIntentLocked(null, null, intent, null,
5572                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5573                Process.SYSTEM_UID, UserHandle.USER_ALL);
5574    }
5575
5576    @Override
5577    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5578        enforceNotIsolatedCaller("getProcessMemoryInfo");
5579        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5580        for (int i=pids.length-1; i>=0; i--) {
5581            ProcessRecord proc;
5582            int oomAdj;
5583            synchronized (this) {
5584                synchronized (mPidsSelfLocked) {
5585                    proc = mPidsSelfLocked.get(pids[i]);
5586                    oomAdj = proc != null ? proc.setAdj : 0;
5587                }
5588            }
5589            infos[i] = new Debug.MemoryInfo();
5590            Debug.getMemoryInfo(pids[i], infos[i]);
5591            if (proc != null) {
5592                synchronized (this) {
5593                    if (proc.thread != null && proc.setAdj == oomAdj) {
5594                        // Record this for posterity if the process has been stable.
5595                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5596                                infos[i].getTotalUss(), false, proc.pkgList);
5597                    }
5598                }
5599            }
5600        }
5601        return infos;
5602    }
5603
5604    @Override
5605    public long[] getProcessPss(int[] pids) {
5606        enforceNotIsolatedCaller("getProcessPss");
5607        long[] pss = new long[pids.length];
5608        for (int i=pids.length-1; i>=0; i--) {
5609            ProcessRecord proc;
5610            int oomAdj;
5611            synchronized (this) {
5612                synchronized (mPidsSelfLocked) {
5613                    proc = mPidsSelfLocked.get(pids[i]);
5614                    oomAdj = proc != null ? proc.setAdj : 0;
5615                }
5616            }
5617            long[] tmpUss = new long[1];
5618            pss[i] = Debug.getPss(pids[i], tmpUss);
5619            if (proc != null) {
5620                synchronized (this) {
5621                    if (proc.thread != null && proc.setAdj == oomAdj) {
5622                        // Record this for posterity if the process has been stable.
5623                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5624                    }
5625                }
5626            }
5627        }
5628        return pss;
5629    }
5630
5631    @Override
5632    public void killApplicationProcess(String processName, int uid) {
5633        if (processName == null) {
5634            return;
5635        }
5636
5637        int callerUid = Binder.getCallingUid();
5638        // Only the system server can kill an application
5639        if (callerUid == Process.SYSTEM_UID) {
5640            synchronized (this) {
5641                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5642                if (app != null && app.thread != null) {
5643                    try {
5644                        app.thread.scheduleSuicide();
5645                    } catch (RemoteException e) {
5646                        // If the other end already died, then our work here is done.
5647                    }
5648                } else {
5649                    Slog.w(TAG, "Process/uid not found attempting kill of "
5650                            + processName + " / " + uid);
5651                }
5652            }
5653        } else {
5654            throw new SecurityException(callerUid + " cannot kill app process: " +
5655                    processName);
5656        }
5657    }
5658
5659    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5660        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5661                false, true, false, false, UserHandle.getUserId(uid), reason);
5662        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5663                Uri.fromParts("package", packageName, null));
5664        if (!mProcessesReady) {
5665            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5666                    | Intent.FLAG_RECEIVER_FOREGROUND);
5667        }
5668        intent.putExtra(Intent.EXTRA_UID, uid);
5669        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5670        broadcastIntentLocked(null, null, intent,
5671                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5672                false, false,
5673                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5674    }
5675
5676    private void forceStopUserLocked(int userId, String reason) {
5677        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5678        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5679        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5680                | Intent.FLAG_RECEIVER_FOREGROUND);
5681        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5682        broadcastIntentLocked(null, null, intent,
5683                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5684                false, false,
5685                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5686    }
5687
5688    private final boolean killPackageProcessesLocked(String packageName, int appId,
5689            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5690            boolean doit, boolean evenPersistent, String reason) {
5691        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5692
5693        // Remove all processes this package may have touched: all with the
5694        // same UID (except for the system or root user), and all whose name
5695        // matches the package name.
5696        final int NP = mProcessNames.getMap().size();
5697        for (int ip=0; ip<NP; ip++) {
5698            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699            final int NA = apps.size();
5700            for (int ia=0; ia<NA; ia++) {
5701                ProcessRecord app = apps.valueAt(ia);
5702                if (app.persistent && !evenPersistent) {
5703                    // we don't kill persistent processes
5704                    continue;
5705                }
5706                if (app.removed) {
5707                    if (doit) {
5708                        procs.add(app);
5709                    }
5710                    continue;
5711                }
5712
5713                // Skip process if it doesn't meet our oom adj requirement.
5714                if (app.setAdj < minOomAdj) {
5715                    continue;
5716                }
5717
5718                // If no package is specified, we call all processes under the
5719                // give user id.
5720                if (packageName == null) {
5721                    if (app.userId != userId) {
5722                        continue;
5723                    }
5724                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5725                        continue;
5726                    }
5727                // Package has been specified, we want to hit all processes
5728                // that match it.  We need to qualify this by the processes
5729                // that are running under the specified app and user ID.
5730                } else {
5731                    final boolean isDep = app.pkgDeps != null
5732                            && app.pkgDeps.contains(packageName);
5733                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5734                        continue;
5735                    }
5736                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5737                        continue;
5738                    }
5739                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5740                        continue;
5741                    }
5742                }
5743
5744                // Process has passed all conditions, kill it!
5745                if (!doit) {
5746                    return true;
5747                }
5748                app.removed = true;
5749                procs.add(app);
5750            }
5751        }
5752
5753        int N = procs.size();
5754        for (int i=0; i<N; i++) {
5755            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5756        }
5757        updateOomAdjLocked();
5758        return N > 0;
5759    }
5760
5761    private final boolean forceStopPackageLocked(String name, int appId,
5762            boolean callerWillRestart, boolean purgeCache, boolean doit,
5763            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5764        int i;
5765        int N;
5766
5767        if (userId == UserHandle.USER_ALL && name == null) {
5768            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5769        }
5770
5771        if (appId < 0 && name != null) {
5772            try {
5773                appId = UserHandle.getAppId(
5774                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5775            } catch (RemoteException e) {
5776            }
5777        }
5778
5779        if (doit) {
5780            if (name != null) {
5781                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5782                        + " user=" + userId + ": " + reason);
5783            } else {
5784                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5785            }
5786
5787            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5788            for (int ip=pmap.size()-1; ip>=0; ip--) {
5789                SparseArray<Long> ba = pmap.valueAt(ip);
5790                for (i=ba.size()-1; i>=0; i--) {
5791                    boolean remove = false;
5792                    final int entUid = ba.keyAt(i);
5793                    if (name != null) {
5794                        if (userId == UserHandle.USER_ALL) {
5795                            if (UserHandle.getAppId(entUid) == appId) {
5796                                remove = true;
5797                            }
5798                        } else {
5799                            if (entUid == UserHandle.getUid(userId, appId)) {
5800                                remove = true;
5801                            }
5802                        }
5803                    } else if (UserHandle.getUserId(entUid) == userId) {
5804                        remove = true;
5805                    }
5806                    if (remove) {
5807                        ba.removeAt(i);
5808                    }
5809                }
5810                if (ba.size() == 0) {
5811                    pmap.removeAt(ip);
5812                }
5813            }
5814        }
5815
5816        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5817                -100, callerWillRestart, true, doit, evenPersistent,
5818                name == null ? ("stop user " + userId) : ("stop " + name));
5819
5820        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5821            if (!doit) {
5822                return true;
5823            }
5824            didSomething = true;
5825        }
5826
5827        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5828            if (!doit) {
5829                return true;
5830            }
5831            didSomething = true;
5832        }
5833
5834        if (name == null) {
5835            // Remove all sticky broadcasts from this user.
5836            mStickyBroadcasts.remove(userId);
5837        }
5838
5839        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5840        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5841                userId, providers)) {
5842            if (!doit) {
5843                return true;
5844            }
5845            didSomething = true;
5846        }
5847        N = providers.size();
5848        for (i=0; i<N; i++) {
5849            removeDyingProviderLocked(null, providers.get(i), true);
5850        }
5851
5852        // Remove transient permissions granted from/to this package/user
5853        removeUriPermissionsForPackageLocked(name, userId, false);
5854
5855        if (name == null || uninstalling) {
5856            // Remove pending intents.  For now we only do this when force
5857            // stopping users, because we have some problems when doing this
5858            // for packages -- app widgets are not currently cleaned up for
5859            // such packages, so they can be left with bad pending intents.
5860            if (mIntentSenderRecords.size() > 0) {
5861                Iterator<WeakReference<PendingIntentRecord>> it
5862                        = mIntentSenderRecords.values().iterator();
5863                while (it.hasNext()) {
5864                    WeakReference<PendingIntentRecord> wpir = it.next();
5865                    if (wpir == null) {
5866                        it.remove();
5867                        continue;
5868                    }
5869                    PendingIntentRecord pir = wpir.get();
5870                    if (pir == null) {
5871                        it.remove();
5872                        continue;
5873                    }
5874                    if (name == null) {
5875                        // Stopping user, remove all objects for the user.
5876                        if (pir.key.userId != userId) {
5877                            // Not the same user, skip it.
5878                            continue;
5879                        }
5880                    } else {
5881                        if (UserHandle.getAppId(pir.uid) != appId) {
5882                            // Different app id, skip it.
5883                            continue;
5884                        }
5885                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5886                            // Different user, skip it.
5887                            continue;
5888                        }
5889                        if (!pir.key.packageName.equals(name)) {
5890                            // Different package, skip it.
5891                            continue;
5892                        }
5893                    }
5894                    if (!doit) {
5895                        return true;
5896                    }
5897                    didSomething = true;
5898                    it.remove();
5899                    pir.canceled = true;
5900                    if (pir.key.activity != null) {
5901                        pir.key.activity.pendingResults.remove(pir.ref);
5902                    }
5903                }
5904            }
5905        }
5906
5907        if (doit) {
5908            if (purgeCache && name != null) {
5909                AttributeCache ac = AttributeCache.instance();
5910                if (ac != null) {
5911                    ac.removePackage(name);
5912                }
5913            }
5914            if (mBooted) {
5915                mStackSupervisor.resumeTopActivitiesLocked();
5916                mStackSupervisor.scheduleIdleLocked();
5917            }
5918        }
5919
5920        return didSomething;
5921    }
5922
5923    private final boolean removeProcessLocked(ProcessRecord app,
5924            boolean callerWillRestart, boolean allowRestart, String reason) {
5925        final String name = app.processName;
5926        final int uid = app.uid;
5927        if (DEBUG_PROCESSES) Slog.d(
5928            TAG, "Force removing proc " + app.toShortString() + " (" + name
5929            + "/" + uid + ")");
5930
5931        mProcessNames.remove(name, uid);
5932        mIsolatedProcesses.remove(app.uid);
5933        if (mHeavyWeightProcess == app) {
5934            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5935                    mHeavyWeightProcess.userId, 0));
5936            mHeavyWeightProcess = null;
5937        }
5938        boolean needRestart = false;
5939        if (app.pid > 0 && app.pid != MY_PID) {
5940            int pid = app.pid;
5941            synchronized (mPidsSelfLocked) {
5942                mPidsSelfLocked.remove(pid);
5943                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5944            }
5945            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5946            if (app.isolated) {
5947                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5948            }
5949            app.kill(reason, true);
5950            handleAppDiedLocked(app, true, allowRestart);
5951            removeLruProcessLocked(app);
5952
5953            if (app.persistent && !app.isolated) {
5954                if (!callerWillRestart) {
5955                    addAppLocked(app.info, false, null /* ABI override */);
5956                } else {
5957                    needRestart = true;
5958                }
5959            }
5960        } else {
5961            mRemovedProcesses.add(app);
5962        }
5963
5964        return needRestart;
5965    }
5966
5967    private final void processStartTimedOutLocked(ProcessRecord app) {
5968        final int pid = app.pid;
5969        boolean gone = false;
5970        synchronized (mPidsSelfLocked) {
5971            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5972            if (knownApp != null && knownApp.thread == null) {
5973                mPidsSelfLocked.remove(pid);
5974                gone = true;
5975            }
5976        }
5977
5978        if (gone) {
5979            Slog.w(TAG, "Process " + app + " failed to attach");
5980            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5981                    pid, app.uid, app.processName);
5982            mProcessNames.remove(app.processName, app.uid);
5983            mIsolatedProcesses.remove(app.uid);
5984            if (mHeavyWeightProcess == app) {
5985                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5986                        mHeavyWeightProcess.userId, 0));
5987                mHeavyWeightProcess = null;
5988            }
5989            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5990            if (app.isolated) {
5991                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5992            }
5993            // Take care of any launching providers waiting for this process.
5994            checkAppInLaunchingProvidersLocked(app, true);
5995            // Take care of any services that are waiting for the process.
5996            mServices.processStartTimedOutLocked(app);
5997            app.kill("start timeout", true);
5998            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5999                Slog.w(TAG, "Unattached app died before backup, skipping");
6000                try {
6001                    IBackupManager bm = IBackupManager.Stub.asInterface(
6002                            ServiceManager.getService(Context.BACKUP_SERVICE));
6003                    bm.agentDisconnected(app.info.packageName);
6004                } catch (RemoteException e) {
6005                    // Can't happen; the backup manager is local
6006                }
6007            }
6008            if (isPendingBroadcastProcessLocked(pid)) {
6009                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6010                skipPendingBroadcastLocked(pid);
6011            }
6012        } else {
6013            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6014        }
6015    }
6016
6017    private final boolean attachApplicationLocked(IApplicationThread thread,
6018            int pid) {
6019
6020        // Find the application record that is being attached...  either via
6021        // the pid if we are running in multiple processes, or just pull the
6022        // next app record if we are emulating process with anonymous threads.
6023        ProcessRecord app;
6024        if (pid != MY_PID && pid >= 0) {
6025            synchronized (mPidsSelfLocked) {
6026                app = mPidsSelfLocked.get(pid);
6027            }
6028        } else {
6029            app = null;
6030        }
6031
6032        if (app == null) {
6033            Slog.w(TAG, "No pending application record for pid " + pid
6034                    + " (IApplicationThread " + thread + "); dropping process");
6035            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6036            if (pid > 0 && pid != MY_PID) {
6037                Process.killProcessQuiet(pid);
6038                //TODO: Process.killProcessGroup(app.info.uid, pid);
6039            } else {
6040                try {
6041                    thread.scheduleExit();
6042                } catch (Exception e) {
6043                    // Ignore exceptions.
6044                }
6045            }
6046            return false;
6047        }
6048
6049        // If this application record is still attached to a previous
6050        // process, clean it up now.
6051        if (app.thread != null) {
6052            handleAppDiedLocked(app, true, true);
6053        }
6054
6055        // Tell the process all about itself.
6056
6057        if (localLOGV) Slog.v(
6058                TAG, "Binding process pid " + pid + " to record " + app);
6059
6060        final String processName = app.processName;
6061        try {
6062            AppDeathRecipient adr = new AppDeathRecipient(
6063                    app, pid, thread);
6064            thread.asBinder().linkToDeath(adr, 0);
6065            app.deathRecipient = adr;
6066        } catch (RemoteException e) {
6067            app.resetPackageList(mProcessStats);
6068            startProcessLocked(app, "link fail", processName);
6069            return false;
6070        }
6071
6072        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6073
6074        app.makeActive(thread, mProcessStats);
6075        app.curAdj = app.setAdj = -100;
6076        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6077        app.forcingToForeground = null;
6078        updateProcessForegroundLocked(app, false, false);
6079        app.hasShownUi = false;
6080        app.debugging = false;
6081        app.cached = false;
6082
6083        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6084
6085        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6086        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6087
6088        if (!normalMode) {
6089            Slog.i(TAG, "Launching preboot mode app: " + app);
6090        }
6091
6092        if (localLOGV) Slog.v(
6093            TAG, "New app record " + app
6094            + " thread=" + thread.asBinder() + " pid=" + pid);
6095        try {
6096            int testMode = IApplicationThread.DEBUG_OFF;
6097            if (mDebugApp != null && mDebugApp.equals(processName)) {
6098                testMode = mWaitForDebugger
6099                    ? IApplicationThread.DEBUG_WAIT
6100                    : IApplicationThread.DEBUG_ON;
6101                app.debugging = true;
6102                if (mDebugTransient) {
6103                    mDebugApp = mOrigDebugApp;
6104                    mWaitForDebugger = mOrigWaitForDebugger;
6105                }
6106            }
6107            String profileFile = app.instrumentationProfileFile;
6108            ParcelFileDescriptor profileFd = null;
6109            int samplingInterval = 0;
6110            boolean profileAutoStop = false;
6111            if (mProfileApp != null && mProfileApp.equals(processName)) {
6112                mProfileProc = app;
6113                profileFile = mProfileFile;
6114                profileFd = mProfileFd;
6115                samplingInterval = mSamplingInterval;
6116                profileAutoStop = mAutoStopProfiler;
6117            }
6118            boolean enableOpenGlTrace = false;
6119            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6120                enableOpenGlTrace = true;
6121                mOpenGlTraceApp = null;
6122            }
6123
6124            // If the app is being launched for restore or full backup, set it up specially
6125            boolean isRestrictedBackupMode = false;
6126            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6127                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6128                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6129                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6130            }
6131
6132            ensurePackageDexOpt(app.instrumentationInfo != null
6133                    ? app.instrumentationInfo.packageName
6134                    : app.info.packageName);
6135            if (app.instrumentationClass != null) {
6136                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6137            }
6138            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6139                    + processName + " with config " + mConfiguration);
6140            ApplicationInfo appInfo = app.instrumentationInfo != null
6141                    ? app.instrumentationInfo : app.info;
6142            app.compat = compatibilityInfoForPackageLocked(appInfo);
6143            if (profileFd != null) {
6144                profileFd = profileFd.dup();
6145            }
6146            ProfilerInfo profilerInfo = profileFile == null ? null
6147                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6148            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6149                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6150                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6151                    isRestrictedBackupMode || !normalMode, app.persistent,
6152                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6153                    mCoreSettingsObserver.getCoreSettingsLocked());
6154            updateLruProcessLocked(app, false, null);
6155            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6156        } catch (Exception e) {
6157            // todo: Yikes!  What should we do?  For now we will try to
6158            // start another process, but that could easily get us in
6159            // an infinite loop of restarting processes...
6160            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6161
6162            app.resetPackageList(mProcessStats);
6163            app.unlinkDeathRecipient();
6164            startProcessLocked(app, "bind fail", processName);
6165            return false;
6166        }
6167
6168        // Remove this record from the list of starting applications.
6169        mPersistentStartingProcesses.remove(app);
6170        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6171                "Attach application locked removing on hold: " + app);
6172        mProcessesOnHold.remove(app);
6173
6174        boolean badApp = false;
6175        boolean didSomething = false;
6176
6177        // See if the top visible activity is waiting to run in this process...
6178        if (normalMode) {
6179            try {
6180                if (mStackSupervisor.attachApplicationLocked(app)) {
6181                    didSomething = true;
6182                }
6183            } catch (Exception e) {
6184                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6185                badApp = true;
6186            }
6187        }
6188
6189        // Find any services that should be running in this process...
6190        if (!badApp) {
6191            try {
6192                didSomething |= mServices.attachApplicationLocked(app, processName);
6193            } catch (Exception e) {
6194                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6195                badApp = true;
6196            }
6197        }
6198
6199        // Check if a next-broadcast receiver is in this process...
6200        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6201            try {
6202                didSomething |= sendPendingBroadcastsLocked(app);
6203            } catch (Exception e) {
6204                // If the app died trying to launch the receiver we declare it 'bad'
6205                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6206                badApp = true;
6207            }
6208        }
6209
6210        // Check whether the next backup agent is in this process...
6211        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6212            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6213            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6214            try {
6215                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6216                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6217                        mBackupTarget.backupMode);
6218            } catch (Exception e) {
6219                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6220                badApp = true;
6221            }
6222        }
6223
6224        if (badApp) {
6225            app.kill("error during init", true);
6226            handleAppDiedLocked(app, false, true);
6227            return false;
6228        }
6229
6230        if (!didSomething) {
6231            updateOomAdjLocked();
6232        }
6233
6234        return true;
6235    }
6236
6237    @Override
6238    public final void attachApplication(IApplicationThread thread) {
6239        synchronized (this) {
6240            int callingPid = Binder.getCallingPid();
6241            final long origId = Binder.clearCallingIdentity();
6242            attachApplicationLocked(thread, callingPid);
6243            Binder.restoreCallingIdentity(origId);
6244        }
6245    }
6246
6247    @Override
6248    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6249        final long origId = Binder.clearCallingIdentity();
6250        synchronized (this) {
6251            ActivityStack stack = ActivityRecord.getStackLocked(token);
6252            if (stack != null) {
6253                ActivityRecord r =
6254                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6255                if (stopProfiling) {
6256                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6257                        try {
6258                            mProfileFd.close();
6259                        } catch (IOException e) {
6260                        }
6261                        clearProfilerLocked();
6262                    }
6263                }
6264            }
6265        }
6266        Binder.restoreCallingIdentity(origId);
6267    }
6268
6269    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6270        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6271                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6272    }
6273
6274    void enableScreenAfterBoot() {
6275        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6276                SystemClock.uptimeMillis());
6277        mWindowManager.enableScreenAfterBoot();
6278
6279        synchronized (this) {
6280            updateEventDispatchingLocked();
6281        }
6282    }
6283
6284    @Override
6285    public void showBootMessage(final CharSequence msg, final boolean always) {
6286        enforceNotIsolatedCaller("showBootMessage");
6287        mWindowManager.showBootMessage(msg, always);
6288    }
6289
6290    @Override
6291    public void keyguardWaitingForActivityDrawn() {
6292        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6293        final long token = Binder.clearCallingIdentity();
6294        try {
6295            synchronized (this) {
6296                if (DEBUG_LOCKSCREEN) logLockScreen("");
6297                mWindowManager.keyguardWaitingForActivityDrawn();
6298                if (mLockScreenShown) {
6299                    mLockScreenShown = false;
6300                    comeOutOfSleepIfNeededLocked();
6301                }
6302            }
6303        } finally {
6304            Binder.restoreCallingIdentity(token);
6305        }
6306    }
6307
6308    final void finishBooting() {
6309        synchronized (this) {
6310            if (!mBootAnimationComplete) {
6311                mCallFinishBooting = true;
6312                return;
6313            }
6314            mCallFinishBooting = false;
6315        }
6316
6317        // Register receivers to handle package update events
6318        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6319
6320        // Let system services know.
6321        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6322
6323        synchronized (this) {
6324            // Ensure that any processes we had put on hold are now started
6325            // up.
6326            final int NP = mProcessesOnHold.size();
6327            if (NP > 0) {
6328                ArrayList<ProcessRecord> procs =
6329                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6330                for (int ip=0; ip<NP; ip++) {
6331                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6332                            + procs.get(ip));
6333                    startProcessLocked(procs.get(ip), "on-hold", null);
6334                }
6335            }
6336
6337            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6338                // Start looking for apps that are abusing wake locks.
6339                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6340                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6341                // Tell anyone interested that we are done booting!
6342                SystemProperties.set("sys.boot_completed", "1");
6343
6344                // And trigger dev.bootcomplete if we are not showing encryption progress
6345                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6346                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6347                    SystemProperties.set("dev.bootcomplete", "1");
6348                }
6349                for (int i=0; i<mStartedUsers.size(); i++) {
6350                    UserStartedState uss = mStartedUsers.valueAt(i);
6351                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6352                        uss.mState = UserStartedState.STATE_RUNNING;
6353                        final int userId = mStartedUsers.keyAt(i);
6354                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6355                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6356                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6357                        broadcastIntentLocked(null, null, intent, null,
6358                                new IIntentReceiver.Stub() {
6359                                    @Override
6360                                    public void performReceive(Intent intent, int resultCode,
6361                                            String data, Bundle extras, boolean ordered,
6362                                            boolean sticky, int sendingUser) {
6363                                        synchronized (ActivityManagerService.this) {
6364                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6365                                                    true, false);
6366                                        }
6367                                    }
6368                                },
6369                                0, null, null,
6370                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6371                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6372                                userId);
6373                    }
6374                }
6375                scheduleStartProfilesLocked();
6376            }
6377        }
6378    }
6379
6380    @Override
6381    public void bootAnimationComplete() {
6382        final boolean callFinishBooting;
6383        synchronized (this) {
6384            callFinishBooting = mCallFinishBooting;
6385            mBootAnimationComplete = true;
6386        }
6387        if (callFinishBooting) {
6388            finishBooting();
6389        }
6390    }
6391
6392    final void ensureBootCompleted() {
6393        boolean booting;
6394        boolean enableScreen;
6395        synchronized (this) {
6396            booting = mBooting;
6397            mBooting = false;
6398            enableScreen = !mBooted;
6399            mBooted = true;
6400        }
6401
6402        if (booting) {
6403            finishBooting();
6404        }
6405
6406        if (enableScreen) {
6407            enableScreenAfterBoot();
6408        }
6409    }
6410
6411    @Override
6412    public final void activityResumed(IBinder token) {
6413        final long origId = Binder.clearCallingIdentity();
6414        synchronized(this) {
6415            ActivityStack stack = ActivityRecord.getStackLocked(token);
6416            if (stack != null) {
6417                ActivityRecord.activityResumedLocked(token);
6418            }
6419        }
6420        Binder.restoreCallingIdentity(origId);
6421    }
6422
6423    @Override
6424    public final void activityPaused(IBinder token) {
6425        final long origId = Binder.clearCallingIdentity();
6426        synchronized(this) {
6427            ActivityStack stack = ActivityRecord.getStackLocked(token);
6428            if (stack != null) {
6429                stack.activityPausedLocked(token, false);
6430            }
6431        }
6432        Binder.restoreCallingIdentity(origId);
6433    }
6434
6435    @Override
6436    public final void activityStopped(IBinder token, Bundle icicle,
6437            PersistableBundle persistentState, CharSequence description) {
6438        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6439
6440        // Refuse possible leaked file descriptors
6441        if (icicle != null && icicle.hasFileDescriptors()) {
6442            throw new IllegalArgumentException("File descriptors passed in Bundle");
6443        }
6444
6445        final long origId = Binder.clearCallingIdentity();
6446
6447        synchronized (this) {
6448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6449            if (r != null) {
6450                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6451            }
6452        }
6453
6454        trimApplications();
6455
6456        Binder.restoreCallingIdentity(origId);
6457    }
6458
6459    @Override
6460    public final void activityDestroyed(IBinder token) {
6461        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6462        synchronized (this) {
6463            ActivityStack stack = ActivityRecord.getStackLocked(token);
6464            if (stack != null) {
6465                stack.activityDestroyedLocked(token);
6466            }
6467        }
6468    }
6469
6470    @Override
6471    public final void backgroundResourcesReleased(IBinder token) {
6472        final long origId = Binder.clearCallingIdentity();
6473        try {
6474            synchronized (this) {
6475                ActivityStack stack = ActivityRecord.getStackLocked(token);
6476                if (stack != null) {
6477                    stack.backgroundResourcesReleased(token);
6478                }
6479            }
6480        } finally {
6481            Binder.restoreCallingIdentity(origId);
6482        }
6483    }
6484
6485    @Override
6486    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6487        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6488    }
6489
6490    @Override
6491    public final void notifyEnterAnimationComplete(IBinder token) {
6492        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6493    }
6494
6495    @Override
6496    public String getCallingPackage(IBinder token) {
6497        synchronized (this) {
6498            ActivityRecord r = getCallingRecordLocked(token);
6499            return r != null ? r.info.packageName : null;
6500        }
6501    }
6502
6503    @Override
6504    public ComponentName getCallingActivity(IBinder token) {
6505        synchronized (this) {
6506            ActivityRecord r = getCallingRecordLocked(token);
6507            return r != null ? r.intent.getComponent() : null;
6508        }
6509    }
6510
6511    private ActivityRecord getCallingRecordLocked(IBinder token) {
6512        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6513        if (r == null) {
6514            return null;
6515        }
6516        return r.resultTo;
6517    }
6518
6519    @Override
6520    public ComponentName getActivityClassForToken(IBinder token) {
6521        synchronized(this) {
6522            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6523            if (r == null) {
6524                return null;
6525            }
6526            return r.intent.getComponent();
6527        }
6528    }
6529
6530    @Override
6531    public String getPackageForToken(IBinder token) {
6532        synchronized(this) {
6533            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6534            if (r == null) {
6535                return null;
6536            }
6537            return r.packageName;
6538        }
6539    }
6540
6541    @Override
6542    public IIntentSender getIntentSender(int type,
6543            String packageName, IBinder token, String resultWho,
6544            int requestCode, Intent[] intents, String[] resolvedTypes,
6545            int flags, Bundle options, int userId) {
6546        enforceNotIsolatedCaller("getIntentSender");
6547        // Refuse possible leaked file descriptors
6548        if (intents != null) {
6549            if (intents.length < 1) {
6550                throw new IllegalArgumentException("Intents array length must be >= 1");
6551            }
6552            for (int i=0; i<intents.length; i++) {
6553                Intent intent = intents[i];
6554                if (intent != null) {
6555                    if (intent.hasFileDescriptors()) {
6556                        throw new IllegalArgumentException("File descriptors passed in Intent");
6557                    }
6558                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6559                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6560                        throw new IllegalArgumentException(
6561                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6562                    }
6563                    intents[i] = new Intent(intent);
6564                }
6565            }
6566            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6567                throw new IllegalArgumentException(
6568                        "Intent array length does not match resolvedTypes length");
6569            }
6570        }
6571        if (options != null) {
6572            if (options.hasFileDescriptors()) {
6573                throw new IllegalArgumentException("File descriptors passed in options");
6574            }
6575        }
6576
6577        synchronized(this) {
6578            int callingUid = Binder.getCallingUid();
6579            int origUserId = userId;
6580            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6581                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6582                    ALLOW_NON_FULL, "getIntentSender", null);
6583            if (origUserId == UserHandle.USER_CURRENT) {
6584                // We don't want to evaluate this until the pending intent is
6585                // actually executed.  However, we do want to always do the
6586                // security checking for it above.
6587                userId = UserHandle.USER_CURRENT;
6588            }
6589            try {
6590                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6591                    int uid = AppGlobals.getPackageManager()
6592                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6593                    if (!UserHandle.isSameApp(callingUid, uid)) {
6594                        String msg = "Permission Denial: getIntentSender() from pid="
6595                            + Binder.getCallingPid()
6596                            + ", uid=" + Binder.getCallingUid()
6597                            + ", (need uid=" + uid + ")"
6598                            + " is not allowed to send as package " + packageName;
6599                        Slog.w(TAG, msg);
6600                        throw new SecurityException(msg);
6601                    }
6602                }
6603
6604                return getIntentSenderLocked(type, packageName, callingUid, userId,
6605                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6606
6607            } catch (RemoteException e) {
6608                throw new SecurityException(e);
6609            }
6610        }
6611    }
6612
6613    IIntentSender getIntentSenderLocked(int type, String packageName,
6614            int callingUid, int userId, IBinder token, String resultWho,
6615            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6616            Bundle options) {
6617        if (DEBUG_MU)
6618            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6619        ActivityRecord activity = null;
6620        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6621            activity = ActivityRecord.isInStackLocked(token);
6622            if (activity == null) {
6623                return null;
6624            }
6625            if (activity.finishing) {
6626                return null;
6627            }
6628        }
6629
6630        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6631        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6632        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6633        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6634                |PendingIntent.FLAG_UPDATE_CURRENT);
6635
6636        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6637                type, packageName, activity, resultWho,
6638                requestCode, intents, resolvedTypes, flags, options, userId);
6639        WeakReference<PendingIntentRecord> ref;
6640        ref = mIntentSenderRecords.get(key);
6641        PendingIntentRecord rec = ref != null ? ref.get() : null;
6642        if (rec != null) {
6643            if (!cancelCurrent) {
6644                if (updateCurrent) {
6645                    if (rec.key.requestIntent != null) {
6646                        rec.key.requestIntent.replaceExtras(intents != null ?
6647                                intents[intents.length - 1] : null);
6648                    }
6649                    if (intents != null) {
6650                        intents[intents.length-1] = rec.key.requestIntent;
6651                        rec.key.allIntents = intents;
6652                        rec.key.allResolvedTypes = resolvedTypes;
6653                    } else {
6654                        rec.key.allIntents = null;
6655                        rec.key.allResolvedTypes = null;
6656                    }
6657                }
6658                return rec;
6659            }
6660            rec.canceled = true;
6661            mIntentSenderRecords.remove(key);
6662        }
6663        if (noCreate) {
6664            return rec;
6665        }
6666        rec = new PendingIntentRecord(this, key, callingUid);
6667        mIntentSenderRecords.put(key, rec.ref);
6668        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6669            if (activity.pendingResults == null) {
6670                activity.pendingResults
6671                        = new HashSet<WeakReference<PendingIntentRecord>>();
6672            }
6673            activity.pendingResults.add(rec.ref);
6674        }
6675        return rec;
6676    }
6677
6678    @Override
6679    public void cancelIntentSender(IIntentSender sender) {
6680        if (!(sender instanceof PendingIntentRecord)) {
6681            return;
6682        }
6683        synchronized(this) {
6684            PendingIntentRecord rec = (PendingIntentRecord)sender;
6685            try {
6686                int uid = AppGlobals.getPackageManager()
6687                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6688                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6689                    String msg = "Permission Denial: cancelIntentSender() from pid="
6690                        + Binder.getCallingPid()
6691                        + ", uid=" + Binder.getCallingUid()
6692                        + " is not allowed to cancel packges "
6693                        + rec.key.packageName;
6694                    Slog.w(TAG, msg);
6695                    throw new SecurityException(msg);
6696                }
6697            } catch (RemoteException e) {
6698                throw new SecurityException(e);
6699            }
6700            cancelIntentSenderLocked(rec, true);
6701        }
6702    }
6703
6704    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6705        rec.canceled = true;
6706        mIntentSenderRecords.remove(rec.key);
6707        if (cleanActivity && rec.key.activity != null) {
6708            rec.key.activity.pendingResults.remove(rec.ref);
6709        }
6710    }
6711
6712    @Override
6713    public String getPackageForIntentSender(IIntentSender pendingResult) {
6714        if (!(pendingResult instanceof PendingIntentRecord)) {
6715            return null;
6716        }
6717        try {
6718            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6719            return res.key.packageName;
6720        } catch (ClassCastException e) {
6721        }
6722        return null;
6723    }
6724
6725    @Override
6726    public int getUidForIntentSender(IIntentSender sender) {
6727        if (sender instanceof PendingIntentRecord) {
6728            try {
6729                PendingIntentRecord res = (PendingIntentRecord)sender;
6730                return res.uid;
6731            } catch (ClassCastException e) {
6732            }
6733        }
6734        return -1;
6735    }
6736
6737    @Override
6738    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6739        if (!(pendingResult instanceof PendingIntentRecord)) {
6740            return false;
6741        }
6742        try {
6743            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6744            if (res.key.allIntents == null) {
6745                return false;
6746            }
6747            for (int i=0; i<res.key.allIntents.length; i++) {
6748                Intent intent = res.key.allIntents[i];
6749                if (intent.getPackage() != null && intent.getComponent() != null) {
6750                    return false;
6751                }
6752            }
6753            return true;
6754        } catch (ClassCastException e) {
6755        }
6756        return false;
6757    }
6758
6759    @Override
6760    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6761        if (!(pendingResult instanceof PendingIntentRecord)) {
6762            return false;
6763        }
6764        try {
6765            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6766            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6767                return true;
6768            }
6769            return false;
6770        } catch (ClassCastException e) {
6771        }
6772        return false;
6773    }
6774
6775    @Override
6776    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6777        if (!(pendingResult instanceof PendingIntentRecord)) {
6778            return null;
6779        }
6780        try {
6781            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6782            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6783        } catch (ClassCastException e) {
6784        }
6785        return null;
6786    }
6787
6788    @Override
6789    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6790        if (!(pendingResult instanceof PendingIntentRecord)) {
6791            return null;
6792        }
6793        try {
6794            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6795            Intent intent = res.key.requestIntent;
6796            if (intent != null) {
6797                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6798                        || res.lastTagPrefix.equals(prefix))) {
6799                    return res.lastTag;
6800                }
6801                res.lastTagPrefix = prefix;
6802                StringBuilder sb = new StringBuilder(128);
6803                if (prefix != null) {
6804                    sb.append(prefix);
6805                }
6806                if (intent.getAction() != null) {
6807                    sb.append(intent.getAction());
6808                } else if (intent.getComponent() != null) {
6809                    intent.getComponent().appendShortString(sb);
6810                } else {
6811                    sb.append("?");
6812                }
6813                return res.lastTag = sb.toString();
6814            }
6815        } catch (ClassCastException e) {
6816        }
6817        return null;
6818    }
6819
6820    @Override
6821    public void setProcessLimit(int max) {
6822        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6823                "setProcessLimit()");
6824        synchronized (this) {
6825            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6826            mProcessLimitOverride = max;
6827        }
6828        trimApplications();
6829    }
6830
6831    @Override
6832    public int getProcessLimit() {
6833        synchronized (this) {
6834            return mProcessLimitOverride;
6835        }
6836    }
6837
6838    void foregroundTokenDied(ForegroundToken token) {
6839        synchronized (ActivityManagerService.this) {
6840            synchronized (mPidsSelfLocked) {
6841                ForegroundToken cur
6842                    = mForegroundProcesses.get(token.pid);
6843                if (cur != token) {
6844                    return;
6845                }
6846                mForegroundProcesses.remove(token.pid);
6847                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6848                if (pr == null) {
6849                    return;
6850                }
6851                pr.forcingToForeground = null;
6852                updateProcessForegroundLocked(pr, false, false);
6853            }
6854            updateOomAdjLocked();
6855        }
6856    }
6857
6858    @Override
6859    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6860        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6861                "setProcessForeground()");
6862        synchronized(this) {
6863            boolean changed = false;
6864
6865            synchronized (mPidsSelfLocked) {
6866                ProcessRecord pr = mPidsSelfLocked.get(pid);
6867                if (pr == null && isForeground) {
6868                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6869                    return;
6870                }
6871                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6872                if (oldToken != null) {
6873                    oldToken.token.unlinkToDeath(oldToken, 0);
6874                    mForegroundProcesses.remove(pid);
6875                    if (pr != null) {
6876                        pr.forcingToForeground = null;
6877                    }
6878                    changed = true;
6879                }
6880                if (isForeground && token != null) {
6881                    ForegroundToken newToken = new ForegroundToken() {
6882                        @Override
6883                        public void binderDied() {
6884                            foregroundTokenDied(this);
6885                        }
6886                    };
6887                    newToken.pid = pid;
6888                    newToken.token = token;
6889                    try {
6890                        token.linkToDeath(newToken, 0);
6891                        mForegroundProcesses.put(pid, newToken);
6892                        pr.forcingToForeground = token;
6893                        changed = true;
6894                    } catch (RemoteException e) {
6895                        // If the process died while doing this, we will later
6896                        // do the cleanup with the process death link.
6897                    }
6898                }
6899            }
6900
6901            if (changed) {
6902                updateOomAdjLocked();
6903            }
6904        }
6905    }
6906
6907    // =========================================================
6908    // PERMISSIONS
6909    // =========================================================
6910
6911    static class PermissionController extends IPermissionController.Stub {
6912        ActivityManagerService mActivityManagerService;
6913        PermissionController(ActivityManagerService activityManagerService) {
6914            mActivityManagerService = activityManagerService;
6915        }
6916
6917        @Override
6918        public boolean checkPermission(String permission, int pid, int uid) {
6919            return mActivityManagerService.checkPermission(permission, pid,
6920                    uid) == PackageManager.PERMISSION_GRANTED;
6921        }
6922    }
6923
6924    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6925        @Override
6926        public int checkComponentPermission(String permission, int pid, int uid,
6927                int owningUid, boolean exported) {
6928            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6929                    owningUid, exported);
6930        }
6931
6932        @Override
6933        public Object getAMSLock() {
6934            return ActivityManagerService.this;
6935        }
6936    }
6937
6938    /**
6939     * This can be called with or without the global lock held.
6940     */
6941    int checkComponentPermission(String permission, int pid, int uid,
6942            int owningUid, boolean exported) {
6943        // We might be performing an operation on behalf of an indirect binder
6944        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6945        // client identity accordingly before proceeding.
6946        Identity tlsIdentity = sCallerIdentity.get();
6947        if (tlsIdentity != null) {
6948            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6949                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6950            uid = tlsIdentity.uid;
6951            pid = tlsIdentity.pid;
6952        }
6953
6954        if (pid == MY_PID) {
6955            return PackageManager.PERMISSION_GRANTED;
6956        }
6957
6958        return ActivityManager.checkComponentPermission(permission, uid,
6959                owningUid, exported);
6960    }
6961
6962    /**
6963     * As the only public entry point for permissions checking, this method
6964     * can enforce the semantic that requesting a check on a null global
6965     * permission is automatically denied.  (Internally a null permission
6966     * string is used when calling {@link #checkComponentPermission} in cases
6967     * when only uid-based security is needed.)
6968     *
6969     * This can be called with or without the global lock held.
6970     */
6971    @Override
6972    public int checkPermission(String permission, int pid, int uid) {
6973        if (permission == null) {
6974            return PackageManager.PERMISSION_DENIED;
6975        }
6976        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6977    }
6978
6979    /**
6980     * Binder IPC calls go through the public entry point.
6981     * This can be called with or without the global lock held.
6982     */
6983    int checkCallingPermission(String permission) {
6984        return checkPermission(permission,
6985                Binder.getCallingPid(),
6986                UserHandle.getAppId(Binder.getCallingUid()));
6987    }
6988
6989    /**
6990     * This can be called with or without the global lock held.
6991     */
6992    void enforceCallingPermission(String permission, String func) {
6993        if (checkCallingPermission(permission)
6994                == PackageManager.PERMISSION_GRANTED) {
6995            return;
6996        }
6997
6998        String msg = "Permission Denial: " + func + " from pid="
6999                + Binder.getCallingPid()
7000                + ", uid=" + Binder.getCallingUid()
7001                + " requires " + permission;
7002        Slog.w(TAG, msg);
7003        throw new SecurityException(msg);
7004    }
7005
7006    /**
7007     * Determine if UID is holding permissions required to access {@link Uri} in
7008     * the given {@link ProviderInfo}. Final permission checking is always done
7009     * in {@link ContentProvider}.
7010     */
7011    private final boolean checkHoldingPermissionsLocked(
7012            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7013        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7014                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7015        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7016            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7017                    != PERMISSION_GRANTED) {
7018                return false;
7019            }
7020        }
7021        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7022    }
7023
7024    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7025            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7026        if (pi.applicationInfo.uid == uid) {
7027            return true;
7028        } else if (!pi.exported) {
7029            return false;
7030        }
7031
7032        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7033        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7034        try {
7035            // check if target holds top-level <provider> permissions
7036            if (!readMet && pi.readPermission != null && considerUidPermissions
7037                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7038                readMet = true;
7039            }
7040            if (!writeMet && pi.writePermission != null && considerUidPermissions
7041                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7042                writeMet = true;
7043            }
7044
7045            // track if unprotected read/write is allowed; any denied
7046            // <path-permission> below removes this ability
7047            boolean allowDefaultRead = pi.readPermission == null;
7048            boolean allowDefaultWrite = pi.writePermission == null;
7049
7050            // check if target holds any <path-permission> that match uri
7051            final PathPermission[] pps = pi.pathPermissions;
7052            if (pps != null) {
7053                final String path = grantUri.uri.getPath();
7054                int i = pps.length;
7055                while (i > 0 && (!readMet || !writeMet)) {
7056                    i--;
7057                    PathPermission pp = pps[i];
7058                    if (pp.match(path)) {
7059                        if (!readMet) {
7060                            final String pprperm = pp.getReadPermission();
7061                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7062                                    + pprperm + " for " + pp.getPath()
7063                                    + ": match=" + pp.match(path)
7064                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7065                            if (pprperm != null) {
7066                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7067                                        == PERMISSION_GRANTED) {
7068                                    readMet = true;
7069                                } else {
7070                                    allowDefaultRead = false;
7071                                }
7072                            }
7073                        }
7074                        if (!writeMet) {
7075                            final String ppwperm = pp.getWritePermission();
7076                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7077                                    + ppwperm + " for " + pp.getPath()
7078                                    + ": match=" + pp.match(path)
7079                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7080                            if (ppwperm != null) {
7081                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7082                                        == PERMISSION_GRANTED) {
7083                                    writeMet = true;
7084                                } else {
7085                                    allowDefaultWrite = false;
7086                                }
7087                            }
7088                        }
7089                    }
7090                }
7091            }
7092
7093            // grant unprotected <provider> read/write, if not blocked by
7094            // <path-permission> above
7095            if (allowDefaultRead) readMet = true;
7096            if (allowDefaultWrite) writeMet = true;
7097
7098        } catch (RemoteException e) {
7099            return false;
7100        }
7101
7102        return readMet && writeMet;
7103    }
7104
7105    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7106        ProviderInfo pi = null;
7107        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7108        if (cpr != null) {
7109            pi = cpr.info;
7110        } else {
7111            try {
7112                pi = AppGlobals.getPackageManager().resolveContentProvider(
7113                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7114            } catch (RemoteException ex) {
7115            }
7116        }
7117        return pi;
7118    }
7119
7120    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7121        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7122        if (targetUris != null) {
7123            return targetUris.get(grantUri);
7124        }
7125        return null;
7126    }
7127
7128    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7129            String targetPkg, int targetUid, GrantUri grantUri) {
7130        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7131        if (targetUris == null) {
7132            targetUris = Maps.newArrayMap();
7133            mGrantedUriPermissions.put(targetUid, targetUris);
7134        }
7135
7136        UriPermission perm = targetUris.get(grantUri);
7137        if (perm == null) {
7138            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7139            targetUris.put(grantUri, perm);
7140        }
7141
7142        return perm;
7143    }
7144
7145    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7146            final int modeFlags) {
7147        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7148        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7149                : UriPermission.STRENGTH_OWNED;
7150
7151        // Root gets to do everything.
7152        if (uid == 0) {
7153            return true;
7154        }
7155
7156        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7157        if (perms == null) return false;
7158
7159        // First look for exact match
7160        final UriPermission exactPerm = perms.get(grantUri);
7161        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7162            return true;
7163        }
7164
7165        // No exact match, look for prefixes
7166        final int N = perms.size();
7167        for (int i = 0; i < N; i++) {
7168            final UriPermission perm = perms.valueAt(i);
7169            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7170                    && perm.getStrength(modeFlags) >= minStrength) {
7171                return true;
7172            }
7173        }
7174
7175        return false;
7176    }
7177
7178    /**
7179     * @param uri This uri must NOT contain an embedded userId.
7180     * @param userId The userId in which the uri is to be resolved.
7181     */
7182    @Override
7183    public int checkUriPermission(Uri uri, int pid, int uid,
7184            final int modeFlags, int userId) {
7185        enforceNotIsolatedCaller("checkUriPermission");
7186
7187        // Another redirected-binder-call permissions check as in
7188        // {@link checkComponentPermission}.
7189        Identity tlsIdentity = sCallerIdentity.get();
7190        if (tlsIdentity != null) {
7191            uid = tlsIdentity.uid;
7192            pid = tlsIdentity.pid;
7193        }
7194
7195        // Our own process gets to do everything.
7196        if (pid == MY_PID) {
7197            return PackageManager.PERMISSION_GRANTED;
7198        }
7199        synchronized (this) {
7200            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7201                    ? PackageManager.PERMISSION_GRANTED
7202                    : PackageManager.PERMISSION_DENIED;
7203        }
7204    }
7205
7206    /**
7207     * Check if the targetPkg can be granted permission to access uri by
7208     * the callingUid using the given modeFlags.  Throws a security exception
7209     * if callingUid is not allowed to do this.  Returns the uid of the target
7210     * if the URI permission grant should be performed; returns -1 if it is not
7211     * needed (for example targetPkg already has permission to access the URI).
7212     * If you already know the uid of the target, you can supply it in
7213     * lastTargetUid else set that to -1.
7214     */
7215    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7216            final int modeFlags, int lastTargetUid) {
7217        if (!Intent.isAccessUriMode(modeFlags)) {
7218            return -1;
7219        }
7220
7221        if (targetPkg != null) {
7222            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7223                    "Checking grant " + targetPkg + " permission to " + grantUri);
7224        }
7225
7226        final IPackageManager pm = AppGlobals.getPackageManager();
7227
7228        // If this is not a content: uri, we can't do anything with it.
7229        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7230            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7231                    "Can't grant URI permission for non-content URI: " + grantUri);
7232            return -1;
7233        }
7234
7235        final String authority = grantUri.uri.getAuthority();
7236        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7237        if (pi == null) {
7238            Slog.w(TAG, "No content provider found for permission check: " +
7239                    grantUri.uri.toSafeString());
7240            return -1;
7241        }
7242
7243        int targetUid = lastTargetUid;
7244        if (targetUid < 0 && targetPkg != null) {
7245            try {
7246                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7247                if (targetUid < 0) {
7248                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7249                            "Can't grant URI permission no uid for: " + targetPkg);
7250                    return -1;
7251                }
7252            } catch (RemoteException ex) {
7253                return -1;
7254            }
7255        }
7256
7257        if (targetUid >= 0) {
7258            // First...  does the target actually need this permission?
7259            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7260                // No need to grant the target this permission.
7261                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7262                        "Target " + targetPkg + " already has full permission to " + grantUri);
7263                return -1;
7264            }
7265        } else {
7266            // First...  there is no target package, so can anyone access it?
7267            boolean allowed = pi.exported;
7268            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7269                if (pi.readPermission != null) {
7270                    allowed = false;
7271                }
7272            }
7273            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7274                if (pi.writePermission != null) {
7275                    allowed = false;
7276                }
7277            }
7278            if (allowed) {
7279                return -1;
7280            }
7281        }
7282
7283        /* There is a special cross user grant if:
7284         * - The target is on another user.
7285         * - Apps on the current user can access the uri without any uid permissions.
7286         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7287         * grant uri permissions.
7288         */
7289        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7290                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7291                modeFlags, false /*without considering the uid permissions*/);
7292
7293        // Second...  is the provider allowing granting of URI permissions?
7294        if (!specialCrossUserGrant) {
7295            if (!pi.grantUriPermissions) {
7296                throw new SecurityException("Provider " + pi.packageName
7297                        + "/" + pi.name
7298                        + " does not allow granting of Uri permissions (uri "
7299                        + grantUri + ")");
7300            }
7301            if (pi.uriPermissionPatterns != null) {
7302                final int N = pi.uriPermissionPatterns.length;
7303                boolean allowed = false;
7304                for (int i=0; i<N; i++) {
7305                    if (pi.uriPermissionPatterns[i] != null
7306                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7307                        allowed = true;
7308                        break;
7309                    }
7310                }
7311                if (!allowed) {
7312                    throw new SecurityException("Provider " + pi.packageName
7313                            + "/" + pi.name
7314                            + " does not allow granting of permission to path of Uri "
7315                            + grantUri);
7316                }
7317            }
7318        }
7319
7320        // Third...  does the caller itself have permission to access
7321        // this uri?
7322        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7323            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7324                // Require they hold a strong enough Uri permission
7325                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7326                    throw new SecurityException("Uid " + callingUid
7327                            + " does not have permission to uri " + grantUri);
7328                }
7329            }
7330        }
7331        return targetUid;
7332    }
7333
7334    /**
7335     * @param uri This uri must NOT contain an embedded userId.
7336     * @param userId The userId in which the uri is to be resolved.
7337     */
7338    @Override
7339    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7340            final int modeFlags, int userId) {
7341        enforceNotIsolatedCaller("checkGrantUriPermission");
7342        synchronized(this) {
7343            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7344                    new GrantUri(userId, uri, false), modeFlags, -1);
7345        }
7346    }
7347
7348    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7349            final int modeFlags, UriPermissionOwner owner) {
7350        if (!Intent.isAccessUriMode(modeFlags)) {
7351            return;
7352        }
7353
7354        // So here we are: the caller has the assumed permission
7355        // to the uri, and the target doesn't.  Let's now give this to
7356        // the target.
7357
7358        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7359                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7360
7361        final String authority = grantUri.uri.getAuthority();
7362        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7363        if (pi == null) {
7364            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7365            return;
7366        }
7367
7368        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7369            grantUri.prefix = true;
7370        }
7371        final UriPermission perm = findOrCreateUriPermissionLocked(
7372                pi.packageName, targetPkg, targetUid, grantUri);
7373        perm.grantModes(modeFlags, owner);
7374    }
7375
7376    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7377            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7378        if (targetPkg == null) {
7379            throw new NullPointerException("targetPkg");
7380        }
7381        int targetUid;
7382        final IPackageManager pm = AppGlobals.getPackageManager();
7383        try {
7384            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7385        } catch (RemoteException ex) {
7386            return;
7387        }
7388
7389        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7390                targetUid);
7391        if (targetUid < 0) {
7392            return;
7393        }
7394
7395        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7396                owner);
7397    }
7398
7399    static class NeededUriGrants extends ArrayList<GrantUri> {
7400        final String targetPkg;
7401        final int targetUid;
7402        final int flags;
7403
7404        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7405            this.targetPkg = targetPkg;
7406            this.targetUid = targetUid;
7407            this.flags = flags;
7408        }
7409    }
7410
7411    /**
7412     * Like checkGrantUriPermissionLocked, but takes an Intent.
7413     */
7414    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7415            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7416        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7417                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7418                + " clip=" + (intent != null ? intent.getClipData() : null)
7419                + " from " + intent + "; flags=0x"
7420                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7421
7422        if (targetPkg == null) {
7423            throw new NullPointerException("targetPkg");
7424        }
7425
7426        if (intent == null) {
7427            return null;
7428        }
7429        Uri data = intent.getData();
7430        ClipData clip = intent.getClipData();
7431        if (data == null && clip == null) {
7432            return null;
7433        }
7434        // Default userId for uris in the intent (if they don't specify it themselves)
7435        int contentUserHint = intent.getContentUserHint();
7436        if (contentUserHint == UserHandle.USER_CURRENT) {
7437            contentUserHint = UserHandle.getUserId(callingUid);
7438        }
7439        final IPackageManager pm = AppGlobals.getPackageManager();
7440        int targetUid;
7441        if (needed != null) {
7442            targetUid = needed.targetUid;
7443        } else {
7444            try {
7445                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7446            } catch (RemoteException ex) {
7447                return null;
7448            }
7449            if (targetUid < 0) {
7450                if (DEBUG_URI_PERMISSION) {
7451                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7452                            + " on user " + targetUserId);
7453                }
7454                return null;
7455            }
7456        }
7457        if (data != null) {
7458            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7459            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7460                    targetUid);
7461            if (targetUid > 0) {
7462                if (needed == null) {
7463                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7464                }
7465                needed.add(grantUri);
7466            }
7467        }
7468        if (clip != null) {
7469            for (int i=0; i<clip.getItemCount(); i++) {
7470                Uri uri = clip.getItemAt(i).getUri();
7471                if (uri != null) {
7472                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7473                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7474                            targetUid);
7475                    if (targetUid > 0) {
7476                        if (needed == null) {
7477                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7478                        }
7479                        needed.add(grantUri);
7480                    }
7481                } else {
7482                    Intent clipIntent = clip.getItemAt(i).getIntent();
7483                    if (clipIntent != null) {
7484                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7485                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7486                        if (newNeeded != null) {
7487                            needed = newNeeded;
7488                        }
7489                    }
7490                }
7491            }
7492        }
7493
7494        return needed;
7495    }
7496
7497    /**
7498     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7499     */
7500    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7501            UriPermissionOwner owner) {
7502        if (needed != null) {
7503            for (int i=0; i<needed.size(); i++) {
7504                GrantUri grantUri = needed.get(i);
7505                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7506                        grantUri, needed.flags, owner);
7507            }
7508        }
7509    }
7510
7511    void grantUriPermissionFromIntentLocked(int callingUid,
7512            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7513        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7514                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7515        if (needed == null) {
7516            return;
7517        }
7518
7519        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7520    }
7521
7522    /**
7523     * @param uri This uri must NOT contain an embedded userId.
7524     * @param userId The userId in which the uri is to be resolved.
7525     */
7526    @Override
7527    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7528            final int modeFlags, int userId) {
7529        enforceNotIsolatedCaller("grantUriPermission");
7530        GrantUri grantUri = new GrantUri(userId, uri, false);
7531        synchronized(this) {
7532            final ProcessRecord r = getRecordForAppLocked(caller);
7533            if (r == null) {
7534                throw new SecurityException("Unable to find app for caller "
7535                        + caller
7536                        + " when granting permission to uri " + grantUri);
7537            }
7538            if (targetPkg == null) {
7539                throw new IllegalArgumentException("null target");
7540            }
7541            if (grantUri == null) {
7542                throw new IllegalArgumentException("null uri");
7543            }
7544
7545            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7546                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7547                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7548                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7549
7550            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7551                    UserHandle.getUserId(r.uid));
7552        }
7553    }
7554
7555    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7556        if (perm.modeFlags == 0) {
7557            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7558                    perm.targetUid);
7559            if (perms != null) {
7560                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7561                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7562
7563                perms.remove(perm.uri);
7564                if (perms.isEmpty()) {
7565                    mGrantedUriPermissions.remove(perm.targetUid);
7566                }
7567            }
7568        }
7569    }
7570
7571    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7572        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7573
7574        final IPackageManager pm = AppGlobals.getPackageManager();
7575        final String authority = grantUri.uri.getAuthority();
7576        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7577        if (pi == null) {
7578            Slog.w(TAG, "No content provider found for permission revoke: "
7579                    + grantUri.toSafeString());
7580            return;
7581        }
7582
7583        // Does the caller have this permission on the URI?
7584        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7585            // If they don't have direct access to the URI, then revoke any
7586            // ownerless URI permissions that have been granted to them.
7587            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7588            if (perms != null) {
7589                boolean persistChanged = false;
7590                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7591                    final UriPermission perm = it.next();
7592                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7593                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7594                        if (DEBUG_URI_PERMISSION)
7595                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7596                                    " permission to " + perm.uri);
7597                        persistChanged |= perm.revokeModes(
7598                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7599                        if (perm.modeFlags == 0) {
7600                            it.remove();
7601                        }
7602                    }
7603                }
7604                if (perms.isEmpty()) {
7605                    mGrantedUriPermissions.remove(callingUid);
7606                }
7607                if (persistChanged) {
7608                    schedulePersistUriGrants();
7609                }
7610            }
7611            return;
7612        }
7613
7614        boolean persistChanged = false;
7615
7616        // Go through all of the permissions and remove any that match.
7617        int N = mGrantedUriPermissions.size();
7618        for (int i = 0; i < N; i++) {
7619            final int targetUid = mGrantedUriPermissions.keyAt(i);
7620            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7621
7622            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7623                final UriPermission perm = it.next();
7624                if (perm.uri.sourceUserId == grantUri.sourceUserId
7625                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7626                    if (DEBUG_URI_PERMISSION)
7627                        Slog.v(TAG,
7628                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7629                    persistChanged |= perm.revokeModes(
7630                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7631                    if (perm.modeFlags == 0) {
7632                        it.remove();
7633                    }
7634                }
7635            }
7636
7637            if (perms.isEmpty()) {
7638                mGrantedUriPermissions.remove(targetUid);
7639                N--;
7640                i--;
7641            }
7642        }
7643
7644        if (persistChanged) {
7645            schedulePersistUriGrants();
7646        }
7647    }
7648
7649    /**
7650     * @param uri This uri must NOT contain an embedded userId.
7651     * @param userId The userId in which the uri is to be resolved.
7652     */
7653    @Override
7654    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7655            int userId) {
7656        enforceNotIsolatedCaller("revokeUriPermission");
7657        synchronized(this) {
7658            final ProcessRecord r = getRecordForAppLocked(caller);
7659            if (r == null) {
7660                throw new SecurityException("Unable to find app for caller "
7661                        + caller
7662                        + " when revoking permission to uri " + uri);
7663            }
7664            if (uri == null) {
7665                Slog.w(TAG, "revokeUriPermission: null uri");
7666                return;
7667            }
7668
7669            if (!Intent.isAccessUriMode(modeFlags)) {
7670                return;
7671            }
7672
7673            final IPackageManager pm = AppGlobals.getPackageManager();
7674            final String authority = uri.getAuthority();
7675            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7676            if (pi == null) {
7677                Slog.w(TAG, "No content provider found for permission revoke: "
7678                        + uri.toSafeString());
7679                return;
7680            }
7681
7682            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7683        }
7684    }
7685
7686    /**
7687     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7688     * given package.
7689     *
7690     * @param packageName Package name to match, or {@code null} to apply to all
7691     *            packages.
7692     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7693     *            to all users.
7694     * @param persistable If persistable grants should be removed.
7695     */
7696    private void removeUriPermissionsForPackageLocked(
7697            String packageName, int userHandle, boolean persistable) {
7698        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7699            throw new IllegalArgumentException("Must narrow by either package or user");
7700        }
7701
7702        boolean persistChanged = false;
7703
7704        int N = mGrantedUriPermissions.size();
7705        for (int i = 0; i < N; i++) {
7706            final int targetUid = mGrantedUriPermissions.keyAt(i);
7707            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7708
7709            // Only inspect grants matching user
7710            if (userHandle == UserHandle.USER_ALL
7711                    || userHandle == UserHandle.getUserId(targetUid)) {
7712                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7713                    final UriPermission perm = it.next();
7714
7715                    // Only inspect grants matching package
7716                    if (packageName == null || perm.sourcePkg.equals(packageName)
7717                            || perm.targetPkg.equals(packageName)) {
7718                        persistChanged |= perm.revokeModes(persistable
7719                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7720
7721                        // Only remove when no modes remain; any persisted grants
7722                        // will keep this alive.
7723                        if (perm.modeFlags == 0) {
7724                            it.remove();
7725                        }
7726                    }
7727                }
7728
7729                if (perms.isEmpty()) {
7730                    mGrantedUriPermissions.remove(targetUid);
7731                    N--;
7732                    i--;
7733                }
7734            }
7735        }
7736
7737        if (persistChanged) {
7738            schedulePersistUriGrants();
7739        }
7740    }
7741
7742    @Override
7743    public IBinder newUriPermissionOwner(String name) {
7744        enforceNotIsolatedCaller("newUriPermissionOwner");
7745        synchronized(this) {
7746            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7747            return owner.getExternalTokenLocked();
7748        }
7749    }
7750
7751    /**
7752     * @param uri This uri must NOT contain an embedded userId.
7753     * @param sourceUserId The userId in which the uri is to be resolved.
7754     * @param targetUserId The userId of the app that receives the grant.
7755     */
7756    @Override
7757    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7758            final int modeFlags, int sourceUserId, int targetUserId) {
7759        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7760                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7761        synchronized(this) {
7762            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7763            if (owner == null) {
7764                throw new IllegalArgumentException("Unknown owner: " + token);
7765            }
7766            if (fromUid != Binder.getCallingUid()) {
7767                if (Binder.getCallingUid() != Process.myUid()) {
7768                    // Only system code can grant URI permissions on behalf
7769                    // of other users.
7770                    throw new SecurityException("nice try");
7771                }
7772            }
7773            if (targetPkg == null) {
7774                throw new IllegalArgumentException("null target");
7775            }
7776            if (uri == null) {
7777                throw new IllegalArgumentException("null uri");
7778            }
7779
7780            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7781                    modeFlags, owner, targetUserId);
7782        }
7783    }
7784
7785    /**
7786     * @param uri This uri must NOT contain an embedded userId.
7787     * @param userId The userId in which the uri is to be resolved.
7788     */
7789    @Override
7790    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7791        synchronized(this) {
7792            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7793            if (owner == null) {
7794                throw new IllegalArgumentException("Unknown owner: " + token);
7795            }
7796
7797            if (uri == null) {
7798                owner.removeUriPermissionsLocked(mode);
7799            } else {
7800                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7801            }
7802        }
7803    }
7804
7805    private void schedulePersistUriGrants() {
7806        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7807            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7808                    10 * DateUtils.SECOND_IN_MILLIS);
7809        }
7810    }
7811
7812    private void writeGrantedUriPermissions() {
7813        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7814
7815        // Snapshot permissions so we can persist without lock
7816        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7817        synchronized (this) {
7818            final int size = mGrantedUriPermissions.size();
7819            for (int i = 0; i < size; i++) {
7820                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7821                for (UriPermission perm : perms.values()) {
7822                    if (perm.persistedModeFlags != 0) {
7823                        persist.add(perm.snapshot());
7824                    }
7825                }
7826            }
7827        }
7828
7829        FileOutputStream fos = null;
7830        try {
7831            fos = mGrantFile.startWrite();
7832
7833            XmlSerializer out = new FastXmlSerializer();
7834            out.setOutput(fos, "utf-8");
7835            out.startDocument(null, true);
7836            out.startTag(null, TAG_URI_GRANTS);
7837            for (UriPermission.Snapshot perm : persist) {
7838                out.startTag(null, TAG_URI_GRANT);
7839                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7840                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7841                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7842                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7843                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7844                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7845                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7846                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7847                out.endTag(null, TAG_URI_GRANT);
7848            }
7849            out.endTag(null, TAG_URI_GRANTS);
7850            out.endDocument();
7851
7852            mGrantFile.finishWrite(fos);
7853        } catch (IOException e) {
7854            if (fos != null) {
7855                mGrantFile.failWrite(fos);
7856            }
7857        }
7858    }
7859
7860    private void readGrantedUriPermissionsLocked() {
7861        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7862
7863        final long now = System.currentTimeMillis();
7864
7865        FileInputStream fis = null;
7866        try {
7867            fis = mGrantFile.openRead();
7868            final XmlPullParser in = Xml.newPullParser();
7869            in.setInput(fis, null);
7870
7871            int type;
7872            while ((type = in.next()) != END_DOCUMENT) {
7873                final String tag = in.getName();
7874                if (type == START_TAG) {
7875                    if (TAG_URI_GRANT.equals(tag)) {
7876                        final int sourceUserId;
7877                        final int targetUserId;
7878                        final int userHandle = readIntAttribute(in,
7879                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7880                        if (userHandle != UserHandle.USER_NULL) {
7881                            // For backwards compatibility.
7882                            sourceUserId = userHandle;
7883                            targetUserId = userHandle;
7884                        } else {
7885                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7886                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7887                        }
7888                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7889                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7890                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7891                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7892                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7893                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7894
7895                        // Sanity check that provider still belongs to source package
7896                        final ProviderInfo pi = getProviderInfoLocked(
7897                                uri.getAuthority(), sourceUserId);
7898                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7899                            int targetUid = -1;
7900                            try {
7901                                targetUid = AppGlobals.getPackageManager()
7902                                        .getPackageUid(targetPkg, targetUserId);
7903                            } catch (RemoteException e) {
7904                            }
7905                            if (targetUid != -1) {
7906                                final UriPermission perm = findOrCreateUriPermissionLocked(
7907                                        sourcePkg, targetPkg, targetUid,
7908                                        new GrantUri(sourceUserId, uri, prefix));
7909                                perm.initPersistedModes(modeFlags, createdTime);
7910                            }
7911                        } else {
7912                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7913                                    + " but instead found " + pi);
7914                        }
7915                    }
7916                }
7917            }
7918        } catch (FileNotFoundException e) {
7919            // Missing grants is okay
7920        } catch (IOException e) {
7921            Log.wtf(TAG, "Failed reading Uri grants", e);
7922        } catch (XmlPullParserException e) {
7923            Log.wtf(TAG, "Failed reading Uri grants", e);
7924        } finally {
7925            IoUtils.closeQuietly(fis);
7926        }
7927    }
7928
7929    /**
7930     * @param uri This uri must NOT contain an embedded userId.
7931     * @param userId The userId in which the uri is to be resolved.
7932     */
7933    @Override
7934    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7935        enforceNotIsolatedCaller("takePersistableUriPermission");
7936
7937        Preconditions.checkFlagsArgument(modeFlags,
7938                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7939
7940        synchronized (this) {
7941            final int callingUid = Binder.getCallingUid();
7942            boolean persistChanged = false;
7943            GrantUri grantUri = new GrantUri(userId, uri, false);
7944
7945            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7946                    new GrantUri(userId, uri, false));
7947            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7948                    new GrantUri(userId, uri, true));
7949
7950            final boolean exactValid = (exactPerm != null)
7951                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7952            final boolean prefixValid = (prefixPerm != null)
7953                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7954
7955            if (!(exactValid || prefixValid)) {
7956                throw new SecurityException("No persistable permission grants found for UID "
7957                        + callingUid + " and Uri " + grantUri.toSafeString());
7958            }
7959
7960            if (exactValid) {
7961                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7962            }
7963            if (prefixValid) {
7964                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7965            }
7966
7967            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7968
7969            if (persistChanged) {
7970                schedulePersistUriGrants();
7971            }
7972        }
7973    }
7974
7975    /**
7976     * @param uri This uri must NOT contain an embedded userId.
7977     * @param userId The userId in which the uri is to be resolved.
7978     */
7979    @Override
7980    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7981        enforceNotIsolatedCaller("releasePersistableUriPermission");
7982
7983        Preconditions.checkFlagsArgument(modeFlags,
7984                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7985
7986        synchronized (this) {
7987            final int callingUid = Binder.getCallingUid();
7988            boolean persistChanged = false;
7989
7990            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7991                    new GrantUri(userId, uri, false));
7992            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7993                    new GrantUri(userId, uri, true));
7994            if (exactPerm == null && prefixPerm == null) {
7995                throw new SecurityException("No permission grants found for UID " + callingUid
7996                        + " and Uri " + uri.toSafeString());
7997            }
7998
7999            if (exactPerm != null) {
8000                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8001                removeUriPermissionIfNeededLocked(exactPerm);
8002            }
8003            if (prefixPerm != null) {
8004                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8005                removeUriPermissionIfNeededLocked(prefixPerm);
8006            }
8007
8008            if (persistChanged) {
8009                schedulePersistUriGrants();
8010            }
8011        }
8012    }
8013
8014    /**
8015     * Prune any older {@link UriPermission} for the given UID until outstanding
8016     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8017     *
8018     * @return if any mutations occured that require persisting.
8019     */
8020    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8021        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8022        if (perms == null) return false;
8023        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8024
8025        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8026        for (UriPermission perm : perms.values()) {
8027            if (perm.persistedModeFlags != 0) {
8028                persisted.add(perm);
8029            }
8030        }
8031
8032        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8033        if (trimCount <= 0) return false;
8034
8035        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8036        for (int i = 0; i < trimCount; i++) {
8037            final UriPermission perm = persisted.get(i);
8038
8039            if (DEBUG_URI_PERMISSION) {
8040                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8041            }
8042
8043            perm.releasePersistableModes(~0);
8044            removeUriPermissionIfNeededLocked(perm);
8045        }
8046
8047        return true;
8048    }
8049
8050    @Override
8051    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8052            String packageName, boolean incoming) {
8053        enforceNotIsolatedCaller("getPersistedUriPermissions");
8054        Preconditions.checkNotNull(packageName, "packageName");
8055
8056        final int callingUid = Binder.getCallingUid();
8057        final IPackageManager pm = AppGlobals.getPackageManager();
8058        try {
8059            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8060            if (packageUid != callingUid) {
8061                throw new SecurityException(
8062                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8063            }
8064        } catch (RemoteException e) {
8065            throw new SecurityException("Failed to verify package name ownership");
8066        }
8067
8068        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8069        synchronized (this) {
8070            if (incoming) {
8071                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8072                        callingUid);
8073                if (perms == null) {
8074                    Slog.w(TAG, "No permission grants found for " + packageName);
8075                } else {
8076                    for (UriPermission perm : perms.values()) {
8077                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8078                            result.add(perm.buildPersistedPublicApiObject());
8079                        }
8080                    }
8081                }
8082            } else {
8083                final int size = mGrantedUriPermissions.size();
8084                for (int i = 0; i < size; i++) {
8085                    final ArrayMap<GrantUri, UriPermission> perms =
8086                            mGrantedUriPermissions.valueAt(i);
8087                    for (UriPermission perm : perms.values()) {
8088                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8089                            result.add(perm.buildPersistedPublicApiObject());
8090                        }
8091                    }
8092                }
8093            }
8094        }
8095        return new ParceledListSlice<android.content.UriPermission>(result);
8096    }
8097
8098    @Override
8099    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8100        synchronized (this) {
8101            ProcessRecord app =
8102                who != null ? getRecordForAppLocked(who) : null;
8103            if (app == null) return;
8104
8105            Message msg = Message.obtain();
8106            msg.what = WAIT_FOR_DEBUGGER_MSG;
8107            msg.obj = app;
8108            msg.arg1 = waiting ? 1 : 0;
8109            mHandler.sendMessage(msg);
8110        }
8111    }
8112
8113    @Override
8114    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8115        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8116        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8117        outInfo.availMem = Process.getFreeMemory();
8118        outInfo.totalMem = Process.getTotalMemory();
8119        outInfo.threshold = homeAppMem;
8120        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8121        outInfo.hiddenAppThreshold = cachedAppMem;
8122        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8123                ProcessList.SERVICE_ADJ);
8124        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8125                ProcessList.VISIBLE_APP_ADJ);
8126        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8127                ProcessList.FOREGROUND_APP_ADJ);
8128    }
8129
8130    // =========================================================
8131    // TASK MANAGEMENT
8132    // =========================================================
8133
8134    @Override
8135    public List<IAppTask> getAppTasks(String callingPackage) {
8136        int callingUid = Binder.getCallingUid();
8137        long ident = Binder.clearCallingIdentity();
8138
8139        synchronized(this) {
8140            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8141            try {
8142                if (localLOGV) Slog.v(TAG, "getAppTasks");
8143
8144                final int N = mRecentTasks.size();
8145                for (int i = 0; i < N; i++) {
8146                    TaskRecord tr = mRecentTasks.get(i);
8147                    // Skip tasks that do not match the caller.  We don't need to verify
8148                    // callingPackage, because we are also limiting to callingUid and know
8149                    // that will limit to the correct security sandbox.
8150                    if (tr.effectiveUid != callingUid) {
8151                        continue;
8152                    }
8153                    Intent intent = tr.getBaseIntent();
8154                    if (intent == null ||
8155                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8156                        continue;
8157                    }
8158                    ActivityManager.RecentTaskInfo taskInfo =
8159                            createRecentTaskInfoFromTaskRecord(tr);
8160                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8161                    list.add(taskImpl);
8162                }
8163            } finally {
8164                Binder.restoreCallingIdentity(ident);
8165            }
8166            return list;
8167        }
8168    }
8169
8170    @Override
8171    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8172        final int callingUid = Binder.getCallingUid();
8173        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8174
8175        synchronized(this) {
8176            if (localLOGV) Slog.v(
8177                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8178
8179            final boolean allowed = checkCallingPermission(
8180                    android.Manifest.permission.GET_TASKS)
8181                    == PackageManager.PERMISSION_GRANTED;
8182            if (!allowed) {
8183                Slog.w(TAG, "getTasks: caller " + callingUid
8184                        + " does not hold GET_TASKS; limiting output");
8185            }
8186
8187            // TODO: Improve with MRU list from all ActivityStacks.
8188            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8189        }
8190
8191        return list;
8192    }
8193
8194    TaskRecord getMostRecentTask() {
8195        return mRecentTasks.get(0);
8196    }
8197
8198    /**
8199     * Creates a new RecentTaskInfo from a TaskRecord.
8200     */
8201    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8202        // Update the task description to reflect any changes in the task stack
8203        tr.updateTaskDescription();
8204
8205        // Compose the recent task info
8206        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8207        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8208        rti.persistentId = tr.taskId;
8209        rti.baseIntent = new Intent(tr.getBaseIntent());
8210        rti.origActivity = tr.origActivity;
8211        rti.description = tr.lastDescription;
8212        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8213        rti.userId = tr.userId;
8214        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8215        rti.firstActiveTime = tr.firstActiveTime;
8216        rti.lastActiveTime = tr.lastActiveTime;
8217        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8218        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8219        return rti;
8220    }
8221
8222    @Override
8223    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8224        final int callingUid = Binder.getCallingUid();
8225        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8226                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8227
8228        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8229        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8230        synchronized (this) {
8231            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8232                    == PackageManager.PERMISSION_GRANTED;
8233            if (!allowed) {
8234                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8235                        + " does not hold GET_TASKS; limiting output");
8236            }
8237            final boolean detailed = checkCallingPermission(
8238                    android.Manifest.permission.GET_DETAILED_TASKS)
8239                    == PackageManager.PERMISSION_GRANTED;
8240
8241            final int N = mRecentTasks.size();
8242            ArrayList<ActivityManager.RecentTaskInfo> res
8243                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8244                            maxNum < N ? maxNum : N);
8245
8246            final Set<Integer> includedUsers;
8247            if (includeProfiles) {
8248                includedUsers = getProfileIdsLocked(userId);
8249            } else {
8250                includedUsers = new HashSet<Integer>();
8251            }
8252            includedUsers.add(Integer.valueOf(userId));
8253
8254            for (int i=0; i<N && maxNum > 0; i++) {
8255                TaskRecord tr = mRecentTasks.get(i);
8256                // Only add calling user or related users recent tasks
8257                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8258                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8259                    continue;
8260                }
8261
8262                // Return the entry if desired by the caller.  We always return
8263                // the first entry, because callers always expect this to be the
8264                // foreground app.  We may filter others if the caller has
8265                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8266                // we should exclude the entry.
8267
8268                if (i == 0
8269                        || withExcluded
8270                        || (tr.intent == null)
8271                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8272                                == 0)) {
8273                    if (!allowed) {
8274                        // If the caller doesn't have the GET_TASKS permission, then only
8275                        // allow them to see a small subset of tasks -- their own and home.
8276                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8277                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8278                            continue;
8279                        }
8280                    }
8281                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8282                        if (tr.stack != null && tr.stack.isHomeStack()) {
8283                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8284                            continue;
8285                        }
8286                    }
8287                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8288                        // Don't include auto remove tasks that are finished or finishing.
8289                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8290                                + tr);
8291                        continue;
8292                    }
8293                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8294                            && !tr.isAvailable) {
8295                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8296                        continue;
8297                    }
8298
8299                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8300                    if (!detailed) {
8301                        rti.baseIntent.replaceExtras((Bundle)null);
8302                    }
8303
8304                    res.add(rti);
8305                    maxNum--;
8306                }
8307            }
8308            return res;
8309        }
8310    }
8311
8312    private TaskRecord recentTaskForIdLocked(int id) {
8313        final int N = mRecentTasks.size();
8314            for (int i=0; i<N; i++) {
8315                TaskRecord tr = mRecentTasks.get(i);
8316                if (tr.taskId == id) {
8317                    return tr;
8318                }
8319            }
8320            return null;
8321    }
8322
8323    @Override
8324    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8325        synchronized (this) {
8326            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8327                    "getTaskThumbnail()");
8328            TaskRecord tr = recentTaskForIdLocked(id);
8329            if (tr != null) {
8330                return tr.getTaskThumbnailLocked();
8331            }
8332        }
8333        return null;
8334    }
8335
8336    @Override
8337    public int addAppTask(IBinder activityToken, Intent intent,
8338            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8339        final int callingUid = Binder.getCallingUid();
8340        final long callingIdent = Binder.clearCallingIdentity();
8341
8342        try {
8343            synchronized (this) {
8344                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8345                if (r == null) {
8346                    throw new IllegalArgumentException("Activity does not exist; token="
8347                            + activityToken);
8348                }
8349                ComponentName comp = intent.getComponent();
8350                if (comp == null) {
8351                    throw new IllegalArgumentException("Intent " + intent
8352                            + " must specify explicit component");
8353                }
8354                if (thumbnail.getWidth() != mThumbnailWidth
8355                        || thumbnail.getHeight() != mThumbnailHeight) {
8356                    throw new IllegalArgumentException("Bad thumbnail size: got "
8357                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8358                            + mThumbnailWidth + "x" + mThumbnailHeight);
8359                }
8360                if (intent.getSelector() != null) {
8361                    intent.setSelector(null);
8362                }
8363                if (intent.getSourceBounds() != null) {
8364                    intent.setSourceBounds(null);
8365                }
8366                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8367                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8368                        // The caller has added this as an auto-remove task...  that makes no
8369                        // sense, so turn off auto-remove.
8370                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8371                    }
8372                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8373                    // Must be a new task.
8374                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8375                }
8376                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8377                    mLastAddedTaskActivity = null;
8378                }
8379                ActivityInfo ainfo = mLastAddedTaskActivity;
8380                if (ainfo == null) {
8381                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8382                            comp, 0, UserHandle.getUserId(callingUid));
8383                    if (ainfo.applicationInfo.uid != callingUid) {
8384                        throw new SecurityException(
8385                                "Can't add task for another application: target uid="
8386                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8387                    }
8388                }
8389
8390                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8391                        intent, description);
8392
8393                int trimIdx = trimRecentsForTask(task, false);
8394                if (trimIdx >= 0) {
8395                    // If this would have caused a trim, then we'll abort because that
8396                    // means it would be added at the end of the list but then just removed.
8397                    return -1;
8398                }
8399
8400                final int N = mRecentTasks.size();
8401                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8402                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8403                    tr.removedFromRecents(mTaskPersister);
8404                }
8405
8406                task.inRecents = true;
8407                mRecentTasks.add(task);
8408                r.task.stack.addTask(task, false, false);
8409
8410                task.setLastThumbnail(thumbnail);
8411                task.freeLastThumbnail();
8412
8413                return task.taskId;
8414            }
8415        } finally {
8416            Binder.restoreCallingIdentity(callingIdent);
8417        }
8418    }
8419
8420    @Override
8421    public Point getAppTaskThumbnailSize() {
8422        synchronized (this) {
8423            return new Point(mThumbnailWidth,  mThumbnailHeight);
8424        }
8425    }
8426
8427    @Override
8428    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8429        synchronized (this) {
8430            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8431            if (r != null) {
8432                r.setTaskDescription(td);
8433                r.task.updateTaskDescription();
8434            }
8435        }
8436    }
8437
8438    @Override
8439    public Bitmap getTaskDescriptionIcon(String filename) {
8440        if (!FileUtils.isValidExtFilename(filename)
8441                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8442            throw new IllegalArgumentException("Bad filename: " + filename);
8443        }
8444        return mTaskPersister.getTaskDescriptionIcon(filename);
8445    }
8446
8447    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8448        mRecentTasks.remove(tr);
8449        tr.removedFromRecents(mTaskPersister);
8450        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8451        Intent baseIntent = new Intent(
8452                tr.intent != null ? tr.intent : tr.affinityIntent);
8453        ComponentName component = baseIntent.getComponent();
8454        if (component == null) {
8455            Slog.w(TAG, "Now component for base intent of task: " + tr);
8456            return;
8457        }
8458
8459        // Find any running services associated with this app.
8460        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8461
8462        if (killProcesses) {
8463            // Find any running processes associated with this app.
8464            final String pkg = component.getPackageName();
8465            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8466            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8467            for (int i=0; i<pmap.size(); i++) {
8468                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8469                for (int j=0; j<uids.size(); j++) {
8470                    ProcessRecord proc = uids.valueAt(j);
8471                    if (proc.userId != tr.userId) {
8472                        continue;
8473                    }
8474                    if (!proc.pkgList.containsKey(pkg)) {
8475                        continue;
8476                    }
8477                    procs.add(proc);
8478                }
8479            }
8480
8481            // Kill the running processes.
8482            for (int i=0; i<procs.size(); i++) {
8483                ProcessRecord pr = procs.get(i);
8484                if (pr == mHomeProcess) {
8485                    // Don't kill the home process along with tasks from the same package.
8486                    continue;
8487                }
8488                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8489                    pr.kill("remove task", true);
8490                } else {
8491                    pr.waitingToKill = "remove task";
8492                }
8493            }
8494        }
8495    }
8496
8497    /**
8498     * Removes the task with the specified task id.
8499     *
8500     * @param taskId Identifier of the task to be removed.
8501     * @param flags Additional operational flags.  May be 0 or
8502     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8503     * @return Returns true if the given task was found and removed.
8504     */
8505    private boolean removeTaskByIdLocked(int taskId, int flags) {
8506        TaskRecord tr = recentTaskForIdLocked(taskId);
8507        if (tr != null) {
8508            tr.removeTaskActivitiesLocked();
8509            cleanUpRemovedTaskLocked(tr, flags);
8510            if (tr.isPersistable) {
8511                notifyTaskPersisterLocked(null, true);
8512            }
8513            return true;
8514        }
8515        return false;
8516    }
8517
8518    @Override
8519    public boolean removeTask(int taskId, int flags) {
8520        synchronized (this) {
8521            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8522                    "removeTask()");
8523            long ident = Binder.clearCallingIdentity();
8524            try {
8525                return removeTaskByIdLocked(taskId, flags);
8526            } finally {
8527                Binder.restoreCallingIdentity(ident);
8528            }
8529        }
8530    }
8531
8532    /**
8533     * TODO: Add mController hook
8534     */
8535    @Override
8536    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8537        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8538                "moveTaskToFront()");
8539
8540        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8541        synchronized(this) {
8542            moveTaskToFrontLocked(taskId, flags, options);
8543        }
8544    }
8545
8546    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8547        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8548                Binder.getCallingUid(), -1, -1, "Task to front")) {
8549            ActivityOptions.abort(options);
8550            return;
8551        }
8552        final long origId = Binder.clearCallingIdentity();
8553        try {
8554            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8555            if (task == null) {
8556                return;
8557            }
8558            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8559                mStackSupervisor.showLockTaskToast();
8560                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8561                return;
8562            }
8563            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8564            if (prev != null && prev.isRecentsActivity()) {
8565                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8566            }
8567            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8568        } finally {
8569            Binder.restoreCallingIdentity(origId);
8570        }
8571        ActivityOptions.abort(options);
8572    }
8573
8574    @Override
8575    public void moveTaskToBack(int taskId) {
8576        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8577                "moveTaskToBack()");
8578
8579        synchronized(this) {
8580            TaskRecord tr = recentTaskForIdLocked(taskId);
8581            if (tr != null) {
8582                if (tr == mStackSupervisor.mLockTaskModeTask) {
8583                    mStackSupervisor.showLockTaskToast();
8584                    return;
8585                }
8586                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8587                ActivityStack stack = tr.stack;
8588                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8589                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8590                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8591                        return;
8592                    }
8593                }
8594                final long origId = Binder.clearCallingIdentity();
8595                try {
8596                    stack.moveTaskToBackLocked(taskId, null);
8597                } finally {
8598                    Binder.restoreCallingIdentity(origId);
8599                }
8600            }
8601        }
8602    }
8603
8604    /**
8605     * Moves an activity, and all of the other activities within the same task, to the bottom
8606     * of the history stack.  The activity's order within the task is unchanged.
8607     *
8608     * @param token A reference to the activity we wish to move
8609     * @param nonRoot If false then this only works if the activity is the root
8610     *                of a task; if true it will work for any activity in a task.
8611     * @return Returns true if the move completed, false if not.
8612     */
8613    @Override
8614    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8615        enforceNotIsolatedCaller("moveActivityTaskToBack");
8616        synchronized(this) {
8617            final long origId = Binder.clearCallingIdentity();
8618            try {
8619                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8620                if (taskId >= 0) {
8621                    if ((mStackSupervisor.mLockTaskModeTask != null)
8622                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8623                        mStackSupervisor.showLockTaskToast();
8624                        return false;
8625                    }
8626                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8627                }
8628            } finally {
8629                Binder.restoreCallingIdentity(origId);
8630            }
8631        }
8632        return false;
8633    }
8634
8635    @Override
8636    public void moveTaskBackwards(int task) {
8637        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8638                "moveTaskBackwards()");
8639
8640        synchronized(this) {
8641            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8642                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8643                return;
8644            }
8645            final long origId = Binder.clearCallingIdentity();
8646            moveTaskBackwardsLocked(task);
8647            Binder.restoreCallingIdentity(origId);
8648        }
8649    }
8650
8651    private final void moveTaskBackwardsLocked(int task) {
8652        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8653    }
8654
8655    @Override
8656    public IBinder getHomeActivityToken() throws RemoteException {
8657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8658                "getHomeActivityToken()");
8659        synchronized (this) {
8660            return mStackSupervisor.getHomeActivityToken();
8661        }
8662    }
8663
8664    @Override
8665    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8666            IActivityContainerCallback callback) throws RemoteException {
8667        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8668                "createActivityContainer()");
8669        synchronized (this) {
8670            if (parentActivityToken == null) {
8671                throw new IllegalArgumentException("parent token must not be null");
8672            }
8673            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8674            if (r == null) {
8675                return null;
8676            }
8677            if (callback == null) {
8678                throw new IllegalArgumentException("callback must not be null");
8679            }
8680            return mStackSupervisor.createActivityContainer(r, callback);
8681        }
8682    }
8683
8684    @Override
8685    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8686        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8687                "deleteActivityContainer()");
8688        synchronized (this) {
8689            mStackSupervisor.deleteActivityContainer(container);
8690        }
8691    }
8692
8693    @Override
8694    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8695            throws RemoteException {
8696        synchronized (this) {
8697            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8698            if (stack != null) {
8699                return stack.mActivityContainer;
8700            }
8701            return null;
8702        }
8703    }
8704
8705    @Override
8706    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8707        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8708                "moveTaskToStack()");
8709        if (stackId == HOME_STACK_ID) {
8710            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8711                    new RuntimeException("here").fillInStackTrace());
8712        }
8713        synchronized (this) {
8714            long ident = Binder.clearCallingIdentity();
8715            try {
8716                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8717                        + stackId + " toTop=" + toTop);
8718                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8719            } finally {
8720                Binder.restoreCallingIdentity(ident);
8721            }
8722        }
8723    }
8724
8725    @Override
8726    public void resizeStack(int stackBoxId, Rect bounds) {
8727        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8728                "resizeStackBox()");
8729        long ident = Binder.clearCallingIdentity();
8730        try {
8731            mWindowManager.resizeStack(stackBoxId, bounds);
8732        } finally {
8733            Binder.restoreCallingIdentity(ident);
8734        }
8735    }
8736
8737    @Override
8738    public List<StackInfo> getAllStackInfos() {
8739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8740                "getAllStackInfos()");
8741        long ident = Binder.clearCallingIdentity();
8742        try {
8743            synchronized (this) {
8744                return mStackSupervisor.getAllStackInfosLocked();
8745            }
8746        } finally {
8747            Binder.restoreCallingIdentity(ident);
8748        }
8749    }
8750
8751    @Override
8752    public StackInfo getStackInfo(int stackId) {
8753        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8754                "getStackInfo()");
8755        long ident = Binder.clearCallingIdentity();
8756        try {
8757            synchronized (this) {
8758                return mStackSupervisor.getStackInfoLocked(stackId);
8759            }
8760        } finally {
8761            Binder.restoreCallingIdentity(ident);
8762        }
8763    }
8764
8765    @Override
8766    public boolean isInHomeStack(int taskId) {
8767        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8768                "getStackInfo()");
8769        long ident = Binder.clearCallingIdentity();
8770        try {
8771            synchronized (this) {
8772                TaskRecord tr = recentTaskForIdLocked(taskId);
8773                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8774            }
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8782        synchronized(this) {
8783            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8784        }
8785    }
8786
8787    private boolean isLockTaskAuthorized(String pkg) {
8788        final DevicePolicyManager dpm = (DevicePolicyManager)
8789                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8790        try {
8791            int uid = mContext.getPackageManager().getPackageUid(pkg,
8792                    Binder.getCallingUserHandle().getIdentifier());
8793            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8794        } catch (NameNotFoundException e) {
8795            return false;
8796        }
8797    }
8798
8799    void startLockTaskMode(TaskRecord task) {
8800        final String pkg;
8801        synchronized (this) {
8802            pkg = task.intent.getComponent().getPackageName();
8803        }
8804        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8805        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8806            final TaskRecord taskRecord = task;
8807            mHandler.post(new Runnable() {
8808                @Override
8809                public void run() {
8810                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8811                }
8812            });
8813            return;
8814        }
8815        long ident = Binder.clearCallingIdentity();
8816        try {
8817            synchronized (this) {
8818                // Since we lost lock on task, make sure it is still there.
8819                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8820                if (task != null) {
8821                    if (!isSystemInitiated
8822                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8823                        throw new IllegalArgumentException("Invalid task, not in foreground");
8824                    }
8825                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8826                }
8827            }
8828        } finally {
8829            Binder.restoreCallingIdentity(ident);
8830        }
8831    }
8832
8833    @Override
8834    public void startLockTaskMode(int taskId) {
8835        final TaskRecord task;
8836        long ident = Binder.clearCallingIdentity();
8837        try {
8838            synchronized (this) {
8839                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8840            }
8841        } finally {
8842            Binder.restoreCallingIdentity(ident);
8843        }
8844        if (task != null) {
8845            startLockTaskMode(task);
8846        }
8847    }
8848
8849    @Override
8850    public void startLockTaskMode(IBinder token) {
8851        final TaskRecord task;
8852        long ident = Binder.clearCallingIdentity();
8853        try {
8854            synchronized (this) {
8855                final ActivityRecord r = ActivityRecord.forToken(token);
8856                if (r == null) {
8857                    return;
8858                }
8859                task = r.task;
8860            }
8861        } finally {
8862            Binder.restoreCallingIdentity(ident);
8863        }
8864        if (task != null) {
8865            startLockTaskMode(task);
8866        }
8867    }
8868
8869    @Override
8870    public void startLockTaskModeOnCurrent() throws RemoteException {
8871        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8872                "startLockTaskModeOnCurrent");
8873        ActivityRecord r = null;
8874        synchronized (this) {
8875            r = mStackSupervisor.topRunningActivityLocked();
8876        }
8877        startLockTaskMode(r.task);
8878    }
8879
8880    @Override
8881    public void stopLockTaskMode() {
8882        // Verify that the user matches the package of the intent for the TaskRecord
8883        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8884        // and stopLockTaskMode.
8885        final int callingUid = Binder.getCallingUid();
8886        if (callingUid != Process.SYSTEM_UID) {
8887            try {
8888                String pkg =
8889                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8890                int uid = mContext.getPackageManager().getPackageUid(pkg,
8891                        Binder.getCallingUserHandle().getIdentifier());
8892                if (uid != callingUid) {
8893                    throw new SecurityException("Invalid uid, expected " + uid);
8894                }
8895            } catch (NameNotFoundException e) {
8896                Log.d(TAG, "stopLockTaskMode " + e);
8897                return;
8898            }
8899        }
8900        long ident = Binder.clearCallingIdentity();
8901        try {
8902            Log.d(TAG, "stopLockTaskMode");
8903            // Stop lock task
8904            synchronized (this) {
8905                mStackSupervisor.setLockTaskModeLocked(null, false);
8906            }
8907        } finally {
8908            Binder.restoreCallingIdentity(ident);
8909        }
8910    }
8911
8912    @Override
8913    public void stopLockTaskModeOnCurrent() throws RemoteException {
8914        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8915                "stopLockTaskModeOnCurrent");
8916        long ident = Binder.clearCallingIdentity();
8917        try {
8918            stopLockTaskMode();
8919        } finally {
8920            Binder.restoreCallingIdentity(ident);
8921        }
8922    }
8923
8924    @Override
8925    public boolean isInLockTaskMode() {
8926        synchronized (this) {
8927            return mStackSupervisor.isInLockTaskMode();
8928        }
8929    }
8930
8931    // =========================================================
8932    // CONTENT PROVIDERS
8933    // =========================================================
8934
8935    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8936        List<ProviderInfo> providers = null;
8937        try {
8938            providers = AppGlobals.getPackageManager().
8939                queryContentProviders(app.processName, app.uid,
8940                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8941        } catch (RemoteException ex) {
8942        }
8943        if (DEBUG_MU)
8944            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8945        int userId = app.userId;
8946        if (providers != null) {
8947            int N = providers.size();
8948            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8949            for (int i=0; i<N; i++) {
8950                ProviderInfo cpi =
8951                    (ProviderInfo)providers.get(i);
8952                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8953                        cpi.name, cpi.flags);
8954                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8955                    // This is a singleton provider, but a user besides the
8956                    // default user is asking to initialize a process it runs
8957                    // in...  well, no, it doesn't actually run in this process,
8958                    // it runs in the process of the default user.  Get rid of it.
8959                    providers.remove(i);
8960                    N--;
8961                    i--;
8962                    continue;
8963                }
8964
8965                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8966                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8967                if (cpr == null) {
8968                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8969                    mProviderMap.putProviderByClass(comp, cpr);
8970                }
8971                if (DEBUG_MU)
8972                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8973                app.pubProviders.put(cpi.name, cpr);
8974                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8975                    // Don't add this if it is a platform component that is marked
8976                    // to run in multiple processes, because this is actually
8977                    // part of the framework so doesn't make sense to track as a
8978                    // separate apk in the process.
8979                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8980                            mProcessStats);
8981                }
8982                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8983            }
8984        }
8985        return providers;
8986    }
8987
8988    /**
8989     * Check if {@link ProcessRecord} has a possible chance at accessing the
8990     * given {@link ProviderInfo}. Final permission checking is always done
8991     * in {@link ContentProvider}.
8992     */
8993    private final String checkContentProviderPermissionLocked(
8994            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8995        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8996        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8997        boolean checkedGrants = false;
8998        if (checkUser) {
8999            // Looking for cross-user grants before enforcing the typical cross-users permissions
9000            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9001            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9002                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9003                    return null;
9004                }
9005                checkedGrants = true;
9006            }
9007            userId = handleIncomingUser(callingPid, callingUid, userId,
9008                    false, ALLOW_NON_FULL,
9009                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9010            if (userId != tmpTargetUserId) {
9011                // When we actually went to determine the final targer user ID, this ended
9012                // up different than our initial check for the authority.  This is because
9013                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9014                // SELF.  So we need to re-check the grants again.
9015                checkedGrants = false;
9016            }
9017        }
9018        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9019                cpi.applicationInfo.uid, cpi.exported)
9020                == PackageManager.PERMISSION_GRANTED) {
9021            return null;
9022        }
9023        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9024                cpi.applicationInfo.uid, cpi.exported)
9025                == PackageManager.PERMISSION_GRANTED) {
9026            return null;
9027        }
9028
9029        PathPermission[] pps = cpi.pathPermissions;
9030        if (pps != null) {
9031            int i = pps.length;
9032            while (i > 0) {
9033                i--;
9034                PathPermission pp = pps[i];
9035                String pprperm = pp.getReadPermission();
9036                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9037                        cpi.applicationInfo.uid, cpi.exported)
9038                        == PackageManager.PERMISSION_GRANTED) {
9039                    return null;
9040                }
9041                String ppwperm = pp.getWritePermission();
9042                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9043                        cpi.applicationInfo.uid, cpi.exported)
9044                        == PackageManager.PERMISSION_GRANTED) {
9045                    return null;
9046                }
9047            }
9048        }
9049        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9050            return null;
9051        }
9052
9053        String msg;
9054        if (!cpi.exported) {
9055            msg = "Permission Denial: opening provider " + cpi.name
9056                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9057                    + ", uid=" + callingUid + ") that is not exported from uid "
9058                    + cpi.applicationInfo.uid;
9059        } else {
9060            msg = "Permission Denial: opening provider " + cpi.name
9061                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9062                    + ", uid=" + callingUid + ") requires "
9063                    + cpi.readPermission + " or " + cpi.writePermission;
9064        }
9065        Slog.w(TAG, msg);
9066        return msg;
9067    }
9068
9069    /**
9070     * Returns if the ContentProvider has granted a uri to callingUid
9071     */
9072    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9073        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9074        if (perms != null) {
9075            for (int i=perms.size()-1; i>=0; i--) {
9076                GrantUri grantUri = perms.keyAt(i);
9077                if (grantUri.sourceUserId == userId || !checkUser) {
9078                    if (matchesProvider(grantUri.uri, cpi)) {
9079                        return true;
9080                    }
9081                }
9082            }
9083        }
9084        return false;
9085    }
9086
9087    /**
9088     * Returns true if the uri authority is one of the authorities specified in the provider.
9089     */
9090    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9091        String uriAuth = uri.getAuthority();
9092        String cpiAuth = cpi.authority;
9093        if (cpiAuth.indexOf(';') == -1) {
9094            return cpiAuth.equals(uriAuth);
9095        }
9096        String[] cpiAuths = cpiAuth.split(";");
9097        int length = cpiAuths.length;
9098        for (int i = 0; i < length; i++) {
9099            if (cpiAuths[i].equals(uriAuth)) return true;
9100        }
9101        return false;
9102    }
9103
9104    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9105            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9106        if (r != null) {
9107            for (int i=0; i<r.conProviders.size(); i++) {
9108                ContentProviderConnection conn = r.conProviders.get(i);
9109                if (conn.provider == cpr) {
9110                    if (DEBUG_PROVIDER) Slog.v(TAG,
9111                            "Adding provider requested by "
9112                            + r.processName + " from process "
9113                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9114                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9115                    if (stable) {
9116                        conn.stableCount++;
9117                        conn.numStableIncs++;
9118                    } else {
9119                        conn.unstableCount++;
9120                        conn.numUnstableIncs++;
9121                    }
9122                    return conn;
9123                }
9124            }
9125            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9126            if (stable) {
9127                conn.stableCount = 1;
9128                conn.numStableIncs = 1;
9129            } else {
9130                conn.unstableCount = 1;
9131                conn.numUnstableIncs = 1;
9132            }
9133            cpr.connections.add(conn);
9134            r.conProviders.add(conn);
9135            return conn;
9136        }
9137        cpr.addExternalProcessHandleLocked(externalProcessToken);
9138        return null;
9139    }
9140
9141    boolean decProviderCountLocked(ContentProviderConnection conn,
9142            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9143        if (conn != null) {
9144            cpr = conn.provider;
9145            if (DEBUG_PROVIDER) Slog.v(TAG,
9146                    "Removing provider requested by "
9147                    + conn.client.processName + " from process "
9148                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9149                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9150            if (stable) {
9151                conn.stableCount--;
9152            } else {
9153                conn.unstableCount--;
9154            }
9155            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9156                cpr.connections.remove(conn);
9157                conn.client.conProviders.remove(conn);
9158                return true;
9159            }
9160            return false;
9161        }
9162        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9163        return false;
9164    }
9165
9166    private void checkTime(long startTime, String where) {
9167        long now = SystemClock.elapsedRealtime();
9168        if ((now-startTime) > 1000) {
9169            // If we are taking more than a second, log about it.
9170            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9171        }
9172    }
9173
9174    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9175            String name, IBinder token, boolean stable, int userId) {
9176        ContentProviderRecord cpr;
9177        ContentProviderConnection conn = null;
9178        ProviderInfo cpi = null;
9179
9180        synchronized(this) {
9181            long startTime = SystemClock.elapsedRealtime();
9182
9183            ProcessRecord r = null;
9184            if (caller != null) {
9185                r = getRecordForAppLocked(caller);
9186                if (r == null) {
9187                    throw new SecurityException(
9188                            "Unable to find app for caller " + caller
9189                          + " (pid=" + Binder.getCallingPid()
9190                          + ") when getting content provider " + name);
9191                }
9192            }
9193
9194            boolean checkCrossUser = true;
9195
9196            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9197
9198            // First check if this content provider has been published...
9199            cpr = mProviderMap.getProviderByName(name, userId);
9200            // If that didn't work, check if it exists for user 0 and then
9201            // verify that it's a singleton provider before using it.
9202            if (cpr == null && userId != UserHandle.USER_OWNER) {
9203                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9204                if (cpr != null) {
9205                    cpi = cpr.info;
9206                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9207                            cpi.name, cpi.flags)
9208                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9209                        userId = UserHandle.USER_OWNER;
9210                        checkCrossUser = false;
9211                    } else {
9212                        cpr = null;
9213                        cpi = null;
9214                    }
9215                }
9216            }
9217
9218            boolean providerRunning = cpr != null;
9219            if (providerRunning) {
9220                cpi = cpr.info;
9221                String msg;
9222                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9223                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9224                        != null) {
9225                    throw new SecurityException(msg);
9226                }
9227                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9228
9229                if (r != null && cpr.canRunHere(r)) {
9230                    // This provider has been published or is in the process
9231                    // of being published...  but it is also allowed to run
9232                    // in the caller's process, so don't make a connection
9233                    // and just let the caller instantiate its own instance.
9234                    ContentProviderHolder holder = cpr.newHolder(null);
9235                    // don't give caller the provider object, it needs
9236                    // to make its own.
9237                    holder.provider = null;
9238                    return holder;
9239                }
9240
9241                final long origId = Binder.clearCallingIdentity();
9242
9243                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9244
9245                // In this case the provider instance already exists, so we can
9246                // return it right away.
9247                conn = incProviderCountLocked(r, cpr, token, stable);
9248                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9249                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9250                        // If this is a perceptible app accessing the provider,
9251                        // make sure to count it as being accessed and thus
9252                        // back up on the LRU list.  This is good because
9253                        // content providers are often expensive to start.
9254                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9255                        updateLruProcessLocked(cpr.proc, false, null);
9256                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9257                    }
9258                }
9259
9260                if (cpr.proc != null) {
9261                    if (false) {
9262                        if (cpr.name.flattenToShortString().equals(
9263                                "com.android.providers.calendar/.CalendarProvider2")) {
9264                            Slog.v(TAG, "****************** KILLING "
9265                                + cpr.name.flattenToShortString());
9266                            Process.killProcess(cpr.proc.pid);
9267                        }
9268                    }
9269                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9270                    boolean success = updateOomAdjLocked(cpr.proc);
9271                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9272                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9273                    // NOTE: there is still a race here where a signal could be
9274                    // pending on the process even though we managed to update its
9275                    // adj level.  Not sure what to do about this, but at least
9276                    // the race is now smaller.
9277                    if (!success) {
9278                        // Uh oh...  it looks like the provider's process
9279                        // has been killed on us.  We need to wait for a new
9280                        // process to be started, and make sure its death
9281                        // doesn't kill our process.
9282                        Slog.i(TAG,
9283                                "Existing provider " + cpr.name.flattenToShortString()
9284                                + " is crashing; detaching " + r);
9285                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9286                        checkTime(startTime, "getContentProviderImpl: before appDied");
9287                        appDiedLocked(cpr.proc);
9288                        checkTime(startTime, "getContentProviderImpl: after appDied");
9289                        if (!lastRef) {
9290                            // This wasn't the last ref our process had on
9291                            // the provider...  we have now been killed, bail.
9292                            return null;
9293                        }
9294                        providerRunning = false;
9295                        conn = null;
9296                    }
9297                }
9298
9299                Binder.restoreCallingIdentity(origId);
9300            }
9301
9302            boolean singleton;
9303            if (!providerRunning) {
9304                try {
9305                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9306                    cpi = AppGlobals.getPackageManager().
9307                        resolveContentProvider(name,
9308                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9309                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9310                } catch (RemoteException ex) {
9311                }
9312                if (cpi == null) {
9313                    return null;
9314                }
9315                // If the provider is a singleton AND
9316                // (it's a call within the same user || the provider is a
9317                // privileged app)
9318                // Then allow connecting to the singleton provider
9319                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9320                        cpi.name, cpi.flags)
9321                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9322                if (singleton) {
9323                    userId = UserHandle.USER_OWNER;
9324                }
9325                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9326                checkTime(startTime, "getContentProviderImpl: got app info for user");
9327
9328                String msg;
9329                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9330                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9331                        != null) {
9332                    throw new SecurityException(msg);
9333                }
9334                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9335
9336                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9337                        && !cpi.processName.equals("system")) {
9338                    // If this content provider does not run in the system
9339                    // process, and the system is not yet ready to run other
9340                    // processes, then fail fast instead of hanging.
9341                    throw new IllegalArgumentException(
9342                            "Attempt to launch content provider before system ready");
9343                }
9344
9345                // Make sure that the user who owns this provider is started.  If not,
9346                // we don't want to allow it to run.
9347                if (mStartedUsers.get(userId) == null) {
9348                    Slog.w(TAG, "Unable to launch app "
9349                            + cpi.applicationInfo.packageName + "/"
9350                            + cpi.applicationInfo.uid + " for provider "
9351                            + name + ": user " + userId + " is stopped");
9352                    return null;
9353                }
9354
9355                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9356                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9357                cpr = mProviderMap.getProviderByClass(comp, userId);
9358                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9359                final boolean firstClass = cpr == null;
9360                if (firstClass) {
9361                    final long ident = Binder.clearCallingIdentity();
9362                    try {
9363                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9364                        ApplicationInfo ai =
9365                            AppGlobals.getPackageManager().
9366                                getApplicationInfo(
9367                                        cpi.applicationInfo.packageName,
9368                                        STOCK_PM_FLAGS, userId);
9369                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9370                        if (ai == null) {
9371                            Slog.w(TAG, "No package info for content provider "
9372                                    + cpi.name);
9373                            return null;
9374                        }
9375                        ai = getAppInfoForUser(ai, userId);
9376                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9377                    } catch (RemoteException ex) {
9378                        // pm is in same process, this will never happen.
9379                    } finally {
9380                        Binder.restoreCallingIdentity(ident);
9381                    }
9382                }
9383
9384                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9385
9386                if (r != null && cpr.canRunHere(r)) {
9387                    // If this is a multiprocess provider, then just return its
9388                    // info and allow the caller to instantiate it.  Only do
9389                    // this if the provider is the same user as the caller's
9390                    // process, or can run as root (so can be in any process).
9391                    return cpr.newHolder(null);
9392                }
9393
9394                if (DEBUG_PROVIDER) {
9395                    RuntimeException e = new RuntimeException("here");
9396                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9397                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9398                }
9399
9400                // This is single process, and our app is now connecting to it.
9401                // See if we are already in the process of launching this
9402                // provider.
9403                final int N = mLaunchingProviders.size();
9404                int i;
9405                for (i=0; i<N; i++) {
9406                    if (mLaunchingProviders.get(i) == cpr) {
9407                        break;
9408                    }
9409                }
9410
9411                // If the provider is not already being launched, then get it
9412                // started.
9413                if (i >= N) {
9414                    final long origId = Binder.clearCallingIdentity();
9415
9416                    try {
9417                        // Content provider is now in use, its package can't be stopped.
9418                        try {
9419                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9420                            AppGlobals.getPackageManager().setPackageStoppedState(
9421                                    cpr.appInfo.packageName, false, userId);
9422                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9423                        } catch (RemoteException e) {
9424                        } catch (IllegalArgumentException e) {
9425                            Slog.w(TAG, "Failed trying to unstop package "
9426                                    + cpr.appInfo.packageName + ": " + e);
9427                        }
9428
9429                        // Use existing process if already started
9430                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9431                        ProcessRecord proc = getProcessRecordLocked(
9432                                cpi.processName, cpr.appInfo.uid, false);
9433                        if (proc != null && proc.thread != null) {
9434                            if (DEBUG_PROVIDER) {
9435                                Slog.d(TAG, "Installing in existing process " + proc);
9436                            }
9437                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9438                            proc.pubProviders.put(cpi.name, cpr);
9439                            try {
9440                                proc.thread.scheduleInstallProvider(cpi);
9441                            } catch (RemoteException e) {
9442                            }
9443                        } else {
9444                            checkTime(startTime, "getContentProviderImpl: before start process");
9445                            proc = startProcessLocked(cpi.processName,
9446                                    cpr.appInfo, false, 0, "content provider",
9447                                    new ComponentName(cpi.applicationInfo.packageName,
9448                                            cpi.name), false, false, false);
9449                            checkTime(startTime, "getContentProviderImpl: after start process");
9450                            if (proc == null) {
9451                                Slog.w(TAG, "Unable to launch app "
9452                                        + cpi.applicationInfo.packageName + "/"
9453                                        + cpi.applicationInfo.uid + " for provider "
9454                                        + name + ": process is bad");
9455                                return null;
9456                            }
9457                        }
9458                        cpr.launchingApp = proc;
9459                        mLaunchingProviders.add(cpr);
9460                    } finally {
9461                        Binder.restoreCallingIdentity(origId);
9462                    }
9463                }
9464
9465                checkTime(startTime, "getContentProviderImpl: updating data structures");
9466
9467                // Make sure the provider is published (the same provider class
9468                // may be published under multiple names).
9469                if (firstClass) {
9470                    mProviderMap.putProviderByClass(comp, cpr);
9471                }
9472
9473                mProviderMap.putProviderByName(name, cpr);
9474                conn = incProviderCountLocked(r, cpr, token, stable);
9475                if (conn != null) {
9476                    conn.waiting = true;
9477                }
9478            }
9479            checkTime(startTime, "getContentProviderImpl: done!");
9480        }
9481
9482        // Wait for the provider to be published...
9483        synchronized (cpr) {
9484            while (cpr.provider == null) {
9485                if (cpr.launchingApp == null) {
9486                    Slog.w(TAG, "Unable to launch app "
9487                            + cpi.applicationInfo.packageName + "/"
9488                            + cpi.applicationInfo.uid + " for provider "
9489                            + name + ": launching app became null");
9490                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9491                            UserHandle.getUserId(cpi.applicationInfo.uid),
9492                            cpi.applicationInfo.packageName,
9493                            cpi.applicationInfo.uid, name);
9494                    return null;
9495                }
9496                try {
9497                    if (DEBUG_MU) {
9498                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9499                                + cpr.launchingApp);
9500                    }
9501                    if (conn != null) {
9502                        conn.waiting = true;
9503                    }
9504                    cpr.wait();
9505                } catch (InterruptedException ex) {
9506                } finally {
9507                    if (conn != null) {
9508                        conn.waiting = false;
9509                    }
9510                }
9511            }
9512        }
9513        return cpr != null ? cpr.newHolder(conn) : null;
9514    }
9515
9516    @Override
9517    public final ContentProviderHolder getContentProvider(
9518            IApplicationThread caller, String name, int userId, boolean stable) {
9519        enforceNotIsolatedCaller("getContentProvider");
9520        if (caller == null) {
9521            String msg = "null IApplicationThread when getting content provider "
9522                    + name;
9523            Slog.w(TAG, msg);
9524            throw new SecurityException(msg);
9525        }
9526        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9527        // with cross-user grant.
9528        return getContentProviderImpl(caller, name, null, stable, userId);
9529    }
9530
9531    public ContentProviderHolder getContentProviderExternal(
9532            String name, int userId, IBinder token) {
9533        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9534            "Do not have permission in call getContentProviderExternal()");
9535        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9536                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9537        return getContentProviderExternalUnchecked(name, token, userId);
9538    }
9539
9540    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9541            IBinder token, int userId) {
9542        return getContentProviderImpl(null, name, token, true, userId);
9543    }
9544
9545    /**
9546     * Drop a content provider from a ProcessRecord's bookkeeping
9547     */
9548    public void removeContentProvider(IBinder connection, boolean stable) {
9549        enforceNotIsolatedCaller("removeContentProvider");
9550        long ident = Binder.clearCallingIdentity();
9551        try {
9552            synchronized (this) {
9553                ContentProviderConnection conn;
9554                try {
9555                    conn = (ContentProviderConnection)connection;
9556                } catch (ClassCastException e) {
9557                    String msg ="removeContentProvider: " + connection
9558                            + " not a ContentProviderConnection";
9559                    Slog.w(TAG, msg);
9560                    throw new IllegalArgumentException(msg);
9561                }
9562                if (conn == null) {
9563                    throw new NullPointerException("connection is null");
9564                }
9565                if (decProviderCountLocked(conn, null, null, stable)) {
9566                    updateOomAdjLocked();
9567                }
9568            }
9569        } finally {
9570            Binder.restoreCallingIdentity(ident);
9571        }
9572    }
9573
9574    public void removeContentProviderExternal(String name, IBinder token) {
9575        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9576            "Do not have permission in call removeContentProviderExternal()");
9577        int userId = UserHandle.getCallingUserId();
9578        long ident = Binder.clearCallingIdentity();
9579        try {
9580            removeContentProviderExternalUnchecked(name, token, userId);
9581        } finally {
9582            Binder.restoreCallingIdentity(ident);
9583        }
9584    }
9585
9586    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9587        synchronized (this) {
9588            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9589            if(cpr == null) {
9590                //remove from mProvidersByClass
9591                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9592                return;
9593            }
9594
9595            //update content provider record entry info
9596            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9597            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9598            if (localCpr.hasExternalProcessHandles()) {
9599                if (localCpr.removeExternalProcessHandleLocked(token)) {
9600                    updateOomAdjLocked();
9601                } else {
9602                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9603                            + " with no external reference for token: "
9604                            + token + ".");
9605                }
9606            } else {
9607                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9608                        + " with no external references.");
9609            }
9610        }
9611    }
9612
9613    public final void publishContentProviders(IApplicationThread caller,
9614            List<ContentProviderHolder> providers) {
9615        if (providers == null) {
9616            return;
9617        }
9618
9619        enforceNotIsolatedCaller("publishContentProviders");
9620        synchronized (this) {
9621            final ProcessRecord r = getRecordForAppLocked(caller);
9622            if (DEBUG_MU)
9623                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9624            if (r == null) {
9625                throw new SecurityException(
9626                        "Unable to find app for caller " + caller
9627                      + " (pid=" + Binder.getCallingPid()
9628                      + ") when publishing content providers");
9629            }
9630
9631            final long origId = Binder.clearCallingIdentity();
9632
9633            final int N = providers.size();
9634            for (int i=0; i<N; i++) {
9635                ContentProviderHolder src = providers.get(i);
9636                if (src == null || src.info == null || src.provider == null) {
9637                    continue;
9638                }
9639                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9640                if (DEBUG_MU)
9641                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9642                if (dst != null) {
9643                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9644                    mProviderMap.putProviderByClass(comp, dst);
9645                    String names[] = dst.info.authority.split(";");
9646                    for (int j = 0; j < names.length; j++) {
9647                        mProviderMap.putProviderByName(names[j], dst);
9648                    }
9649
9650                    int NL = mLaunchingProviders.size();
9651                    int j;
9652                    for (j=0; j<NL; j++) {
9653                        if (mLaunchingProviders.get(j) == dst) {
9654                            mLaunchingProviders.remove(j);
9655                            j--;
9656                            NL--;
9657                        }
9658                    }
9659                    synchronized (dst) {
9660                        dst.provider = src.provider;
9661                        dst.proc = r;
9662                        dst.notifyAll();
9663                    }
9664                    updateOomAdjLocked(r);
9665                }
9666            }
9667
9668            Binder.restoreCallingIdentity(origId);
9669        }
9670    }
9671
9672    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9673        ContentProviderConnection conn;
9674        try {
9675            conn = (ContentProviderConnection)connection;
9676        } catch (ClassCastException e) {
9677            String msg ="refContentProvider: " + connection
9678                    + " not a ContentProviderConnection";
9679            Slog.w(TAG, msg);
9680            throw new IllegalArgumentException(msg);
9681        }
9682        if (conn == null) {
9683            throw new NullPointerException("connection is null");
9684        }
9685
9686        synchronized (this) {
9687            if (stable > 0) {
9688                conn.numStableIncs += stable;
9689            }
9690            stable = conn.stableCount + stable;
9691            if (stable < 0) {
9692                throw new IllegalStateException("stableCount < 0: " + stable);
9693            }
9694
9695            if (unstable > 0) {
9696                conn.numUnstableIncs += unstable;
9697            }
9698            unstable = conn.unstableCount + unstable;
9699            if (unstable < 0) {
9700                throw new IllegalStateException("unstableCount < 0: " + unstable);
9701            }
9702
9703            if ((stable+unstable) <= 0) {
9704                throw new IllegalStateException("ref counts can't go to zero here: stable="
9705                        + stable + " unstable=" + unstable);
9706            }
9707            conn.stableCount = stable;
9708            conn.unstableCount = unstable;
9709            return !conn.dead;
9710        }
9711    }
9712
9713    public void unstableProviderDied(IBinder connection) {
9714        ContentProviderConnection conn;
9715        try {
9716            conn = (ContentProviderConnection)connection;
9717        } catch (ClassCastException e) {
9718            String msg ="refContentProvider: " + connection
9719                    + " not a ContentProviderConnection";
9720            Slog.w(TAG, msg);
9721            throw new IllegalArgumentException(msg);
9722        }
9723        if (conn == null) {
9724            throw new NullPointerException("connection is null");
9725        }
9726
9727        // Safely retrieve the content provider associated with the connection.
9728        IContentProvider provider;
9729        synchronized (this) {
9730            provider = conn.provider.provider;
9731        }
9732
9733        if (provider == null) {
9734            // Um, yeah, we're way ahead of you.
9735            return;
9736        }
9737
9738        // Make sure the caller is being honest with us.
9739        if (provider.asBinder().pingBinder()) {
9740            // Er, no, still looks good to us.
9741            synchronized (this) {
9742                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9743                        + " says " + conn + " died, but we don't agree");
9744                return;
9745            }
9746        }
9747
9748        // Well look at that!  It's dead!
9749        synchronized (this) {
9750            if (conn.provider.provider != provider) {
9751                // But something changed...  good enough.
9752                return;
9753            }
9754
9755            ProcessRecord proc = conn.provider.proc;
9756            if (proc == null || proc.thread == null) {
9757                // Seems like the process is already cleaned up.
9758                return;
9759            }
9760
9761            // As far as we're concerned, this is just like receiving a
9762            // death notification...  just a bit prematurely.
9763            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9764                    + ") early provider death");
9765            final long ident = Binder.clearCallingIdentity();
9766            try {
9767                appDiedLocked(proc);
9768            } finally {
9769                Binder.restoreCallingIdentity(ident);
9770            }
9771        }
9772    }
9773
9774    @Override
9775    public void appNotRespondingViaProvider(IBinder connection) {
9776        enforceCallingPermission(
9777                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9778
9779        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9780        if (conn == null) {
9781            Slog.w(TAG, "ContentProviderConnection is null");
9782            return;
9783        }
9784
9785        final ProcessRecord host = conn.provider.proc;
9786        if (host == null) {
9787            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9788            return;
9789        }
9790
9791        final long token = Binder.clearCallingIdentity();
9792        try {
9793            appNotResponding(host, null, null, false, "ContentProvider not responding");
9794        } finally {
9795            Binder.restoreCallingIdentity(token);
9796        }
9797    }
9798
9799    public final void installSystemProviders() {
9800        List<ProviderInfo> providers;
9801        synchronized (this) {
9802            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9803            providers = generateApplicationProvidersLocked(app);
9804            if (providers != null) {
9805                for (int i=providers.size()-1; i>=0; i--) {
9806                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9807                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9808                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9809                                + ": not system .apk");
9810                        providers.remove(i);
9811                    }
9812                }
9813            }
9814        }
9815        if (providers != null) {
9816            mSystemThread.installSystemProviders(providers);
9817        }
9818
9819        mCoreSettingsObserver = new CoreSettingsObserver(this);
9820
9821        //mUsageStatsService.monitorPackages();
9822    }
9823
9824    /**
9825     * Allows apps to retrieve the MIME type of a URI.
9826     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9827     * users, then it does not need permission to access the ContentProvider.
9828     * Either, it needs cross-user uri grants.
9829     *
9830     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9831     *
9832     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9833     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9834     */
9835    public String getProviderMimeType(Uri uri, int userId) {
9836        enforceNotIsolatedCaller("getProviderMimeType");
9837        final String name = uri.getAuthority();
9838        int callingUid = Binder.getCallingUid();
9839        int callingPid = Binder.getCallingPid();
9840        long ident = 0;
9841        boolean clearedIdentity = false;
9842        userId = unsafeConvertIncomingUser(userId);
9843        if (canClearIdentity(callingPid, callingUid, userId)) {
9844            clearedIdentity = true;
9845            ident = Binder.clearCallingIdentity();
9846        }
9847        ContentProviderHolder holder = null;
9848        try {
9849            holder = getContentProviderExternalUnchecked(name, null, userId);
9850            if (holder != null) {
9851                return holder.provider.getType(uri);
9852            }
9853        } catch (RemoteException e) {
9854            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9855            return null;
9856        } finally {
9857            // We need to clear the identity to call removeContentProviderExternalUnchecked
9858            if (!clearedIdentity) {
9859                ident = Binder.clearCallingIdentity();
9860            }
9861            try {
9862                if (holder != null) {
9863                    removeContentProviderExternalUnchecked(name, null, userId);
9864                }
9865            } finally {
9866                Binder.restoreCallingIdentity(ident);
9867            }
9868        }
9869
9870        return null;
9871    }
9872
9873    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9874        if (UserHandle.getUserId(callingUid) == userId) {
9875            return true;
9876        }
9877        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9878                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9879                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9880                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9881                return true;
9882        }
9883        return false;
9884    }
9885
9886    // =========================================================
9887    // GLOBAL MANAGEMENT
9888    // =========================================================
9889
9890    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9891            boolean isolated, int isolatedUid) {
9892        String proc = customProcess != null ? customProcess : info.processName;
9893        BatteryStatsImpl.Uid.Proc ps = null;
9894        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9895        int uid = info.uid;
9896        if (isolated) {
9897            if (isolatedUid == 0) {
9898                int userId = UserHandle.getUserId(uid);
9899                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9900                while (true) {
9901                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9902                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9903                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9904                    }
9905                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9906                    mNextIsolatedProcessUid++;
9907                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9908                        // No process for this uid, use it.
9909                        break;
9910                    }
9911                    stepsLeft--;
9912                    if (stepsLeft <= 0) {
9913                        return null;
9914                    }
9915                }
9916            } else {
9917                // Special case for startIsolatedProcess (internal only), where
9918                // the uid of the isolated process is specified by the caller.
9919                uid = isolatedUid;
9920            }
9921        }
9922        return new ProcessRecord(stats, info, proc, uid);
9923    }
9924
9925    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9926            String abiOverride) {
9927        ProcessRecord app;
9928        if (!isolated) {
9929            app = getProcessRecordLocked(info.processName, info.uid, true);
9930        } else {
9931            app = null;
9932        }
9933
9934        if (app == null) {
9935            app = newProcessRecordLocked(info, null, isolated, 0);
9936            mProcessNames.put(info.processName, app.uid, app);
9937            if (isolated) {
9938                mIsolatedProcesses.put(app.uid, app);
9939            }
9940            updateLruProcessLocked(app, false, null);
9941            updateOomAdjLocked();
9942        }
9943
9944        // This package really, really can not be stopped.
9945        try {
9946            AppGlobals.getPackageManager().setPackageStoppedState(
9947                    info.packageName, false, UserHandle.getUserId(app.uid));
9948        } catch (RemoteException e) {
9949        } catch (IllegalArgumentException e) {
9950            Slog.w(TAG, "Failed trying to unstop package "
9951                    + info.packageName + ": " + e);
9952        }
9953
9954        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9955                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9956            app.persistent = true;
9957            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9958        }
9959        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9960            mPersistentStartingProcesses.add(app);
9961            startProcessLocked(app, "added application", app.processName, abiOverride,
9962                    null /* entryPoint */, null /* entryPointArgs */);
9963        }
9964
9965        return app;
9966    }
9967
9968    public void unhandledBack() {
9969        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9970                "unhandledBack()");
9971
9972        synchronized(this) {
9973            final long origId = Binder.clearCallingIdentity();
9974            try {
9975                getFocusedStack().unhandledBackLocked();
9976            } finally {
9977                Binder.restoreCallingIdentity(origId);
9978            }
9979        }
9980    }
9981
9982    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9983        enforceNotIsolatedCaller("openContentUri");
9984        final int userId = UserHandle.getCallingUserId();
9985        String name = uri.getAuthority();
9986        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9987        ParcelFileDescriptor pfd = null;
9988        if (cph != null) {
9989            // We record the binder invoker's uid in thread-local storage before
9990            // going to the content provider to open the file.  Later, in the code
9991            // that handles all permissions checks, we look for this uid and use
9992            // that rather than the Activity Manager's own uid.  The effect is that
9993            // we do the check against the caller's permissions even though it looks
9994            // to the content provider like the Activity Manager itself is making
9995            // the request.
9996            sCallerIdentity.set(new Identity(
9997                    Binder.getCallingPid(), Binder.getCallingUid()));
9998            try {
9999                pfd = cph.provider.openFile(null, uri, "r", null);
10000            } catch (FileNotFoundException e) {
10001                // do nothing; pfd will be returned null
10002            } finally {
10003                // Ensure that whatever happens, we clean up the identity state
10004                sCallerIdentity.remove();
10005            }
10006
10007            // We've got the fd now, so we're done with the provider.
10008            removeContentProviderExternalUnchecked(name, null, userId);
10009        } else {
10010            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10011        }
10012        return pfd;
10013    }
10014
10015    // Actually is sleeping or shutting down or whatever else in the future
10016    // is an inactive state.
10017    public boolean isSleepingOrShuttingDown() {
10018        return isSleeping() || mShuttingDown;
10019    }
10020
10021    public boolean isSleeping() {
10022        return mSleeping;
10023    }
10024
10025    void goingToSleep() {
10026        synchronized(this) {
10027            mWentToSleep = true;
10028            goToSleepIfNeededLocked();
10029        }
10030    }
10031
10032    void finishRunningVoiceLocked() {
10033        if (mRunningVoice) {
10034            mRunningVoice = false;
10035            goToSleepIfNeededLocked();
10036        }
10037    }
10038
10039    void goToSleepIfNeededLocked() {
10040        if (mWentToSleep && !mRunningVoice) {
10041            if (!mSleeping) {
10042                mSleeping = true;
10043                mStackSupervisor.goingToSleepLocked();
10044
10045                // Initialize the wake times of all processes.
10046                checkExcessivePowerUsageLocked(false);
10047                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10048                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10049                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10050            }
10051        }
10052    }
10053
10054    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10055        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10056            // Never persist the home stack.
10057            return;
10058        }
10059        mTaskPersister.wakeup(task, flush);
10060    }
10061
10062    @Override
10063    public boolean shutdown(int timeout) {
10064        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10065                != PackageManager.PERMISSION_GRANTED) {
10066            throw new SecurityException("Requires permission "
10067                    + android.Manifest.permission.SHUTDOWN);
10068        }
10069
10070        boolean timedout = false;
10071
10072        synchronized(this) {
10073            mShuttingDown = true;
10074            updateEventDispatchingLocked();
10075            timedout = mStackSupervisor.shutdownLocked(timeout);
10076        }
10077
10078        mAppOpsService.shutdown();
10079        if (mUsageStatsService != null) {
10080            mUsageStatsService.prepareShutdown();
10081        }
10082        mBatteryStatsService.shutdown();
10083        synchronized (this) {
10084            mProcessStats.shutdownLocked();
10085        }
10086        notifyTaskPersisterLocked(null, true);
10087
10088        return timedout;
10089    }
10090
10091    public final void activitySlept(IBinder token) {
10092        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10093
10094        final long origId = Binder.clearCallingIdentity();
10095
10096        synchronized (this) {
10097            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10098            if (r != null) {
10099                mStackSupervisor.activitySleptLocked(r);
10100            }
10101        }
10102
10103        Binder.restoreCallingIdentity(origId);
10104    }
10105
10106    void logLockScreen(String msg) {
10107        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10108                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10109                mWentToSleep + " mSleeping=" + mSleeping);
10110    }
10111
10112    private void comeOutOfSleepIfNeededLocked() {
10113        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10114            if (mSleeping) {
10115                mSleeping = false;
10116                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10117            }
10118        }
10119    }
10120
10121    void wakingUp() {
10122        synchronized(this) {
10123            mWentToSleep = false;
10124            comeOutOfSleepIfNeededLocked();
10125        }
10126    }
10127
10128    void startRunningVoiceLocked() {
10129        if (!mRunningVoice) {
10130            mRunningVoice = true;
10131            comeOutOfSleepIfNeededLocked();
10132        }
10133    }
10134
10135    private void updateEventDispatchingLocked() {
10136        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10137    }
10138
10139    public void setLockScreenShown(boolean shown) {
10140        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10141                != PackageManager.PERMISSION_GRANTED) {
10142            throw new SecurityException("Requires permission "
10143                    + android.Manifest.permission.DEVICE_POWER);
10144        }
10145
10146        synchronized(this) {
10147            long ident = Binder.clearCallingIdentity();
10148            try {
10149                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10150                mLockScreenShown = shown;
10151                comeOutOfSleepIfNeededLocked();
10152            } finally {
10153                Binder.restoreCallingIdentity(ident);
10154            }
10155        }
10156    }
10157
10158    @Override
10159    public void stopAppSwitches() {
10160        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10161                != PackageManager.PERMISSION_GRANTED) {
10162            throw new SecurityException("Requires permission "
10163                    + android.Manifest.permission.STOP_APP_SWITCHES);
10164        }
10165
10166        synchronized(this) {
10167            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10168                    + APP_SWITCH_DELAY_TIME;
10169            mDidAppSwitch = false;
10170            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10171            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10172            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10173        }
10174    }
10175
10176    public void resumeAppSwitches() {
10177        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10178                != PackageManager.PERMISSION_GRANTED) {
10179            throw new SecurityException("Requires permission "
10180                    + android.Manifest.permission.STOP_APP_SWITCHES);
10181        }
10182
10183        synchronized(this) {
10184            // Note that we don't execute any pending app switches... we will
10185            // let those wait until either the timeout, or the next start
10186            // activity request.
10187            mAppSwitchesAllowedTime = 0;
10188        }
10189    }
10190
10191    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10192            int callingPid, int callingUid, String name) {
10193        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10194            return true;
10195        }
10196
10197        int perm = checkComponentPermission(
10198                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10199                sourceUid, -1, true);
10200        if (perm == PackageManager.PERMISSION_GRANTED) {
10201            return true;
10202        }
10203
10204        // If the actual IPC caller is different from the logical source, then
10205        // also see if they are allowed to control app switches.
10206        if (callingUid != -1 && callingUid != sourceUid) {
10207            perm = checkComponentPermission(
10208                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10209                    callingUid, -1, true);
10210            if (perm == PackageManager.PERMISSION_GRANTED) {
10211                return true;
10212            }
10213        }
10214
10215        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10216        return false;
10217    }
10218
10219    public void setDebugApp(String packageName, boolean waitForDebugger,
10220            boolean persistent) {
10221        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10222                "setDebugApp()");
10223
10224        long ident = Binder.clearCallingIdentity();
10225        try {
10226            // Note that this is not really thread safe if there are multiple
10227            // callers into it at the same time, but that's not a situation we
10228            // care about.
10229            if (persistent) {
10230                final ContentResolver resolver = mContext.getContentResolver();
10231                Settings.Global.putString(
10232                    resolver, Settings.Global.DEBUG_APP,
10233                    packageName);
10234                Settings.Global.putInt(
10235                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10236                    waitForDebugger ? 1 : 0);
10237            }
10238
10239            synchronized (this) {
10240                if (!persistent) {
10241                    mOrigDebugApp = mDebugApp;
10242                    mOrigWaitForDebugger = mWaitForDebugger;
10243                }
10244                mDebugApp = packageName;
10245                mWaitForDebugger = waitForDebugger;
10246                mDebugTransient = !persistent;
10247                if (packageName != null) {
10248                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10249                            false, UserHandle.USER_ALL, "set debug app");
10250                }
10251            }
10252        } finally {
10253            Binder.restoreCallingIdentity(ident);
10254        }
10255    }
10256
10257    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10258        synchronized (this) {
10259            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10260            if (!isDebuggable) {
10261                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10262                    throw new SecurityException("Process not debuggable: " + app.packageName);
10263                }
10264            }
10265
10266            mOpenGlTraceApp = processName;
10267        }
10268    }
10269
10270    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10271        synchronized (this) {
10272            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10273            if (!isDebuggable) {
10274                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10275                    throw new SecurityException("Process not debuggable: " + app.packageName);
10276                }
10277            }
10278            mProfileApp = processName;
10279            mProfileFile = profilerInfo.profileFile;
10280            if (mProfileFd != null) {
10281                try {
10282                    mProfileFd.close();
10283                } catch (IOException e) {
10284                }
10285                mProfileFd = null;
10286            }
10287            mProfileFd = profilerInfo.profileFd;
10288            mSamplingInterval = profilerInfo.samplingInterval;
10289            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10290            mProfileType = 0;
10291        }
10292    }
10293
10294    @Override
10295    public void setAlwaysFinish(boolean enabled) {
10296        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10297                "setAlwaysFinish()");
10298
10299        Settings.Global.putInt(
10300                mContext.getContentResolver(),
10301                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10302
10303        synchronized (this) {
10304            mAlwaysFinishActivities = enabled;
10305        }
10306    }
10307
10308    @Override
10309    public void setActivityController(IActivityController controller) {
10310        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10311                "setActivityController()");
10312        synchronized (this) {
10313            mController = controller;
10314            Watchdog.getInstance().setActivityController(controller);
10315        }
10316    }
10317
10318    @Override
10319    public void setUserIsMonkey(boolean userIsMonkey) {
10320        synchronized (this) {
10321            synchronized (mPidsSelfLocked) {
10322                final int callingPid = Binder.getCallingPid();
10323                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10324                if (precessRecord == null) {
10325                    throw new SecurityException("Unknown process: " + callingPid);
10326                }
10327                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10328                    throw new SecurityException("Only an instrumentation process "
10329                            + "with a UiAutomation can call setUserIsMonkey");
10330                }
10331            }
10332            mUserIsMonkey = userIsMonkey;
10333        }
10334    }
10335
10336    @Override
10337    public boolean isUserAMonkey() {
10338        synchronized (this) {
10339            // If there is a controller also implies the user is a monkey.
10340            return (mUserIsMonkey || mController != null);
10341        }
10342    }
10343
10344    public void requestBugReport() {
10345        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10346        SystemProperties.set("ctl.start", "bugreport");
10347    }
10348
10349    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10350        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10351    }
10352
10353    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10354        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10355            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10356        }
10357        return KEY_DISPATCHING_TIMEOUT;
10358    }
10359
10360    @Override
10361    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10362        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10363                != PackageManager.PERMISSION_GRANTED) {
10364            throw new SecurityException("Requires permission "
10365                    + android.Manifest.permission.FILTER_EVENTS);
10366        }
10367        ProcessRecord proc;
10368        long timeout;
10369        synchronized (this) {
10370            synchronized (mPidsSelfLocked) {
10371                proc = mPidsSelfLocked.get(pid);
10372            }
10373            timeout = getInputDispatchingTimeoutLocked(proc);
10374        }
10375
10376        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10377            return -1;
10378        }
10379
10380        return timeout;
10381    }
10382
10383    /**
10384     * Handle input dispatching timeouts.
10385     * Returns whether input dispatching should be aborted or not.
10386     */
10387    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10388            final ActivityRecord activity, final ActivityRecord parent,
10389            final boolean aboveSystem, String reason) {
10390        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10391                != PackageManager.PERMISSION_GRANTED) {
10392            throw new SecurityException("Requires permission "
10393                    + android.Manifest.permission.FILTER_EVENTS);
10394        }
10395
10396        final String annotation;
10397        if (reason == null) {
10398            annotation = "Input dispatching timed out";
10399        } else {
10400            annotation = "Input dispatching timed out (" + reason + ")";
10401        }
10402
10403        if (proc != null) {
10404            synchronized (this) {
10405                if (proc.debugging) {
10406                    return false;
10407                }
10408
10409                if (mDidDexOpt) {
10410                    // Give more time since we were dexopting.
10411                    mDidDexOpt = false;
10412                    return false;
10413                }
10414
10415                if (proc.instrumentationClass != null) {
10416                    Bundle info = new Bundle();
10417                    info.putString("shortMsg", "keyDispatchingTimedOut");
10418                    info.putString("longMsg", annotation);
10419                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10420                    return true;
10421                }
10422            }
10423            mHandler.post(new Runnable() {
10424                @Override
10425                public void run() {
10426                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10427                }
10428            });
10429        }
10430
10431        return true;
10432    }
10433
10434    public Bundle getAssistContextExtras(int requestType) {
10435        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10436                "getAssistContextExtras()");
10437        PendingAssistExtras pae;
10438        Bundle extras = new Bundle();
10439        synchronized (this) {
10440            ActivityRecord activity = getFocusedStack().mResumedActivity;
10441            if (activity == null) {
10442                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10443                return null;
10444            }
10445            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10446            if (activity.app == null || activity.app.thread == null) {
10447                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10448                return extras;
10449            }
10450            if (activity.app.pid == Binder.getCallingPid()) {
10451                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10452                return extras;
10453            }
10454            pae = new PendingAssistExtras(activity);
10455            try {
10456                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10457                        requestType);
10458                mPendingAssistExtras.add(pae);
10459                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10460            } catch (RemoteException e) {
10461                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10462                return extras;
10463            }
10464        }
10465        synchronized (pae) {
10466            while (!pae.haveResult) {
10467                try {
10468                    pae.wait();
10469                } catch (InterruptedException e) {
10470                }
10471            }
10472            if (pae.result != null) {
10473                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10474            }
10475        }
10476        synchronized (this) {
10477            mPendingAssistExtras.remove(pae);
10478            mHandler.removeCallbacks(pae);
10479        }
10480        return extras;
10481    }
10482
10483    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10484        PendingAssistExtras pae = (PendingAssistExtras)token;
10485        synchronized (pae) {
10486            pae.result = extras;
10487            pae.haveResult = true;
10488            pae.notifyAll();
10489        }
10490    }
10491
10492    public void registerProcessObserver(IProcessObserver observer) {
10493        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10494                "registerProcessObserver()");
10495        synchronized (this) {
10496            mProcessObservers.register(observer);
10497        }
10498    }
10499
10500    @Override
10501    public void unregisterProcessObserver(IProcessObserver observer) {
10502        synchronized (this) {
10503            mProcessObservers.unregister(observer);
10504        }
10505    }
10506
10507    @Override
10508    public boolean convertFromTranslucent(IBinder token) {
10509        final long origId = Binder.clearCallingIdentity();
10510        try {
10511            synchronized (this) {
10512                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10513                if (r == null) {
10514                    return false;
10515                }
10516                final boolean translucentChanged = r.changeWindowTranslucency(true);
10517                if (translucentChanged) {
10518                    r.task.stack.releaseBackgroundResources();
10519                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10520                }
10521                mWindowManager.setAppFullscreen(token, true);
10522                return translucentChanged;
10523            }
10524        } finally {
10525            Binder.restoreCallingIdentity(origId);
10526        }
10527    }
10528
10529    @Override
10530    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10531        final long origId = Binder.clearCallingIdentity();
10532        try {
10533            synchronized (this) {
10534                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10535                if (r == null) {
10536                    return false;
10537                }
10538                int index = r.task.mActivities.lastIndexOf(r);
10539                if (index > 0) {
10540                    ActivityRecord under = r.task.mActivities.get(index - 1);
10541                    under.returningOptions = options;
10542                }
10543                final boolean translucentChanged = r.changeWindowTranslucency(false);
10544                if (translucentChanged) {
10545                    r.task.stack.convertToTranslucent(r);
10546                }
10547                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10548                mWindowManager.setAppFullscreen(token, false);
10549                return translucentChanged;
10550            }
10551        } finally {
10552            Binder.restoreCallingIdentity(origId);
10553        }
10554    }
10555
10556    @Override
10557    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10558        final long origId = Binder.clearCallingIdentity();
10559        try {
10560            synchronized (this) {
10561                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10562                if (r != null) {
10563                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10564                }
10565            }
10566            return false;
10567        } finally {
10568            Binder.restoreCallingIdentity(origId);
10569        }
10570    }
10571
10572    @Override
10573    public boolean isBackgroundVisibleBehind(IBinder token) {
10574        final long origId = Binder.clearCallingIdentity();
10575        try {
10576            synchronized (this) {
10577                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10578                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10579                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10580                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10581                return visible;
10582            }
10583        } finally {
10584            Binder.restoreCallingIdentity(origId);
10585        }
10586    }
10587
10588    @Override
10589    public ActivityOptions getActivityOptions(IBinder token) {
10590        final long origId = Binder.clearCallingIdentity();
10591        try {
10592            synchronized (this) {
10593                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10594                if (r != null) {
10595                    final ActivityOptions activityOptions = r.pendingOptions;
10596                    r.pendingOptions = null;
10597                    return activityOptions;
10598                }
10599                return null;
10600            }
10601        } finally {
10602            Binder.restoreCallingIdentity(origId);
10603        }
10604    }
10605
10606    @Override
10607    public void setImmersive(IBinder token, boolean immersive) {
10608        synchronized(this) {
10609            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10610            if (r == null) {
10611                throw new IllegalArgumentException();
10612            }
10613            r.immersive = immersive;
10614
10615            // update associated state if we're frontmost
10616            if (r == mFocusedActivity) {
10617                if (DEBUG_IMMERSIVE) {
10618                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10619                }
10620                applyUpdateLockStateLocked(r);
10621            }
10622        }
10623    }
10624
10625    @Override
10626    public boolean isImmersive(IBinder token) {
10627        synchronized (this) {
10628            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10629            if (r == null) {
10630                throw new IllegalArgumentException();
10631            }
10632            return r.immersive;
10633        }
10634    }
10635
10636    public boolean isTopActivityImmersive() {
10637        enforceNotIsolatedCaller("startActivity");
10638        synchronized (this) {
10639            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10640            return (r != null) ? r.immersive : false;
10641        }
10642    }
10643
10644    @Override
10645    public boolean isTopOfTask(IBinder token) {
10646        synchronized (this) {
10647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10648            if (r == null) {
10649                throw new IllegalArgumentException();
10650            }
10651            return r.task.getTopActivity() == r;
10652        }
10653    }
10654
10655    public final void enterSafeMode() {
10656        synchronized(this) {
10657            // It only makes sense to do this before the system is ready
10658            // and started launching other packages.
10659            if (!mSystemReady) {
10660                try {
10661                    AppGlobals.getPackageManager().enterSafeMode();
10662                } catch (RemoteException e) {
10663                }
10664            }
10665
10666            mSafeMode = true;
10667        }
10668    }
10669
10670    public final void showSafeModeOverlay() {
10671        View v = LayoutInflater.from(mContext).inflate(
10672                com.android.internal.R.layout.safe_mode, null);
10673        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10674        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10675        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10676        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10677        lp.gravity = Gravity.BOTTOM | Gravity.START;
10678        lp.format = v.getBackground().getOpacity();
10679        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10680                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10681        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10682        ((WindowManager)mContext.getSystemService(
10683                Context.WINDOW_SERVICE)).addView(v, lp);
10684    }
10685
10686    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10687        if (!(sender instanceof PendingIntentRecord)) {
10688            return;
10689        }
10690        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10691        synchronized (stats) {
10692            if (mBatteryStatsService.isOnBattery()) {
10693                mBatteryStatsService.enforceCallingPermission();
10694                PendingIntentRecord rec = (PendingIntentRecord)sender;
10695                int MY_UID = Binder.getCallingUid();
10696                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10697                BatteryStatsImpl.Uid.Pkg pkg =
10698                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10699                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10700                pkg.incWakeupsLocked();
10701            }
10702        }
10703    }
10704
10705    public boolean killPids(int[] pids, String pReason, boolean secure) {
10706        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10707            throw new SecurityException("killPids only available to the system");
10708        }
10709        String reason = (pReason == null) ? "Unknown" : pReason;
10710        // XXX Note: don't acquire main activity lock here, because the window
10711        // manager calls in with its locks held.
10712
10713        boolean killed = false;
10714        synchronized (mPidsSelfLocked) {
10715            int[] types = new int[pids.length];
10716            int worstType = 0;
10717            for (int i=0; i<pids.length; i++) {
10718                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10719                if (proc != null) {
10720                    int type = proc.setAdj;
10721                    types[i] = type;
10722                    if (type > worstType) {
10723                        worstType = type;
10724                    }
10725                }
10726            }
10727
10728            // If the worst oom_adj is somewhere in the cached proc LRU range,
10729            // then constrain it so we will kill all cached procs.
10730            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10731                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10732                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10733            }
10734
10735            // If this is not a secure call, don't let it kill processes that
10736            // are important.
10737            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10738                worstType = ProcessList.SERVICE_ADJ;
10739            }
10740
10741            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10742            for (int i=0; i<pids.length; i++) {
10743                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10744                if (proc == null) {
10745                    continue;
10746                }
10747                int adj = proc.setAdj;
10748                if (adj >= worstType && !proc.killedByAm) {
10749                    proc.kill(reason, true);
10750                    killed = true;
10751                }
10752            }
10753        }
10754        return killed;
10755    }
10756
10757    @Override
10758    public void killUid(int uid, String reason) {
10759        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10760            throw new SecurityException("killUid only available to the system");
10761        }
10762        synchronized (this) {
10763            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10764                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10765                    reason != null ? reason : "kill uid");
10766        }
10767    }
10768
10769    @Override
10770    public boolean killProcessesBelowForeground(String reason) {
10771        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10772            throw new SecurityException("killProcessesBelowForeground() only available to system");
10773        }
10774
10775        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10776    }
10777
10778    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10779        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10780            throw new SecurityException("killProcessesBelowAdj() only available to system");
10781        }
10782
10783        boolean killed = false;
10784        synchronized (mPidsSelfLocked) {
10785            final int size = mPidsSelfLocked.size();
10786            for (int i = 0; i < size; i++) {
10787                final int pid = mPidsSelfLocked.keyAt(i);
10788                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10789                if (proc == null) continue;
10790
10791                final int adj = proc.setAdj;
10792                if (adj > belowAdj && !proc.killedByAm) {
10793                    proc.kill(reason, true);
10794                    killed = true;
10795                }
10796            }
10797        }
10798        return killed;
10799    }
10800
10801    @Override
10802    public void hang(final IBinder who, boolean allowRestart) {
10803        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10804                != PackageManager.PERMISSION_GRANTED) {
10805            throw new SecurityException("Requires permission "
10806                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10807        }
10808
10809        final IBinder.DeathRecipient death = new DeathRecipient() {
10810            @Override
10811            public void binderDied() {
10812                synchronized (this) {
10813                    notifyAll();
10814                }
10815            }
10816        };
10817
10818        try {
10819            who.linkToDeath(death, 0);
10820        } catch (RemoteException e) {
10821            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10822            return;
10823        }
10824
10825        synchronized (this) {
10826            Watchdog.getInstance().setAllowRestart(allowRestart);
10827            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10828            synchronized (death) {
10829                while (who.isBinderAlive()) {
10830                    try {
10831                        death.wait();
10832                    } catch (InterruptedException e) {
10833                    }
10834                }
10835            }
10836            Watchdog.getInstance().setAllowRestart(true);
10837        }
10838    }
10839
10840    @Override
10841    public void restart() {
10842        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10843                != PackageManager.PERMISSION_GRANTED) {
10844            throw new SecurityException("Requires permission "
10845                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10846        }
10847
10848        Log.i(TAG, "Sending shutdown broadcast...");
10849
10850        BroadcastReceiver br = new BroadcastReceiver() {
10851            @Override public void onReceive(Context context, Intent intent) {
10852                // Now the broadcast is done, finish up the low-level shutdown.
10853                Log.i(TAG, "Shutting down activity manager...");
10854                shutdown(10000);
10855                Log.i(TAG, "Shutdown complete, restarting!");
10856                Process.killProcess(Process.myPid());
10857                System.exit(10);
10858            }
10859        };
10860
10861        // First send the high-level shut down broadcast.
10862        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10863        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10864        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10865        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10866        mContext.sendOrderedBroadcastAsUser(intent,
10867                UserHandle.ALL, null, br, mHandler, 0, null, null);
10868        */
10869        br.onReceive(mContext, intent);
10870    }
10871
10872    private long getLowRamTimeSinceIdle(long now) {
10873        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10874    }
10875
10876    @Override
10877    public void performIdleMaintenance() {
10878        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10879                != PackageManager.PERMISSION_GRANTED) {
10880            throw new SecurityException("Requires permission "
10881                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10882        }
10883
10884        synchronized (this) {
10885            final long now = SystemClock.uptimeMillis();
10886            final long timeSinceLastIdle = now - mLastIdleTime;
10887            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10888            mLastIdleTime = now;
10889            mLowRamTimeSinceLastIdle = 0;
10890            if (mLowRamStartTime != 0) {
10891                mLowRamStartTime = now;
10892            }
10893
10894            StringBuilder sb = new StringBuilder(128);
10895            sb.append("Idle maintenance over ");
10896            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10897            sb.append(" low RAM for ");
10898            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10899            Slog.i(TAG, sb.toString());
10900
10901            // If at least 1/3 of our time since the last idle period has been spent
10902            // with RAM low, then we want to kill processes.
10903            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10904
10905            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10906                ProcessRecord proc = mLruProcesses.get(i);
10907                if (proc.notCachedSinceIdle) {
10908                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10909                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10910                        if (doKilling && proc.initialIdlePss != 0
10911                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10912                            proc.kill("idle maint (pss " + proc.lastPss
10913                                    + " from " + proc.initialIdlePss + ")", true);
10914                        }
10915                    }
10916                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10917                    proc.notCachedSinceIdle = true;
10918                    proc.initialIdlePss = 0;
10919                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10920                            isSleeping(), now);
10921                }
10922            }
10923
10924            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10925            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10926        }
10927    }
10928
10929    private void retrieveSettings() {
10930        final ContentResolver resolver = mContext.getContentResolver();
10931        String debugApp = Settings.Global.getString(
10932            resolver, Settings.Global.DEBUG_APP);
10933        boolean waitForDebugger = Settings.Global.getInt(
10934            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10935        boolean alwaysFinishActivities = Settings.Global.getInt(
10936            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10937        boolean forceRtl = Settings.Global.getInt(
10938                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10939        // Transfer any global setting for forcing RTL layout, into a System Property
10940        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10941
10942        Configuration configuration = new Configuration();
10943        Settings.System.getConfiguration(resolver, configuration);
10944        if (forceRtl) {
10945            // This will take care of setting the correct layout direction flags
10946            configuration.setLayoutDirection(configuration.locale);
10947        }
10948
10949        synchronized (this) {
10950            mDebugApp = mOrigDebugApp = debugApp;
10951            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10952            mAlwaysFinishActivities = alwaysFinishActivities;
10953            // This happens before any activities are started, so we can
10954            // change mConfiguration in-place.
10955            updateConfigurationLocked(configuration, null, false, true);
10956            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10957        }
10958    }
10959
10960    /** Loads resources after the current configuration has been set. */
10961    private void loadResourcesOnSystemReady() {
10962        final Resources res = mContext.getResources();
10963        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10964        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10965        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10966    }
10967
10968    public boolean testIsSystemReady() {
10969        // no need to synchronize(this) just to read & return the value
10970        return mSystemReady;
10971    }
10972
10973    private static File getCalledPreBootReceiversFile() {
10974        File dataDir = Environment.getDataDirectory();
10975        File systemDir = new File(dataDir, "system");
10976        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10977        return fname;
10978    }
10979
10980    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10981        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10982        File file = getCalledPreBootReceiversFile();
10983        FileInputStream fis = null;
10984        try {
10985            fis = new FileInputStream(file);
10986            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10987            int fvers = dis.readInt();
10988            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10989                String vers = dis.readUTF();
10990                String codename = dis.readUTF();
10991                String build = dis.readUTF();
10992                if (android.os.Build.VERSION.RELEASE.equals(vers)
10993                        && android.os.Build.VERSION.CODENAME.equals(codename)
10994                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10995                    int num = dis.readInt();
10996                    while (num > 0) {
10997                        num--;
10998                        String pkg = dis.readUTF();
10999                        String cls = dis.readUTF();
11000                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11001                    }
11002                }
11003            }
11004        } catch (FileNotFoundException e) {
11005        } catch (IOException e) {
11006            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11007        } finally {
11008            if (fis != null) {
11009                try {
11010                    fis.close();
11011                } catch (IOException e) {
11012                }
11013            }
11014        }
11015        return lastDoneReceivers;
11016    }
11017
11018    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11019        File file = getCalledPreBootReceiversFile();
11020        FileOutputStream fos = null;
11021        DataOutputStream dos = null;
11022        try {
11023            fos = new FileOutputStream(file);
11024            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11025            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11026            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11027            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11028            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11029            dos.writeInt(list.size());
11030            for (int i=0; i<list.size(); i++) {
11031                dos.writeUTF(list.get(i).getPackageName());
11032                dos.writeUTF(list.get(i).getClassName());
11033            }
11034        } catch (IOException e) {
11035            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11036            file.delete();
11037        } finally {
11038            FileUtils.sync(fos);
11039            if (dos != null) {
11040                try {
11041                    dos.close();
11042                } catch (IOException e) {
11043                    // TODO Auto-generated catch block
11044                    e.printStackTrace();
11045                }
11046            }
11047        }
11048    }
11049
11050    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11051            ArrayList<ComponentName> doneReceivers, int userId) {
11052        boolean waitingUpdate = false;
11053        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11054        List<ResolveInfo> ris = null;
11055        try {
11056            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11057                    intent, null, 0, userId);
11058        } catch (RemoteException e) {
11059        }
11060        if (ris != null) {
11061            for (int i=ris.size()-1; i>=0; i--) {
11062                if ((ris.get(i).activityInfo.applicationInfo.flags
11063                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11064                    ris.remove(i);
11065                }
11066            }
11067            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11068
11069            // For User 0, load the version number. When delivering to a new user, deliver
11070            // to all receivers.
11071            if (userId == UserHandle.USER_OWNER) {
11072                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11073                for (int i=0; i<ris.size(); i++) {
11074                    ActivityInfo ai = ris.get(i).activityInfo;
11075                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11076                    if (lastDoneReceivers.contains(comp)) {
11077                        // We already did the pre boot receiver for this app with the current
11078                        // platform version, so don't do it again...
11079                        ris.remove(i);
11080                        i--;
11081                        // ...however, do keep it as one that has been done, so we don't
11082                        // forget about it when rewriting the file of last done receivers.
11083                        doneReceivers.add(comp);
11084                    }
11085                }
11086            }
11087
11088            // If primary user, send broadcast to all available users, else just to userId
11089            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11090                    : new int[] { userId };
11091            for (int i = 0; i < ris.size(); i++) {
11092                ActivityInfo ai = ris.get(i).activityInfo;
11093                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11094                doneReceivers.add(comp);
11095                intent.setComponent(comp);
11096                for (int j=0; j<users.length; j++) {
11097                    IIntentReceiver finisher = null;
11098                    // On last receiver and user, set up a completion callback
11099                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11100                        finisher = new IIntentReceiver.Stub() {
11101                            public void performReceive(Intent intent, int resultCode,
11102                                    String data, Bundle extras, boolean ordered,
11103                                    boolean sticky, int sendingUser) {
11104                                // The raw IIntentReceiver interface is called
11105                                // with the AM lock held, so redispatch to
11106                                // execute our code without the lock.
11107                                mHandler.post(onFinishCallback);
11108                            }
11109                        };
11110                    }
11111                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11112                            + " for user " + users[j]);
11113                    broadcastIntentLocked(null, null, intent, null, finisher,
11114                            0, null, null, null, AppOpsManager.OP_NONE,
11115                            true, false, MY_PID, Process.SYSTEM_UID,
11116                            users[j]);
11117                    if (finisher != null) {
11118                        waitingUpdate = true;
11119                    }
11120                }
11121            }
11122        }
11123
11124        return waitingUpdate;
11125    }
11126
11127    public void systemReady(final Runnable goingCallback) {
11128        synchronized(this) {
11129            if (mSystemReady) {
11130                // If we're done calling all the receivers, run the next "boot phase" passed in
11131                // by the SystemServer
11132                if (goingCallback != null) {
11133                    goingCallback.run();
11134                }
11135                return;
11136            }
11137
11138            // Make sure we have the current profile info, since it is needed for
11139            // security checks.
11140            updateCurrentProfileIdsLocked();
11141
11142            if (mRecentTasks == null) {
11143                mRecentTasks = mTaskPersister.restoreTasksLocked();
11144                if (!mRecentTasks.isEmpty()) {
11145                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11146                }
11147                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11148                mTaskPersister.startPersisting();
11149            }
11150
11151            // Check to see if there are any update receivers to run.
11152            if (!mDidUpdate) {
11153                if (mWaitingUpdate) {
11154                    return;
11155                }
11156                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11157                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11158                    public void run() {
11159                        synchronized (ActivityManagerService.this) {
11160                            mDidUpdate = true;
11161                        }
11162                        writeLastDonePreBootReceivers(doneReceivers);
11163                        showBootMessage(mContext.getText(
11164                                R.string.android_upgrading_complete),
11165                                false);
11166                        systemReady(goingCallback);
11167                    }
11168                }, doneReceivers, UserHandle.USER_OWNER);
11169
11170                if (mWaitingUpdate) {
11171                    return;
11172                }
11173                mDidUpdate = true;
11174            }
11175
11176            mAppOpsService.systemReady();
11177            mSystemReady = true;
11178        }
11179
11180        ArrayList<ProcessRecord> procsToKill = null;
11181        synchronized(mPidsSelfLocked) {
11182            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11183                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11184                if (!isAllowedWhileBooting(proc.info)){
11185                    if (procsToKill == null) {
11186                        procsToKill = new ArrayList<ProcessRecord>();
11187                    }
11188                    procsToKill.add(proc);
11189                }
11190            }
11191        }
11192
11193        synchronized(this) {
11194            if (procsToKill != null) {
11195                for (int i=procsToKill.size()-1; i>=0; i--) {
11196                    ProcessRecord proc = procsToKill.get(i);
11197                    Slog.i(TAG, "Removing system update proc: " + proc);
11198                    removeProcessLocked(proc, true, false, "system update done");
11199                }
11200            }
11201
11202            // Now that we have cleaned up any update processes, we
11203            // are ready to start launching real processes and know that
11204            // we won't trample on them any more.
11205            mProcessesReady = true;
11206        }
11207
11208        Slog.i(TAG, "System now ready");
11209        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11210            SystemClock.uptimeMillis());
11211
11212        synchronized(this) {
11213            // Make sure we have no pre-ready processes sitting around.
11214
11215            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11216                ResolveInfo ri = mContext.getPackageManager()
11217                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11218                                STOCK_PM_FLAGS);
11219                CharSequence errorMsg = null;
11220                if (ri != null) {
11221                    ActivityInfo ai = ri.activityInfo;
11222                    ApplicationInfo app = ai.applicationInfo;
11223                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11224                        mTopAction = Intent.ACTION_FACTORY_TEST;
11225                        mTopData = null;
11226                        mTopComponent = new ComponentName(app.packageName,
11227                                ai.name);
11228                    } else {
11229                        errorMsg = mContext.getResources().getText(
11230                                com.android.internal.R.string.factorytest_not_system);
11231                    }
11232                } else {
11233                    errorMsg = mContext.getResources().getText(
11234                            com.android.internal.R.string.factorytest_no_action);
11235                }
11236                if (errorMsg != null) {
11237                    mTopAction = null;
11238                    mTopData = null;
11239                    mTopComponent = null;
11240                    Message msg = Message.obtain();
11241                    msg.what = SHOW_FACTORY_ERROR_MSG;
11242                    msg.getData().putCharSequence("msg", errorMsg);
11243                    mHandler.sendMessage(msg);
11244                }
11245            }
11246        }
11247
11248        retrieveSettings();
11249        loadResourcesOnSystemReady();
11250
11251        synchronized (this) {
11252            readGrantedUriPermissionsLocked();
11253        }
11254
11255        if (goingCallback != null) goingCallback.run();
11256
11257        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11258                Integer.toString(mCurrentUserId), mCurrentUserId);
11259        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11260                Integer.toString(mCurrentUserId), mCurrentUserId);
11261        mSystemServiceManager.startUser(mCurrentUserId);
11262
11263        synchronized (this) {
11264            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11265                try {
11266                    List apps = AppGlobals.getPackageManager().
11267                        getPersistentApplications(STOCK_PM_FLAGS);
11268                    if (apps != null) {
11269                        int N = apps.size();
11270                        int i;
11271                        for (i=0; i<N; i++) {
11272                            ApplicationInfo info
11273                                = (ApplicationInfo)apps.get(i);
11274                            if (info != null &&
11275                                    !info.packageName.equals("android")) {
11276                                addAppLocked(info, false, null /* ABI override */);
11277                            }
11278                        }
11279                    }
11280                } catch (RemoteException ex) {
11281                    // pm is in same process, this will never happen.
11282                }
11283            }
11284
11285            // Start up initial activity.
11286            mBooting = true;
11287            startHomeActivityLocked(mCurrentUserId);
11288
11289            try {
11290                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11291                    Message msg = Message.obtain();
11292                    msg.what = SHOW_UID_ERROR_MSG;
11293                    mHandler.sendMessage(msg);
11294                }
11295            } catch (RemoteException e) {
11296            }
11297
11298            long ident = Binder.clearCallingIdentity();
11299            try {
11300                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11301                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11302                        | Intent.FLAG_RECEIVER_FOREGROUND);
11303                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11304                broadcastIntentLocked(null, null, intent,
11305                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11306                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11307                intent = new Intent(Intent.ACTION_USER_STARTING);
11308                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11309                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11310                broadcastIntentLocked(null, null, intent,
11311                        null, new IIntentReceiver.Stub() {
11312                            @Override
11313                            public void performReceive(Intent intent, int resultCode, String data,
11314                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11315                                    throws RemoteException {
11316                            }
11317                        }, 0, null, null,
11318                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11319                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11320            } catch (Throwable t) {
11321                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11322            } finally {
11323                Binder.restoreCallingIdentity(ident);
11324            }
11325            mStackSupervisor.resumeTopActivitiesLocked();
11326            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11327        }
11328    }
11329
11330    private boolean makeAppCrashingLocked(ProcessRecord app,
11331            String shortMsg, String longMsg, String stackTrace) {
11332        app.crashing = true;
11333        app.crashingReport = generateProcessError(app,
11334                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11335        startAppProblemLocked(app);
11336        app.stopFreezingAllLocked();
11337        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11338    }
11339
11340    private void makeAppNotRespondingLocked(ProcessRecord app,
11341            String activity, String shortMsg, String longMsg) {
11342        app.notResponding = true;
11343        app.notRespondingReport = generateProcessError(app,
11344                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11345                activity, shortMsg, longMsg, null);
11346        startAppProblemLocked(app);
11347        app.stopFreezingAllLocked();
11348    }
11349
11350    /**
11351     * Generate a process error record, suitable for attachment to a ProcessRecord.
11352     *
11353     * @param app The ProcessRecord in which the error occurred.
11354     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11355     *                      ActivityManager.AppErrorStateInfo
11356     * @param activity The activity associated with the crash, if known.
11357     * @param shortMsg Short message describing the crash.
11358     * @param longMsg Long message describing the crash.
11359     * @param stackTrace Full crash stack trace, may be null.
11360     *
11361     * @return Returns a fully-formed AppErrorStateInfo record.
11362     */
11363    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11364            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11365        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11366
11367        report.condition = condition;
11368        report.processName = app.processName;
11369        report.pid = app.pid;
11370        report.uid = app.info.uid;
11371        report.tag = activity;
11372        report.shortMsg = shortMsg;
11373        report.longMsg = longMsg;
11374        report.stackTrace = stackTrace;
11375
11376        return report;
11377    }
11378
11379    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11380        synchronized (this) {
11381            app.crashing = false;
11382            app.crashingReport = null;
11383            app.notResponding = false;
11384            app.notRespondingReport = null;
11385            if (app.anrDialog == fromDialog) {
11386                app.anrDialog = null;
11387            }
11388            if (app.waitDialog == fromDialog) {
11389                app.waitDialog = null;
11390            }
11391            if (app.pid > 0 && app.pid != MY_PID) {
11392                handleAppCrashLocked(app, null, null, null);
11393                app.kill("user request after error", true);
11394            }
11395        }
11396    }
11397
11398    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11399            String stackTrace) {
11400        long now = SystemClock.uptimeMillis();
11401
11402        Long crashTime;
11403        if (!app.isolated) {
11404            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11405        } else {
11406            crashTime = null;
11407        }
11408        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11409            // This process loses!
11410            Slog.w(TAG, "Process " + app.info.processName
11411                    + " has crashed too many times: killing!");
11412            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11413                    app.userId, app.info.processName, app.uid);
11414            mStackSupervisor.handleAppCrashLocked(app);
11415            if (!app.persistent) {
11416                // We don't want to start this process again until the user
11417                // explicitly does so...  but for persistent process, we really
11418                // need to keep it running.  If a persistent process is actually
11419                // repeatedly crashing, then badness for everyone.
11420                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11421                        app.info.processName);
11422                if (!app.isolated) {
11423                    // XXX We don't have a way to mark isolated processes
11424                    // as bad, since they don't have a peristent identity.
11425                    mBadProcesses.put(app.info.processName, app.uid,
11426                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11427                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11428                }
11429                app.bad = true;
11430                app.removed = true;
11431                // Don't let services in this process be restarted and potentially
11432                // annoy the user repeatedly.  Unless it is persistent, since those
11433                // processes run critical code.
11434                removeProcessLocked(app, false, false, "crash");
11435                mStackSupervisor.resumeTopActivitiesLocked();
11436                return false;
11437            }
11438            mStackSupervisor.resumeTopActivitiesLocked();
11439        } else {
11440            mStackSupervisor.finishTopRunningActivityLocked(app);
11441        }
11442
11443        // Bump up the crash count of any services currently running in the proc.
11444        for (int i=app.services.size()-1; i>=0; i--) {
11445            // Any services running in the application need to be placed
11446            // back in the pending list.
11447            ServiceRecord sr = app.services.valueAt(i);
11448            sr.crashCount++;
11449        }
11450
11451        // If the crashing process is what we consider to be the "home process" and it has been
11452        // replaced by a third-party app, clear the package preferred activities from packages
11453        // with a home activity running in the process to prevent a repeatedly crashing app
11454        // from blocking the user to manually clear the list.
11455        final ArrayList<ActivityRecord> activities = app.activities;
11456        if (app == mHomeProcess && activities.size() > 0
11457                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11458            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11459                final ActivityRecord r = activities.get(activityNdx);
11460                if (r.isHomeActivity()) {
11461                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11462                    try {
11463                        ActivityThread.getPackageManager()
11464                                .clearPackagePreferredActivities(r.packageName);
11465                    } catch (RemoteException c) {
11466                        // pm is in same process, this will never happen.
11467                    }
11468                }
11469            }
11470        }
11471
11472        if (!app.isolated) {
11473            // XXX Can't keep track of crash times for isolated processes,
11474            // because they don't have a perisistent identity.
11475            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11476        }
11477
11478        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11479        return true;
11480    }
11481
11482    void startAppProblemLocked(ProcessRecord app) {
11483        // If this app is not running under the current user, then we
11484        // can't give it a report button because that would require
11485        // launching the report UI under a different user.
11486        app.errorReportReceiver = null;
11487
11488        for (int userId : mCurrentProfileIds) {
11489            if (app.userId == userId) {
11490                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11491                        mContext, app.info.packageName, app.info.flags);
11492            }
11493        }
11494        skipCurrentReceiverLocked(app);
11495    }
11496
11497    void skipCurrentReceiverLocked(ProcessRecord app) {
11498        for (BroadcastQueue queue : mBroadcastQueues) {
11499            queue.skipCurrentReceiverLocked(app);
11500        }
11501    }
11502
11503    /**
11504     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11505     * The application process will exit immediately after this call returns.
11506     * @param app object of the crashing app, null for the system server
11507     * @param crashInfo describing the exception
11508     */
11509    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11510        ProcessRecord r = findAppProcess(app, "Crash");
11511        final String processName = app == null ? "system_server"
11512                : (r == null ? "unknown" : r.processName);
11513
11514        handleApplicationCrashInner("crash", r, processName, crashInfo);
11515    }
11516
11517    /* Native crash reporting uses this inner version because it needs to be somewhat
11518     * decoupled from the AM-managed cleanup lifecycle
11519     */
11520    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11521            ApplicationErrorReport.CrashInfo crashInfo) {
11522        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11523                UserHandle.getUserId(Binder.getCallingUid()), processName,
11524                r == null ? -1 : r.info.flags,
11525                crashInfo.exceptionClassName,
11526                crashInfo.exceptionMessage,
11527                crashInfo.throwFileName,
11528                crashInfo.throwLineNumber);
11529
11530        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11531
11532        crashApplication(r, crashInfo);
11533    }
11534
11535    public void handleApplicationStrictModeViolation(
11536            IBinder app,
11537            int violationMask,
11538            StrictMode.ViolationInfo info) {
11539        ProcessRecord r = findAppProcess(app, "StrictMode");
11540        if (r == null) {
11541            return;
11542        }
11543
11544        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11545            Integer stackFingerprint = info.hashCode();
11546            boolean logIt = true;
11547            synchronized (mAlreadyLoggedViolatedStacks) {
11548                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11549                    logIt = false;
11550                    // TODO: sub-sample into EventLog for these, with
11551                    // the info.durationMillis?  Then we'd get
11552                    // the relative pain numbers, without logging all
11553                    // the stack traces repeatedly.  We'd want to do
11554                    // likewise in the client code, which also does
11555                    // dup suppression, before the Binder call.
11556                } else {
11557                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11558                        mAlreadyLoggedViolatedStacks.clear();
11559                    }
11560                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11561                }
11562            }
11563            if (logIt) {
11564                logStrictModeViolationToDropBox(r, info);
11565            }
11566        }
11567
11568        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11569            AppErrorResult result = new AppErrorResult();
11570            synchronized (this) {
11571                final long origId = Binder.clearCallingIdentity();
11572
11573                Message msg = Message.obtain();
11574                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11575                HashMap<String, Object> data = new HashMap<String, Object>();
11576                data.put("result", result);
11577                data.put("app", r);
11578                data.put("violationMask", violationMask);
11579                data.put("info", info);
11580                msg.obj = data;
11581                mHandler.sendMessage(msg);
11582
11583                Binder.restoreCallingIdentity(origId);
11584            }
11585            int res = result.get();
11586            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11587        }
11588    }
11589
11590    // Depending on the policy in effect, there could be a bunch of
11591    // these in quick succession so we try to batch these together to
11592    // minimize disk writes, number of dropbox entries, and maximize
11593    // compression, by having more fewer, larger records.
11594    private void logStrictModeViolationToDropBox(
11595            ProcessRecord process,
11596            StrictMode.ViolationInfo info) {
11597        if (info == null) {
11598            return;
11599        }
11600        final boolean isSystemApp = process == null ||
11601                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11602                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11603        final String processName = process == null ? "unknown" : process.processName;
11604        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11605        final DropBoxManager dbox = (DropBoxManager)
11606                mContext.getSystemService(Context.DROPBOX_SERVICE);
11607
11608        // Exit early if the dropbox isn't configured to accept this report type.
11609        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11610
11611        boolean bufferWasEmpty;
11612        boolean needsFlush;
11613        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11614        synchronized (sb) {
11615            bufferWasEmpty = sb.length() == 0;
11616            appendDropBoxProcessHeaders(process, processName, sb);
11617            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11618            sb.append("System-App: ").append(isSystemApp).append("\n");
11619            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11620            if (info.violationNumThisLoop != 0) {
11621                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11622            }
11623            if (info.numAnimationsRunning != 0) {
11624                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11625            }
11626            if (info.broadcastIntentAction != null) {
11627                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11628            }
11629            if (info.durationMillis != -1) {
11630                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11631            }
11632            if (info.numInstances != -1) {
11633                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11634            }
11635            if (info.tags != null) {
11636                for (String tag : info.tags) {
11637                    sb.append("Span-Tag: ").append(tag).append("\n");
11638                }
11639            }
11640            sb.append("\n");
11641            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11642                sb.append(info.crashInfo.stackTrace);
11643            }
11644            sb.append("\n");
11645
11646            // Only buffer up to ~64k.  Various logging bits truncate
11647            // things at 128k.
11648            needsFlush = (sb.length() > 64 * 1024);
11649        }
11650
11651        // Flush immediately if the buffer's grown too large, or this
11652        // is a non-system app.  Non-system apps are isolated with a
11653        // different tag & policy and not batched.
11654        //
11655        // Batching is useful during internal testing with
11656        // StrictMode settings turned up high.  Without batching,
11657        // thousands of separate files could be created on boot.
11658        if (!isSystemApp || needsFlush) {
11659            new Thread("Error dump: " + dropboxTag) {
11660                @Override
11661                public void run() {
11662                    String report;
11663                    synchronized (sb) {
11664                        report = sb.toString();
11665                        sb.delete(0, sb.length());
11666                        sb.trimToSize();
11667                    }
11668                    if (report.length() != 0) {
11669                        dbox.addText(dropboxTag, report);
11670                    }
11671                }
11672            }.start();
11673            return;
11674        }
11675
11676        // System app batching:
11677        if (!bufferWasEmpty) {
11678            // An existing dropbox-writing thread is outstanding, so
11679            // we don't need to start it up.  The existing thread will
11680            // catch the buffer appends we just did.
11681            return;
11682        }
11683
11684        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11685        // (After this point, we shouldn't access AMS internal data structures.)
11686        new Thread("Error dump: " + dropboxTag) {
11687            @Override
11688            public void run() {
11689                // 5 second sleep to let stacks arrive and be batched together
11690                try {
11691                    Thread.sleep(5000);  // 5 seconds
11692                } catch (InterruptedException e) {}
11693
11694                String errorReport;
11695                synchronized (mStrictModeBuffer) {
11696                    errorReport = mStrictModeBuffer.toString();
11697                    if (errorReport.length() == 0) {
11698                        return;
11699                    }
11700                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11701                    mStrictModeBuffer.trimToSize();
11702                }
11703                dbox.addText(dropboxTag, errorReport);
11704            }
11705        }.start();
11706    }
11707
11708    /**
11709     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11710     * @param app object of the crashing app, null for the system server
11711     * @param tag reported by the caller
11712     * @param system whether this wtf is coming from the system
11713     * @param crashInfo describing the context of the error
11714     * @return true if the process should exit immediately (WTF is fatal)
11715     */
11716    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11717            final ApplicationErrorReport.CrashInfo crashInfo) {
11718        final ProcessRecord r = findAppProcess(app, "WTF");
11719        final String processName = app == null ? "system_server"
11720                : (r == null ? "unknown" : r.processName);
11721
11722        EventLog.writeEvent(EventLogTags.AM_WTF,
11723                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11724                processName,
11725                r == null ? -1 : r.info.flags,
11726                tag, crashInfo.exceptionMessage);
11727
11728        if (system) {
11729            // If this is coming from the system, we could very well have low-level
11730            // system locks held, so we want to do this all asynchronously.  And we
11731            // never want this to become fatal, so there is that too.
11732            mHandler.post(new Runnable() {
11733                @Override public void run() {
11734                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11735                            crashInfo);
11736                }
11737            });
11738            return false;
11739        }
11740
11741        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11742
11743        if (r != null && r.pid != Process.myPid() &&
11744                Settings.Global.getInt(mContext.getContentResolver(),
11745                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11746            crashApplication(r, crashInfo);
11747            return true;
11748        } else {
11749            return false;
11750        }
11751    }
11752
11753    /**
11754     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11755     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11756     */
11757    private ProcessRecord findAppProcess(IBinder app, String reason) {
11758        if (app == null) {
11759            return null;
11760        }
11761
11762        synchronized (this) {
11763            final int NP = mProcessNames.getMap().size();
11764            for (int ip=0; ip<NP; ip++) {
11765                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11766                final int NA = apps.size();
11767                for (int ia=0; ia<NA; ia++) {
11768                    ProcessRecord p = apps.valueAt(ia);
11769                    if (p.thread != null && p.thread.asBinder() == app) {
11770                        return p;
11771                    }
11772                }
11773            }
11774
11775            Slog.w(TAG, "Can't find mystery application for " + reason
11776                    + " from pid=" + Binder.getCallingPid()
11777                    + " uid=" + Binder.getCallingUid() + ": " + app);
11778            return null;
11779        }
11780    }
11781
11782    /**
11783     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11784     * to append various headers to the dropbox log text.
11785     */
11786    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11787            StringBuilder sb) {
11788        // Watchdog thread ends up invoking this function (with
11789        // a null ProcessRecord) to add the stack file to dropbox.
11790        // Do not acquire a lock on this (am) in such cases, as it
11791        // could cause a potential deadlock, if and when watchdog
11792        // is invoked due to unavailability of lock on am and it
11793        // would prevent watchdog from killing system_server.
11794        if (process == null) {
11795            sb.append("Process: ").append(processName).append("\n");
11796            return;
11797        }
11798        // Note: ProcessRecord 'process' is guarded by the service
11799        // instance.  (notably process.pkgList, which could otherwise change
11800        // concurrently during execution of this method)
11801        synchronized (this) {
11802            sb.append("Process: ").append(processName).append("\n");
11803            int flags = process.info.flags;
11804            IPackageManager pm = AppGlobals.getPackageManager();
11805            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11806            for (int ip=0; ip<process.pkgList.size(); ip++) {
11807                String pkg = process.pkgList.keyAt(ip);
11808                sb.append("Package: ").append(pkg);
11809                try {
11810                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11811                    if (pi != null) {
11812                        sb.append(" v").append(pi.versionCode);
11813                        if (pi.versionName != null) {
11814                            sb.append(" (").append(pi.versionName).append(")");
11815                        }
11816                    }
11817                } catch (RemoteException e) {
11818                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11819                }
11820                sb.append("\n");
11821            }
11822        }
11823    }
11824
11825    private static String processClass(ProcessRecord process) {
11826        if (process == null || process.pid == MY_PID) {
11827            return "system_server";
11828        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11829            return "system_app";
11830        } else {
11831            return "data_app";
11832        }
11833    }
11834
11835    /**
11836     * Write a description of an error (crash, WTF, ANR) to the drop box.
11837     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11838     * @param process which caused the error, null means the system server
11839     * @param activity which triggered the error, null if unknown
11840     * @param parent activity related to the error, null if unknown
11841     * @param subject line related to the error, null if absent
11842     * @param report in long form describing the error, null if absent
11843     * @param logFile to include in the report, null if none
11844     * @param crashInfo giving an application stack trace, null if absent
11845     */
11846    public void addErrorToDropBox(String eventType,
11847            ProcessRecord process, String processName, ActivityRecord activity,
11848            ActivityRecord parent, String subject,
11849            final String report, final File logFile,
11850            final ApplicationErrorReport.CrashInfo crashInfo) {
11851        // NOTE -- this must never acquire the ActivityManagerService lock,
11852        // otherwise the watchdog may be prevented from resetting the system.
11853
11854        final String dropboxTag = processClass(process) + "_" + eventType;
11855        final DropBoxManager dbox = (DropBoxManager)
11856                mContext.getSystemService(Context.DROPBOX_SERVICE);
11857
11858        // Exit early if the dropbox isn't configured to accept this report type.
11859        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11860
11861        final StringBuilder sb = new StringBuilder(1024);
11862        appendDropBoxProcessHeaders(process, processName, sb);
11863        if (activity != null) {
11864            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11865        }
11866        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11867            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11868        }
11869        if (parent != null && parent != activity) {
11870            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11871        }
11872        if (subject != null) {
11873            sb.append("Subject: ").append(subject).append("\n");
11874        }
11875        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11876        if (Debug.isDebuggerConnected()) {
11877            sb.append("Debugger: Connected\n");
11878        }
11879        sb.append("\n");
11880
11881        // Do the rest in a worker thread to avoid blocking the caller on I/O
11882        // (After this point, we shouldn't access AMS internal data structures.)
11883        Thread worker = new Thread("Error dump: " + dropboxTag) {
11884            @Override
11885            public void run() {
11886                if (report != null) {
11887                    sb.append(report);
11888                }
11889                if (logFile != null) {
11890                    try {
11891                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11892                                    "\n\n[[TRUNCATED]]"));
11893                    } catch (IOException e) {
11894                        Slog.e(TAG, "Error reading " + logFile, e);
11895                    }
11896                }
11897                if (crashInfo != null && crashInfo.stackTrace != null) {
11898                    sb.append(crashInfo.stackTrace);
11899                }
11900
11901                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11902                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11903                if (lines > 0) {
11904                    sb.append("\n");
11905
11906                    // Merge several logcat streams, and take the last N lines
11907                    InputStreamReader input = null;
11908                    try {
11909                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11910                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11911                                "-b", "crash",
11912                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11913
11914                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11915                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11916                        input = new InputStreamReader(logcat.getInputStream());
11917
11918                        int num;
11919                        char[] buf = new char[8192];
11920                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11921                    } catch (IOException e) {
11922                        Slog.e(TAG, "Error running logcat", e);
11923                    } finally {
11924                        if (input != null) try { input.close(); } catch (IOException e) {}
11925                    }
11926                }
11927
11928                dbox.addText(dropboxTag, sb.toString());
11929            }
11930        };
11931
11932        if (process == null) {
11933            // If process is null, we are being called from some internal code
11934            // and may be about to die -- run this synchronously.
11935            worker.run();
11936        } else {
11937            worker.start();
11938        }
11939    }
11940
11941    /**
11942     * Bring up the "unexpected error" dialog box for a crashing app.
11943     * Deal with edge cases (intercepts from instrumented applications,
11944     * ActivityController, error intent receivers, that sort of thing).
11945     * @param r the application crashing
11946     * @param crashInfo describing the failure
11947     */
11948    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11949        long timeMillis = System.currentTimeMillis();
11950        String shortMsg = crashInfo.exceptionClassName;
11951        String longMsg = crashInfo.exceptionMessage;
11952        String stackTrace = crashInfo.stackTrace;
11953        if (shortMsg != null && longMsg != null) {
11954            longMsg = shortMsg + ": " + longMsg;
11955        } else if (shortMsg != null) {
11956            longMsg = shortMsg;
11957        }
11958
11959        AppErrorResult result = new AppErrorResult();
11960        synchronized (this) {
11961            if (mController != null) {
11962                try {
11963                    String name = r != null ? r.processName : null;
11964                    int pid = r != null ? r.pid : Binder.getCallingPid();
11965                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11966                    if (!mController.appCrashed(name, pid,
11967                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11968                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11969                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11970                            Slog.w(TAG, "Skip killing native crashed app " + name
11971                                    + "(" + pid + ") during testing");
11972                        } else {
11973                            Slog.w(TAG, "Force-killing crashed app " + name
11974                                    + " at watcher's request");
11975                            if (r != null) {
11976                                r.kill("crash", true);
11977                            } else {
11978                                // Huh.
11979                                Process.killProcess(pid);
11980                                Process.killProcessGroup(uid, pid);
11981                            }
11982                        }
11983                        return;
11984                    }
11985                } catch (RemoteException e) {
11986                    mController = null;
11987                    Watchdog.getInstance().setActivityController(null);
11988                }
11989            }
11990
11991            final long origId = Binder.clearCallingIdentity();
11992
11993            // If this process is running instrumentation, finish it.
11994            if (r != null && r.instrumentationClass != null) {
11995                Slog.w(TAG, "Error in app " + r.processName
11996                      + " running instrumentation " + r.instrumentationClass + ":");
11997                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11998                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11999                Bundle info = new Bundle();
12000                info.putString("shortMsg", shortMsg);
12001                info.putString("longMsg", longMsg);
12002                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12003                Binder.restoreCallingIdentity(origId);
12004                return;
12005            }
12006
12007            // If we can't identify the process or it's already exceeded its crash quota,
12008            // quit right away without showing a crash dialog.
12009            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12010                Binder.restoreCallingIdentity(origId);
12011                return;
12012            }
12013
12014            Message msg = Message.obtain();
12015            msg.what = SHOW_ERROR_MSG;
12016            HashMap data = new HashMap();
12017            data.put("result", result);
12018            data.put("app", r);
12019            msg.obj = data;
12020            mHandler.sendMessage(msg);
12021
12022            Binder.restoreCallingIdentity(origId);
12023        }
12024
12025        int res = result.get();
12026
12027        Intent appErrorIntent = null;
12028        synchronized (this) {
12029            if (r != null && !r.isolated) {
12030                // XXX Can't keep track of crash time for isolated processes,
12031                // since they don't have a persistent identity.
12032                mProcessCrashTimes.put(r.info.processName, r.uid,
12033                        SystemClock.uptimeMillis());
12034            }
12035            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12036                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12037            }
12038        }
12039
12040        if (appErrorIntent != null) {
12041            try {
12042                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12043            } catch (ActivityNotFoundException e) {
12044                Slog.w(TAG, "bug report receiver dissappeared", e);
12045            }
12046        }
12047    }
12048
12049    Intent createAppErrorIntentLocked(ProcessRecord r,
12050            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12051        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12052        if (report == null) {
12053            return null;
12054        }
12055        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12056        result.setComponent(r.errorReportReceiver);
12057        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12058        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12059        return result;
12060    }
12061
12062    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12063            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12064        if (r.errorReportReceiver == null) {
12065            return null;
12066        }
12067
12068        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12069            return null;
12070        }
12071
12072        ApplicationErrorReport report = new ApplicationErrorReport();
12073        report.packageName = r.info.packageName;
12074        report.installerPackageName = r.errorReportReceiver.getPackageName();
12075        report.processName = r.processName;
12076        report.time = timeMillis;
12077        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12078
12079        if (r.crashing || r.forceCrashReport) {
12080            report.type = ApplicationErrorReport.TYPE_CRASH;
12081            report.crashInfo = crashInfo;
12082        } else if (r.notResponding) {
12083            report.type = ApplicationErrorReport.TYPE_ANR;
12084            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12085
12086            report.anrInfo.activity = r.notRespondingReport.tag;
12087            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12088            report.anrInfo.info = r.notRespondingReport.longMsg;
12089        }
12090
12091        return report;
12092    }
12093
12094    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12095        enforceNotIsolatedCaller("getProcessesInErrorState");
12096        // assume our apps are happy - lazy create the list
12097        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12098
12099        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12100                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12101        int userId = UserHandle.getUserId(Binder.getCallingUid());
12102
12103        synchronized (this) {
12104
12105            // iterate across all processes
12106            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12107                ProcessRecord app = mLruProcesses.get(i);
12108                if (!allUsers && app.userId != userId) {
12109                    continue;
12110                }
12111                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12112                    // This one's in trouble, so we'll generate a report for it
12113                    // crashes are higher priority (in case there's a crash *and* an anr)
12114                    ActivityManager.ProcessErrorStateInfo report = null;
12115                    if (app.crashing) {
12116                        report = app.crashingReport;
12117                    } else if (app.notResponding) {
12118                        report = app.notRespondingReport;
12119                    }
12120
12121                    if (report != null) {
12122                        if (errList == null) {
12123                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12124                        }
12125                        errList.add(report);
12126                    } else {
12127                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12128                                " crashing = " + app.crashing +
12129                                " notResponding = " + app.notResponding);
12130                    }
12131                }
12132            }
12133        }
12134
12135        return errList;
12136    }
12137
12138    static int procStateToImportance(int procState, int memAdj,
12139            ActivityManager.RunningAppProcessInfo currApp) {
12140        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12141        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12142            currApp.lru = memAdj;
12143        } else {
12144            currApp.lru = 0;
12145        }
12146        return imp;
12147    }
12148
12149    private void fillInProcMemInfo(ProcessRecord app,
12150            ActivityManager.RunningAppProcessInfo outInfo) {
12151        outInfo.pid = app.pid;
12152        outInfo.uid = app.info.uid;
12153        if (mHeavyWeightProcess == app) {
12154            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12155        }
12156        if (app.persistent) {
12157            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12158        }
12159        if (app.activities.size() > 0) {
12160            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12161        }
12162        outInfo.lastTrimLevel = app.trimMemoryLevel;
12163        int adj = app.curAdj;
12164        int procState = app.curProcState;
12165        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12166        outInfo.importanceReasonCode = app.adjTypeCode;
12167        outInfo.processState = app.curProcState;
12168    }
12169
12170    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12171        enforceNotIsolatedCaller("getRunningAppProcesses");
12172        // Lazy instantiation of list
12173        List<ActivityManager.RunningAppProcessInfo> runList = null;
12174        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12175                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12176        int userId = UserHandle.getUserId(Binder.getCallingUid());
12177        synchronized (this) {
12178            // Iterate across all processes
12179            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12180                ProcessRecord app = mLruProcesses.get(i);
12181                if (!allUsers && app.userId != userId) {
12182                    continue;
12183                }
12184                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12185                    // Generate process state info for running application
12186                    ActivityManager.RunningAppProcessInfo currApp =
12187                        new ActivityManager.RunningAppProcessInfo(app.processName,
12188                                app.pid, app.getPackageList());
12189                    fillInProcMemInfo(app, currApp);
12190                    if (app.adjSource instanceof ProcessRecord) {
12191                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12192                        currApp.importanceReasonImportance =
12193                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12194                                        app.adjSourceProcState);
12195                    } else if (app.adjSource instanceof ActivityRecord) {
12196                        ActivityRecord r = (ActivityRecord)app.adjSource;
12197                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12198                    }
12199                    if (app.adjTarget instanceof ComponentName) {
12200                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12201                    }
12202                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12203                    //        + " lru=" + currApp.lru);
12204                    if (runList == null) {
12205                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12206                    }
12207                    runList.add(currApp);
12208                }
12209            }
12210        }
12211        return runList;
12212    }
12213
12214    public List<ApplicationInfo> getRunningExternalApplications() {
12215        enforceNotIsolatedCaller("getRunningExternalApplications");
12216        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12217        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12218        if (runningApps != null && runningApps.size() > 0) {
12219            Set<String> extList = new HashSet<String>();
12220            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12221                if (app.pkgList != null) {
12222                    for (String pkg : app.pkgList) {
12223                        extList.add(pkg);
12224                    }
12225                }
12226            }
12227            IPackageManager pm = AppGlobals.getPackageManager();
12228            for (String pkg : extList) {
12229                try {
12230                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12231                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12232                        retList.add(info);
12233                    }
12234                } catch (RemoteException e) {
12235                }
12236            }
12237        }
12238        return retList;
12239    }
12240
12241    @Override
12242    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12243        enforceNotIsolatedCaller("getMyMemoryState");
12244        synchronized (this) {
12245            ProcessRecord proc;
12246            synchronized (mPidsSelfLocked) {
12247                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12248            }
12249            fillInProcMemInfo(proc, outInfo);
12250        }
12251    }
12252
12253    @Override
12254    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12255        if (checkCallingPermission(android.Manifest.permission.DUMP)
12256                != PackageManager.PERMISSION_GRANTED) {
12257            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12258                    + Binder.getCallingPid()
12259                    + ", uid=" + Binder.getCallingUid()
12260                    + " without permission "
12261                    + android.Manifest.permission.DUMP);
12262            return;
12263        }
12264
12265        boolean dumpAll = false;
12266        boolean dumpClient = false;
12267        String dumpPackage = null;
12268
12269        int opti = 0;
12270        while (opti < args.length) {
12271            String opt = args[opti];
12272            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12273                break;
12274            }
12275            opti++;
12276            if ("-a".equals(opt)) {
12277                dumpAll = true;
12278            } else if ("-c".equals(opt)) {
12279                dumpClient = true;
12280            } else if ("-h".equals(opt)) {
12281                pw.println("Activity manager dump options:");
12282                pw.println("  [-a] [-c] [-h] [cmd] ...");
12283                pw.println("  cmd may be one of:");
12284                pw.println("    a[ctivities]: activity stack state");
12285                pw.println("    r[recents]: recent activities state");
12286                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12287                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12288                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12289                pw.println("    o[om]: out of memory management");
12290                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12291                pw.println("    provider [COMP_SPEC]: provider client-side state");
12292                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12293                pw.println("    service [COMP_SPEC]: service client-side state");
12294                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12295                pw.println("    all: dump all activities");
12296                pw.println("    top: dump the top activity");
12297                pw.println("    write: write all pending state to storage");
12298                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12299                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12300                pw.println("    a partial substring in a component name, a");
12301                pw.println("    hex object identifier.");
12302                pw.println("  -a: include all available server state.");
12303                pw.println("  -c: include client state.");
12304                return;
12305            } else {
12306                pw.println("Unknown argument: " + opt + "; use -h for help");
12307            }
12308        }
12309
12310        long origId = Binder.clearCallingIdentity();
12311        boolean more = false;
12312        // Is the caller requesting to dump a particular piece of data?
12313        if (opti < args.length) {
12314            String cmd = args[opti];
12315            opti++;
12316            if ("activities".equals(cmd) || "a".equals(cmd)) {
12317                synchronized (this) {
12318                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12319                }
12320            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12321                synchronized (this) {
12322                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12323                }
12324            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12325                String[] newArgs;
12326                String name;
12327                if (opti >= args.length) {
12328                    name = null;
12329                    newArgs = EMPTY_STRING_ARRAY;
12330                } else {
12331                    name = args[opti];
12332                    opti++;
12333                    newArgs = new String[args.length - opti];
12334                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12335                            args.length - opti);
12336                }
12337                synchronized (this) {
12338                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12339                }
12340            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12341                String[] newArgs;
12342                String name;
12343                if (opti >= args.length) {
12344                    name = null;
12345                    newArgs = EMPTY_STRING_ARRAY;
12346                } else {
12347                    name = args[opti];
12348                    opti++;
12349                    newArgs = new String[args.length - opti];
12350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12351                            args.length - opti);
12352                }
12353                synchronized (this) {
12354                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12355                }
12356            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12357                String[] newArgs;
12358                String name;
12359                if (opti >= args.length) {
12360                    name = null;
12361                    newArgs = EMPTY_STRING_ARRAY;
12362                } else {
12363                    name = args[opti];
12364                    opti++;
12365                    newArgs = new String[args.length - opti];
12366                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12367                            args.length - opti);
12368                }
12369                synchronized (this) {
12370                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12371                }
12372            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12373                synchronized (this) {
12374                    dumpOomLocked(fd, pw, args, opti, true);
12375                }
12376            } else if ("provider".equals(cmd)) {
12377                String[] newArgs;
12378                String name;
12379                if (opti >= args.length) {
12380                    name = null;
12381                    newArgs = EMPTY_STRING_ARRAY;
12382                } else {
12383                    name = args[opti];
12384                    opti++;
12385                    newArgs = new String[args.length - opti];
12386                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12387                }
12388                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12389                    pw.println("No providers match: " + name);
12390                    pw.println("Use -h for help.");
12391                }
12392            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12393                synchronized (this) {
12394                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12395                }
12396            } else if ("service".equals(cmd)) {
12397                String[] newArgs;
12398                String name;
12399                if (opti >= args.length) {
12400                    name = null;
12401                    newArgs = EMPTY_STRING_ARRAY;
12402                } else {
12403                    name = args[opti];
12404                    opti++;
12405                    newArgs = new String[args.length - opti];
12406                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12407                            args.length - opti);
12408                }
12409                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12410                    pw.println("No services match: " + name);
12411                    pw.println("Use -h for help.");
12412                }
12413            } else if ("package".equals(cmd)) {
12414                String[] newArgs;
12415                if (opti >= args.length) {
12416                    pw.println("package: no package name specified");
12417                    pw.println("Use -h for help.");
12418                } else {
12419                    dumpPackage = args[opti];
12420                    opti++;
12421                    newArgs = new String[args.length - opti];
12422                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12423                            args.length - opti);
12424                    args = newArgs;
12425                    opti = 0;
12426                    more = true;
12427                }
12428            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12429                synchronized (this) {
12430                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12431                }
12432            } else if ("write".equals(cmd)) {
12433                mTaskPersister.flush();
12434                pw.println("All tasks persisted.");
12435                return;
12436            } else {
12437                // Dumping a single activity?
12438                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12439                    pw.println("Bad activity command, or no activities match: " + cmd);
12440                    pw.println("Use -h for help.");
12441                }
12442            }
12443            if (!more) {
12444                Binder.restoreCallingIdentity(origId);
12445                return;
12446            }
12447        }
12448
12449        // No piece of data specified, dump everything.
12450        synchronized (this) {
12451            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12452            pw.println();
12453            if (dumpAll) {
12454                pw.println("-------------------------------------------------------------------------------");
12455            }
12456            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12457            pw.println();
12458            if (dumpAll) {
12459                pw.println("-------------------------------------------------------------------------------");
12460            }
12461            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12462            pw.println();
12463            if (dumpAll) {
12464                pw.println("-------------------------------------------------------------------------------");
12465            }
12466            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12467            pw.println();
12468            if (dumpAll) {
12469                pw.println("-------------------------------------------------------------------------------");
12470            }
12471            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12472            pw.println();
12473            if (dumpAll) {
12474                pw.println("-------------------------------------------------------------------------------");
12475            }
12476            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12477            pw.println();
12478            if (dumpAll) {
12479                pw.println("-------------------------------------------------------------------------------");
12480            }
12481            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12482        }
12483        Binder.restoreCallingIdentity(origId);
12484    }
12485
12486    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12487            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12488        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12489
12490        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12491                dumpPackage);
12492        boolean needSep = printedAnything;
12493
12494        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12495                dumpPackage, needSep, "  mFocusedActivity: ");
12496        if (printed) {
12497            printedAnything = true;
12498            needSep = false;
12499        }
12500
12501        if (dumpPackage == null) {
12502            if (needSep) {
12503                pw.println();
12504            }
12505            needSep = true;
12506            printedAnything = true;
12507            mStackSupervisor.dump(pw, "  ");
12508        }
12509
12510        if (!printedAnything) {
12511            pw.println("  (nothing)");
12512        }
12513    }
12514
12515    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12516            int opti, boolean dumpAll, String dumpPackage) {
12517        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12518
12519        boolean printedAnything = false;
12520
12521        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12522            boolean printedHeader = false;
12523
12524            final int N = mRecentTasks.size();
12525            for (int i=0; i<N; i++) {
12526                TaskRecord tr = mRecentTasks.get(i);
12527                if (dumpPackage != null) {
12528                    if (tr.realActivity == null ||
12529                            !dumpPackage.equals(tr.realActivity)) {
12530                        continue;
12531                    }
12532                }
12533                if (!printedHeader) {
12534                    pw.println("  Recent tasks:");
12535                    printedHeader = true;
12536                    printedAnything = true;
12537                }
12538                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12539                        pw.println(tr);
12540                if (dumpAll) {
12541                    mRecentTasks.get(i).dump(pw, "    ");
12542                }
12543            }
12544        }
12545
12546        if (!printedAnything) {
12547            pw.println("  (nothing)");
12548        }
12549    }
12550
12551    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12552            int opti, boolean dumpAll, String dumpPackage) {
12553        boolean needSep = false;
12554        boolean printedAnything = false;
12555        int numPers = 0;
12556
12557        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12558
12559        if (dumpAll) {
12560            final int NP = mProcessNames.getMap().size();
12561            for (int ip=0; ip<NP; ip++) {
12562                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12563                final int NA = procs.size();
12564                for (int ia=0; ia<NA; ia++) {
12565                    ProcessRecord r = procs.valueAt(ia);
12566                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12567                        continue;
12568                    }
12569                    if (!needSep) {
12570                        pw.println("  All known processes:");
12571                        needSep = true;
12572                        printedAnything = true;
12573                    }
12574                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12575                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12576                        pw.print(" "); pw.println(r);
12577                    r.dump(pw, "    ");
12578                    if (r.persistent) {
12579                        numPers++;
12580                    }
12581                }
12582            }
12583        }
12584
12585        if (mIsolatedProcesses.size() > 0) {
12586            boolean printed = false;
12587            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12588                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12589                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12590                    continue;
12591                }
12592                if (!printed) {
12593                    if (needSep) {
12594                        pw.println();
12595                    }
12596                    pw.println("  Isolated process list (sorted by uid):");
12597                    printedAnything = true;
12598                    printed = true;
12599                    needSep = true;
12600                }
12601                pw.println(String.format("%sIsolated #%2d: %s",
12602                        "    ", i, r.toString()));
12603            }
12604        }
12605
12606        if (mLruProcesses.size() > 0) {
12607            if (needSep) {
12608                pw.println();
12609            }
12610            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12611                    pw.print(" total, non-act at ");
12612                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12613                    pw.print(", non-svc at ");
12614                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12615                    pw.println("):");
12616            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12617            needSep = true;
12618            printedAnything = true;
12619        }
12620
12621        if (dumpAll || dumpPackage != null) {
12622            synchronized (mPidsSelfLocked) {
12623                boolean printed = false;
12624                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12625                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12626                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12627                        continue;
12628                    }
12629                    if (!printed) {
12630                        if (needSep) pw.println();
12631                        needSep = true;
12632                        pw.println("  PID mappings:");
12633                        printed = true;
12634                        printedAnything = true;
12635                    }
12636                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12637                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12638                }
12639            }
12640        }
12641
12642        if (mForegroundProcesses.size() > 0) {
12643            synchronized (mPidsSelfLocked) {
12644                boolean printed = false;
12645                for (int i=0; i<mForegroundProcesses.size(); i++) {
12646                    ProcessRecord r = mPidsSelfLocked.get(
12647                            mForegroundProcesses.valueAt(i).pid);
12648                    if (dumpPackage != null && (r == null
12649                            || !r.pkgList.containsKey(dumpPackage))) {
12650                        continue;
12651                    }
12652                    if (!printed) {
12653                        if (needSep) pw.println();
12654                        needSep = true;
12655                        pw.println("  Foreground Processes:");
12656                        printed = true;
12657                        printedAnything = true;
12658                    }
12659                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12660                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12661                }
12662            }
12663        }
12664
12665        if (mPersistentStartingProcesses.size() > 0) {
12666            if (needSep) pw.println();
12667            needSep = true;
12668            printedAnything = true;
12669            pw.println("  Persisent processes that are starting:");
12670            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12671                    "Starting Norm", "Restarting PERS", dumpPackage);
12672        }
12673
12674        if (mRemovedProcesses.size() > 0) {
12675            if (needSep) pw.println();
12676            needSep = true;
12677            printedAnything = true;
12678            pw.println("  Processes that are being removed:");
12679            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12680                    "Removed Norm", "Removed PERS", dumpPackage);
12681        }
12682
12683        if (mProcessesOnHold.size() > 0) {
12684            if (needSep) pw.println();
12685            needSep = true;
12686            printedAnything = true;
12687            pw.println("  Processes that are on old until the system is ready:");
12688            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12689                    "OnHold Norm", "OnHold PERS", dumpPackage);
12690        }
12691
12692        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12693
12694        if (mProcessCrashTimes.getMap().size() > 0) {
12695            boolean printed = false;
12696            long now = SystemClock.uptimeMillis();
12697            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12698            final int NP = pmap.size();
12699            for (int ip=0; ip<NP; ip++) {
12700                String pname = pmap.keyAt(ip);
12701                SparseArray<Long> uids = pmap.valueAt(ip);
12702                final int N = uids.size();
12703                for (int i=0; i<N; i++) {
12704                    int puid = uids.keyAt(i);
12705                    ProcessRecord r = mProcessNames.get(pname, puid);
12706                    if (dumpPackage != null && (r == null
12707                            || !r.pkgList.containsKey(dumpPackage))) {
12708                        continue;
12709                    }
12710                    if (!printed) {
12711                        if (needSep) pw.println();
12712                        needSep = true;
12713                        pw.println("  Time since processes crashed:");
12714                        printed = true;
12715                        printedAnything = true;
12716                    }
12717                    pw.print("    Process "); pw.print(pname);
12718                            pw.print(" uid "); pw.print(puid);
12719                            pw.print(": last crashed ");
12720                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12721                            pw.println(" ago");
12722                }
12723            }
12724        }
12725
12726        if (mBadProcesses.getMap().size() > 0) {
12727            boolean printed = false;
12728            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12729            final int NP = pmap.size();
12730            for (int ip=0; ip<NP; ip++) {
12731                String pname = pmap.keyAt(ip);
12732                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12733                final int N = uids.size();
12734                for (int i=0; i<N; i++) {
12735                    int puid = uids.keyAt(i);
12736                    ProcessRecord r = mProcessNames.get(pname, puid);
12737                    if (dumpPackage != null && (r == null
12738                            || !r.pkgList.containsKey(dumpPackage))) {
12739                        continue;
12740                    }
12741                    if (!printed) {
12742                        if (needSep) pw.println();
12743                        needSep = true;
12744                        pw.println("  Bad processes:");
12745                        printedAnything = true;
12746                    }
12747                    BadProcessInfo info = uids.valueAt(i);
12748                    pw.print("    Bad process "); pw.print(pname);
12749                            pw.print(" uid "); pw.print(puid);
12750                            pw.print(": crashed at time "); pw.println(info.time);
12751                    if (info.shortMsg != null) {
12752                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12753                    }
12754                    if (info.longMsg != null) {
12755                        pw.print("      Long msg: "); pw.println(info.longMsg);
12756                    }
12757                    if (info.stack != null) {
12758                        pw.println("      Stack:");
12759                        int lastPos = 0;
12760                        for (int pos=0; pos<info.stack.length(); pos++) {
12761                            if (info.stack.charAt(pos) == '\n') {
12762                                pw.print("        ");
12763                                pw.write(info.stack, lastPos, pos-lastPos);
12764                                pw.println();
12765                                lastPos = pos+1;
12766                            }
12767                        }
12768                        if (lastPos < info.stack.length()) {
12769                            pw.print("        ");
12770                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12771                            pw.println();
12772                        }
12773                    }
12774                }
12775            }
12776        }
12777
12778        if (dumpPackage == null) {
12779            pw.println();
12780            needSep = false;
12781            pw.println("  mStartedUsers:");
12782            for (int i=0; i<mStartedUsers.size(); i++) {
12783                UserStartedState uss = mStartedUsers.valueAt(i);
12784                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12785                        pw.print(": "); uss.dump("", pw);
12786            }
12787            pw.print("  mStartedUserArray: [");
12788            for (int i=0; i<mStartedUserArray.length; i++) {
12789                if (i > 0) pw.print(", ");
12790                pw.print(mStartedUserArray[i]);
12791            }
12792            pw.println("]");
12793            pw.print("  mUserLru: [");
12794            for (int i=0; i<mUserLru.size(); i++) {
12795                if (i > 0) pw.print(", ");
12796                pw.print(mUserLru.get(i));
12797            }
12798            pw.println("]");
12799            if (dumpAll) {
12800                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12801            }
12802            synchronized (mUserProfileGroupIdsSelfLocked) {
12803                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12804                    pw.println("  mUserProfileGroupIds:");
12805                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12806                        pw.print("    User #");
12807                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12808                        pw.print(" -> profile #");
12809                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12810                    }
12811                }
12812            }
12813        }
12814        if (mHomeProcess != null && (dumpPackage == null
12815                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12816            if (needSep) {
12817                pw.println();
12818                needSep = false;
12819            }
12820            pw.println("  mHomeProcess: " + mHomeProcess);
12821        }
12822        if (mPreviousProcess != null && (dumpPackage == null
12823                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12824            if (needSep) {
12825                pw.println();
12826                needSep = false;
12827            }
12828            pw.println("  mPreviousProcess: " + mPreviousProcess);
12829        }
12830        if (dumpAll) {
12831            StringBuilder sb = new StringBuilder(128);
12832            sb.append("  mPreviousProcessVisibleTime: ");
12833            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12834            pw.println(sb);
12835        }
12836        if (mHeavyWeightProcess != null && (dumpPackage == null
12837                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12838            if (needSep) {
12839                pw.println();
12840                needSep = false;
12841            }
12842            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12843        }
12844        if (dumpPackage == null) {
12845            pw.println("  mConfiguration: " + mConfiguration);
12846        }
12847        if (dumpAll) {
12848            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12849            if (mCompatModePackages.getPackages().size() > 0) {
12850                boolean printed = false;
12851                for (Map.Entry<String, Integer> entry
12852                        : mCompatModePackages.getPackages().entrySet()) {
12853                    String pkg = entry.getKey();
12854                    int mode = entry.getValue();
12855                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12856                        continue;
12857                    }
12858                    if (!printed) {
12859                        pw.println("  mScreenCompatPackages:");
12860                        printed = true;
12861                    }
12862                    pw.print("    "); pw.print(pkg); pw.print(": ");
12863                            pw.print(mode); pw.println();
12864                }
12865            }
12866        }
12867        if (dumpPackage == null) {
12868            if (mSleeping || mWentToSleep || mLockScreenShown) {
12869                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12870                        + " mLockScreenShown " + mLockScreenShown);
12871            }
12872            if (mShuttingDown || mRunningVoice) {
12873                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12874            }
12875        }
12876        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12877                || mOrigWaitForDebugger) {
12878            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12879                    || dumpPackage.equals(mOrigDebugApp)) {
12880                if (needSep) {
12881                    pw.println();
12882                    needSep = false;
12883                }
12884                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12885                        + " mDebugTransient=" + mDebugTransient
12886                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12887            }
12888        }
12889        if (mOpenGlTraceApp != null) {
12890            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12891                if (needSep) {
12892                    pw.println();
12893                    needSep = false;
12894                }
12895                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12896            }
12897        }
12898        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12899                || mProfileFd != null) {
12900            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12901                if (needSep) {
12902                    pw.println();
12903                    needSep = false;
12904                }
12905                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12906                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12907                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12908                        + mAutoStopProfiler);
12909                pw.println("  mProfileType=" + mProfileType);
12910            }
12911        }
12912        if (dumpPackage == null) {
12913            if (mAlwaysFinishActivities || mController != null) {
12914                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12915                        + " mController=" + mController);
12916            }
12917            if (dumpAll) {
12918                pw.println("  Total persistent processes: " + numPers);
12919                pw.println("  mProcessesReady=" + mProcessesReady
12920                        + " mSystemReady=" + mSystemReady
12921                        + " mBooted=" + mBooted
12922                        + " mFactoryTest=" + mFactoryTest);
12923                pw.println("  mBooting=" + mBooting
12924                        + " mCallFinishBooting=" + mCallFinishBooting
12925                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12926                pw.print("  mLastPowerCheckRealtime=");
12927                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12928                        pw.println("");
12929                pw.print("  mLastPowerCheckUptime=");
12930                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12931                        pw.println("");
12932                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12933                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12934                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12935                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12936                        + " (" + mLruProcesses.size() + " total)"
12937                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12938                        + " mNumServiceProcs=" + mNumServiceProcs
12939                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12940                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12941                        + " mLastMemoryLevel" + mLastMemoryLevel
12942                        + " mLastNumProcesses" + mLastNumProcesses);
12943                long now = SystemClock.uptimeMillis();
12944                pw.print("  mLastIdleTime=");
12945                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12946                        pw.print(" mLowRamSinceLastIdle=");
12947                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12948                        pw.println();
12949            }
12950        }
12951
12952        if (!printedAnything) {
12953            pw.println("  (nothing)");
12954        }
12955    }
12956
12957    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12958            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12959        if (mProcessesToGc.size() > 0) {
12960            boolean printed = false;
12961            long now = SystemClock.uptimeMillis();
12962            for (int i=0; i<mProcessesToGc.size(); i++) {
12963                ProcessRecord proc = mProcessesToGc.get(i);
12964                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12965                    continue;
12966                }
12967                if (!printed) {
12968                    if (needSep) pw.println();
12969                    needSep = true;
12970                    pw.println("  Processes that are waiting to GC:");
12971                    printed = true;
12972                }
12973                pw.print("    Process "); pw.println(proc);
12974                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12975                        pw.print(", last gced=");
12976                        pw.print(now-proc.lastRequestedGc);
12977                        pw.print(" ms ago, last lowMem=");
12978                        pw.print(now-proc.lastLowMemory);
12979                        pw.println(" ms ago");
12980
12981            }
12982        }
12983        return needSep;
12984    }
12985
12986    void printOomLevel(PrintWriter pw, String name, int adj) {
12987        pw.print("    ");
12988        if (adj >= 0) {
12989            pw.print(' ');
12990            if (adj < 10) pw.print(' ');
12991        } else {
12992            if (adj > -10) pw.print(' ');
12993        }
12994        pw.print(adj);
12995        pw.print(": ");
12996        pw.print(name);
12997        pw.print(" (");
12998        pw.print(mProcessList.getMemLevel(adj)/1024);
12999        pw.println(" kB)");
13000    }
13001
13002    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13003            int opti, boolean dumpAll) {
13004        boolean needSep = false;
13005
13006        if (mLruProcesses.size() > 0) {
13007            if (needSep) pw.println();
13008            needSep = true;
13009            pw.println("  OOM levels:");
13010            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13011            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13012            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13013            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13014            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13015            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13016            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13017            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13018            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13019            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13020            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13021            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13022            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13023
13024            if (needSep) pw.println();
13025            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13026                    pw.print(" total, non-act at ");
13027                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13028                    pw.print(", non-svc at ");
13029                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13030                    pw.println("):");
13031            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13032            needSep = true;
13033        }
13034
13035        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13036
13037        pw.println();
13038        pw.println("  mHomeProcess: " + mHomeProcess);
13039        pw.println("  mPreviousProcess: " + mPreviousProcess);
13040        if (mHeavyWeightProcess != null) {
13041            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13042        }
13043
13044        return true;
13045    }
13046
13047    /**
13048     * There are three ways to call this:
13049     *  - no provider specified: dump all the providers
13050     *  - a flattened component name that matched an existing provider was specified as the
13051     *    first arg: dump that one provider
13052     *  - the first arg isn't the flattened component name of an existing provider:
13053     *    dump all providers whose component contains the first arg as a substring
13054     */
13055    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13056            int opti, boolean dumpAll) {
13057        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13058    }
13059
13060    static class ItemMatcher {
13061        ArrayList<ComponentName> components;
13062        ArrayList<String> strings;
13063        ArrayList<Integer> objects;
13064        boolean all;
13065
13066        ItemMatcher() {
13067            all = true;
13068        }
13069
13070        void build(String name) {
13071            ComponentName componentName = ComponentName.unflattenFromString(name);
13072            if (componentName != null) {
13073                if (components == null) {
13074                    components = new ArrayList<ComponentName>();
13075                }
13076                components.add(componentName);
13077                all = false;
13078            } else {
13079                int objectId = 0;
13080                // Not a '/' separated full component name; maybe an object ID?
13081                try {
13082                    objectId = Integer.parseInt(name, 16);
13083                    if (objects == null) {
13084                        objects = new ArrayList<Integer>();
13085                    }
13086                    objects.add(objectId);
13087                    all = false;
13088                } catch (RuntimeException e) {
13089                    // Not an integer; just do string match.
13090                    if (strings == null) {
13091                        strings = new ArrayList<String>();
13092                    }
13093                    strings.add(name);
13094                    all = false;
13095                }
13096            }
13097        }
13098
13099        int build(String[] args, int opti) {
13100            for (; opti<args.length; opti++) {
13101                String name = args[opti];
13102                if ("--".equals(name)) {
13103                    return opti+1;
13104                }
13105                build(name);
13106            }
13107            return opti;
13108        }
13109
13110        boolean match(Object object, ComponentName comp) {
13111            if (all) {
13112                return true;
13113            }
13114            if (components != null) {
13115                for (int i=0; i<components.size(); i++) {
13116                    if (components.get(i).equals(comp)) {
13117                        return true;
13118                    }
13119                }
13120            }
13121            if (objects != null) {
13122                for (int i=0; i<objects.size(); i++) {
13123                    if (System.identityHashCode(object) == objects.get(i)) {
13124                        return true;
13125                    }
13126                }
13127            }
13128            if (strings != null) {
13129                String flat = comp.flattenToString();
13130                for (int i=0; i<strings.size(); i++) {
13131                    if (flat.contains(strings.get(i))) {
13132                        return true;
13133                    }
13134                }
13135            }
13136            return false;
13137        }
13138    }
13139
13140    /**
13141     * There are three things that cmd can be:
13142     *  - a flattened component name that matches an existing activity
13143     *  - the cmd arg isn't the flattened component name of an existing activity:
13144     *    dump all activity whose component contains the cmd as a substring
13145     *  - A hex number of the ActivityRecord object instance.
13146     */
13147    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13148            int opti, boolean dumpAll) {
13149        ArrayList<ActivityRecord> activities;
13150
13151        synchronized (this) {
13152            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13153        }
13154
13155        if (activities.size() <= 0) {
13156            return false;
13157        }
13158
13159        String[] newArgs = new String[args.length - opti];
13160        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13161
13162        TaskRecord lastTask = null;
13163        boolean needSep = false;
13164        for (int i=activities.size()-1; i>=0; i--) {
13165            ActivityRecord r = activities.get(i);
13166            if (needSep) {
13167                pw.println();
13168            }
13169            needSep = true;
13170            synchronized (this) {
13171                if (lastTask != r.task) {
13172                    lastTask = r.task;
13173                    pw.print("TASK "); pw.print(lastTask.affinity);
13174                            pw.print(" id="); pw.println(lastTask.taskId);
13175                    if (dumpAll) {
13176                        lastTask.dump(pw, "  ");
13177                    }
13178                }
13179            }
13180            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13181        }
13182        return true;
13183    }
13184
13185    /**
13186     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13187     * there is a thread associated with the activity.
13188     */
13189    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13190            final ActivityRecord r, String[] args, boolean dumpAll) {
13191        String innerPrefix = prefix + "  ";
13192        synchronized (this) {
13193            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13194                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13195                    pw.print(" pid=");
13196                    if (r.app != null) pw.println(r.app.pid);
13197                    else pw.println("(not running)");
13198            if (dumpAll) {
13199                r.dump(pw, innerPrefix);
13200            }
13201        }
13202        if (r.app != null && r.app.thread != null) {
13203            // flush anything that is already in the PrintWriter since the thread is going
13204            // to write to the file descriptor directly
13205            pw.flush();
13206            try {
13207                TransferPipe tp = new TransferPipe();
13208                try {
13209                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13210                            r.appToken, innerPrefix, args);
13211                    tp.go(fd);
13212                } finally {
13213                    tp.kill();
13214                }
13215            } catch (IOException e) {
13216                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13217            } catch (RemoteException e) {
13218                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13219            }
13220        }
13221    }
13222
13223    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13224            int opti, boolean dumpAll, String dumpPackage) {
13225        boolean needSep = false;
13226        boolean onlyHistory = false;
13227        boolean printedAnything = false;
13228
13229        if ("history".equals(dumpPackage)) {
13230            if (opti < args.length && "-s".equals(args[opti])) {
13231                dumpAll = false;
13232            }
13233            onlyHistory = true;
13234            dumpPackage = null;
13235        }
13236
13237        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13238        if (!onlyHistory && dumpAll) {
13239            if (mRegisteredReceivers.size() > 0) {
13240                boolean printed = false;
13241                Iterator it = mRegisteredReceivers.values().iterator();
13242                while (it.hasNext()) {
13243                    ReceiverList r = (ReceiverList)it.next();
13244                    if (dumpPackage != null && (r.app == null ||
13245                            !dumpPackage.equals(r.app.info.packageName))) {
13246                        continue;
13247                    }
13248                    if (!printed) {
13249                        pw.println("  Registered Receivers:");
13250                        needSep = true;
13251                        printed = true;
13252                        printedAnything = true;
13253                    }
13254                    pw.print("  * "); pw.println(r);
13255                    r.dump(pw, "    ");
13256                }
13257            }
13258
13259            if (mReceiverResolver.dump(pw, needSep ?
13260                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13261                    "    ", dumpPackage, false)) {
13262                needSep = true;
13263                printedAnything = true;
13264            }
13265        }
13266
13267        for (BroadcastQueue q : mBroadcastQueues) {
13268            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13269            printedAnything |= needSep;
13270        }
13271
13272        needSep = true;
13273
13274        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13275            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13276                if (needSep) {
13277                    pw.println();
13278                }
13279                needSep = true;
13280                printedAnything = true;
13281                pw.print("  Sticky broadcasts for user ");
13282                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13283                StringBuilder sb = new StringBuilder(128);
13284                for (Map.Entry<String, ArrayList<Intent>> ent
13285                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13286                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13287                    if (dumpAll) {
13288                        pw.println(":");
13289                        ArrayList<Intent> intents = ent.getValue();
13290                        final int N = intents.size();
13291                        for (int i=0; i<N; i++) {
13292                            sb.setLength(0);
13293                            sb.append("    Intent: ");
13294                            intents.get(i).toShortString(sb, false, true, false, false);
13295                            pw.println(sb.toString());
13296                            Bundle bundle = intents.get(i).getExtras();
13297                            if (bundle != null) {
13298                                pw.print("      ");
13299                                pw.println(bundle.toString());
13300                            }
13301                        }
13302                    } else {
13303                        pw.println("");
13304                    }
13305                }
13306            }
13307        }
13308
13309        if (!onlyHistory && dumpAll) {
13310            pw.println();
13311            for (BroadcastQueue queue : mBroadcastQueues) {
13312                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13313                        + queue.mBroadcastsScheduled);
13314            }
13315            pw.println("  mHandler:");
13316            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13317            needSep = true;
13318            printedAnything = true;
13319        }
13320
13321        if (!printedAnything) {
13322            pw.println("  (nothing)");
13323        }
13324    }
13325
13326    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13327            int opti, boolean dumpAll, String dumpPackage) {
13328        boolean needSep;
13329        boolean printedAnything = false;
13330
13331        ItemMatcher matcher = new ItemMatcher();
13332        matcher.build(args, opti);
13333
13334        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13335
13336        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13337        printedAnything |= needSep;
13338
13339        if (mLaunchingProviders.size() > 0) {
13340            boolean printed = false;
13341            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13342                ContentProviderRecord r = mLaunchingProviders.get(i);
13343                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13344                    continue;
13345                }
13346                if (!printed) {
13347                    if (needSep) pw.println();
13348                    needSep = true;
13349                    pw.println("  Launching content providers:");
13350                    printed = true;
13351                    printedAnything = true;
13352                }
13353                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13354                        pw.println(r);
13355            }
13356        }
13357
13358        if (mGrantedUriPermissions.size() > 0) {
13359            boolean printed = false;
13360            int dumpUid = -2;
13361            if (dumpPackage != null) {
13362                try {
13363                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13364                } catch (NameNotFoundException e) {
13365                    dumpUid = -1;
13366                }
13367            }
13368            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13369                int uid = mGrantedUriPermissions.keyAt(i);
13370                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13371                    continue;
13372                }
13373                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13374                if (!printed) {
13375                    if (needSep) pw.println();
13376                    needSep = true;
13377                    pw.println("  Granted Uri Permissions:");
13378                    printed = true;
13379                    printedAnything = true;
13380                }
13381                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13382                for (UriPermission perm : perms.values()) {
13383                    pw.print("    "); pw.println(perm);
13384                    if (dumpAll) {
13385                        perm.dump(pw, "      ");
13386                    }
13387                }
13388            }
13389        }
13390
13391        if (!printedAnything) {
13392            pw.println("  (nothing)");
13393        }
13394    }
13395
13396    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13397            int opti, boolean dumpAll, String dumpPackage) {
13398        boolean printed = false;
13399
13400        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13401
13402        if (mIntentSenderRecords.size() > 0) {
13403            Iterator<WeakReference<PendingIntentRecord>> it
13404                    = mIntentSenderRecords.values().iterator();
13405            while (it.hasNext()) {
13406                WeakReference<PendingIntentRecord> ref = it.next();
13407                PendingIntentRecord rec = ref != null ? ref.get(): null;
13408                if (dumpPackage != null && (rec == null
13409                        || !dumpPackage.equals(rec.key.packageName))) {
13410                    continue;
13411                }
13412                printed = true;
13413                if (rec != null) {
13414                    pw.print("  * "); pw.println(rec);
13415                    if (dumpAll) {
13416                        rec.dump(pw, "    ");
13417                    }
13418                } else {
13419                    pw.print("  * "); pw.println(ref);
13420                }
13421            }
13422        }
13423
13424        if (!printed) {
13425            pw.println("  (nothing)");
13426        }
13427    }
13428
13429    private static final int dumpProcessList(PrintWriter pw,
13430            ActivityManagerService service, List list,
13431            String prefix, String normalLabel, String persistentLabel,
13432            String dumpPackage) {
13433        int numPers = 0;
13434        final int N = list.size()-1;
13435        for (int i=N; i>=0; i--) {
13436            ProcessRecord r = (ProcessRecord)list.get(i);
13437            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13438                continue;
13439            }
13440            pw.println(String.format("%s%s #%2d: %s",
13441                    prefix, (r.persistent ? persistentLabel : normalLabel),
13442                    i, r.toString()));
13443            if (r.persistent) {
13444                numPers++;
13445            }
13446        }
13447        return numPers;
13448    }
13449
13450    private static final boolean dumpProcessOomList(PrintWriter pw,
13451            ActivityManagerService service, List<ProcessRecord> origList,
13452            String prefix, String normalLabel, String persistentLabel,
13453            boolean inclDetails, String dumpPackage) {
13454
13455        ArrayList<Pair<ProcessRecord, Integer>> list
13456                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13457        for (int i=0; i<origList.size(); i++) {
13458            ProcessRecord r = origList.get(i);
13459            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13460                continue;
13461            }
13462            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13463        }
13464
13465        if (list.size() <= 0) {
13466            return false;
13467        }
13468
13469        Comparator<Pair<ProcessRecord, Integer>> comparator
13470                = new Comparator<Pair<ProcessRecord, Integer>>() {
13471            @Override
13472            public int compare(Pair<ProcessRecord, Integer> object1,
13473                    Pair<ProcessRecord, Integer> object2) {
13474                if (object1.first.setAdj != object2.first.setAdj) {
13475                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13476                }
13477                if (object1.second.intValue() != object2.second.intValue()) {
13478                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13479                }
13480                return 0;
13481            }
13482        };
13483
13484        Collections.sort(list, comparator);
13485
13486        final long curRealtime = SystemClock.elapsedRealtime();
13487        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13488        final long curUptime = SystemClock.uptimeMillis();
13489        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13490
13491        for (int i=list.size()-1; i>=0; i--) {
13492            ProcessRecord r = list.get(i).first;
13493            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13494            char schedGroup;
13495            switch (r.setSchedGroup) {
13496                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13497                    schedGroup = 'B';
13498                    break;
13499                case Process.THREAD_GROUP_DEFAULT:
13500                    schedGroup = 'F';
13501                    break;
13502                default:
13503                    schedGroup = '?';
13504                    break;
13505            }
13506            char foreground;
13507            if (r.foregroundActivities) {
13508                foreground = 'A';
13509            } else if (r.foregroundServices) {
13510                foreground = 'S';
13511            } else {
13512                foreground = ' ';
13513            }
13514            String procState = ProcessList.makeProcStateString(r.curProcState);
13515            pw.print(prefix);
13516            pw.print(r.persistent ? persistentLabel : normalLabel);
13517            pw.print(" #");
13518            int num = (origList.size()-1)-list.get(i).second;
13519            if (num < 10) pw.print(' ');
13520            pw.print(num);
13521            pw.print(": ");
13522            pw.print(oomAdj);
13523            pw.print(' ');
13524            pw.print(schedGroup);
13525            pw.print('/');
13526            pw.print(foreground);
13527            pw.print('/');
13528            pw.print(procState);
13529            pw.print(" trm:");
13530            if (r.trimMemoryLevel < 10) pw.print(' ');
13531            pw.print(r.trimMemoryLevel);
13532            pw.print(' ');
13533            pw.print(r.toShortString());
13534            pw.print(" (");
13535            pw.print(r.adjType);
13536            pw.println(')');
13537            if (r.adjSource != null || r.adjTarget != null) {
13538                pw.print(prefix);
13539                pw.print("    ");
13540                if (r.adjTarget instanceof ComponentName) {
13541                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13542                } else if (r.adjTarget != null) {
13543                    pw.print(r.adjTarget.toString());
13544                } else {
13545                    pw.print("{null}");
13546                }
13547                pw.print("<=");
13548                if (r.adjSource instanceof ProcessRecord) {
13549                    pw.print("Proc{");
13550                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13551                    pw.println("}");
13552                } else if (r.adjSource != null) {
13553                    pw.println(r.adjSource.toString());
13554                } else {
13555                    pw.println("{null}");
13556                }
13557            }
13558            if (inclDetails) {
13559                pw.print(prefix);
13560                pw.print("    ");
13561                pw.print("oom: max="); pw.print(r.maxAdj);
13562                pw.print(" curRaw="); pw.print(r.curRawAdj);
13563                pw.print(" setRaw="); pw.print(r.setRawAdj);
13564                pw.print(" cur="); pw.print(r.curAdj);
13565                pw.print(" set="); pw.println(r.setAdj);
13566                pw.print(prefix);
13567                pw.print("    ");
13568                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13569                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13570                pw.print(" lastPss="); pw.print(r.lastPss);
13571                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13572                pw.print(prefix);
13573                pw.print("    ");
13574                pw.print("cached="); pw.print(r.cached);
13575                pw.print(" empty="); pw.print(r.empty);
13576                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13577
13578                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13579                    if (r.lastWakeTime != 0) {
13580                        long wtime;
13581                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13582                        synchronized (stats) {
13583                            wtime = stats.getProcessWakeTime(r.info.uid,
13584                                    r.pid, curRealtime);
13585                        }
13586                        long timeUsed = wtime - r.lastWakeTime;
13587                        pw.print(prefix);
13588                        pw.print("    ");
13589                        pw.print("keep awake over ");
13590                        TimeUtils.formatDuration(realtimeSince, pw);
13591                        pw.print(" used ");
13592                        TimeUtils.formatDuration(timeUsed, pw);
13593                        pw.print(" (");
13594                        pw.print((timeUsed*100)/realtimeSince);
13595                        pw.println("%)");
13596                    }
13597                    if (r.lastCpuTime != 0) {
13598                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13599                        pw.print(prefix);
13600                        pw.print("    ");
13601                        pw.print("run cpu over ");
13602                        TimeUtils.formatDuration(uptimeSince, pw);
13603                        pw.print(" used ");
13604                        TimeUtils.formatDuration(timeUsed, pw);
13605                        pw.print(" (");
13606                        pw.print((timeUsed*100)/uptimeSince);
13607                        pw.println("%)");
13608                    }
13609                }
13610            }
13611        }
13612        return true;
13613    }
13614
13615    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13616        ArrayList<ProcessRecord> procs;
13617        synchronized (this) {
13618            if (args != null && args.length > start
13619                    && args[start].charAt(0) != '-') {
13620                procs = new ArrayList<ProcessRecord>();
13621                int pid = -1;
13622                try {
13623                    pid = Integer.parseInt(args[start]);
13624                } catch (NumberFormatException e) {
13625                }
13626                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13627                    ProcessRecord proc = mLruProcesses.get(i);
13628                    if (proc.pid == pid) {
13629                        procs.add(proc);
13630                    } else if (proc.processName.equals(args[start])) {
13631                        procs.add(proc);
13632                    }
13633                }
13634                if (procs.size() <= 0) {
13635                    return null;
13636                }
13637            } else {
13638                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13639            }
13640        }
13641        return procs;
13642    }
13643
13644    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13645            PrintWriter pw, String[] args) {
13646        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13647        if (procs == null) {
13648            pw.println("No process found for: " + args[0]);
13649            return;
13650        }
13651
13652        long uptime = SystemClock.uptimeMillis();
13653        long realtime = SystemClock.elapsedRealtime();
13654        pw.println("Applications Graphics Acceleration Info:");
13655        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13656
13657        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13658            ProcessRecord r = procs.get(i);
13659            if (r.thread != null) {
13660                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13661                pw.flush();
13662                try {
13663                    TransferPipe tp = new TransferPipe();
13664                    try {
13665                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13666                        tp.go(fd);
13667                    } finally {
13668                        tp.kill();
13669                    }
13670                } catch (IOException e) {
13671                    pw.println("Failure while dumping the app: " + r);
13672                    pw.flush();
13673                } catch (RemoteException e) {
13674                    pw.println("Got a RemoteException while dumping the app " + r);
13675                    pw.flush();
13676                }
13677            }
13678        }
13679    }
13680
13681    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13682        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13683        if (procs == null) {
13684            pw.println("No process found for: " + args[0]);
13685            return;
13686        }
13687
13688        pw.println("Applications Database Info:");
13689
13690        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13691            ProcessRecord r = procs.get(i);
13692            if (r.thread != null) {
13693                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13694                pw.flush();
13695                try {
13696                    TransferPipe tp = new TransferPipe();
13697                    try {
13698                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13699                        tp.go(fd);
13700                    } finally {
13701                        tp.kill();
13702                    }
13703                } catch (IOException e) {
13704                    pw.println("Failure while dumping the app: " + r);
13705                    pw.flush();
13706                } catch (RemoteException e) {
13707                    pw.println("Got a RemoteException while dumping the app " + r);
13708                    pw.flush();
13709                }
13710            }
13711        }
13712    }
13713
13714    final static class MemItem {
13715        final boolean isProc;
13716        final String label;
13717        final String shortLabel;
13718        final long pss;
13719        final int id;
13720        final boolean hasActivities;
13721        ArrayList<MemItem> subitems;
13722
13723        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13724                boolean _hasActivities) {
13725            isProc = true;
13726            label = _label;
13727            shortLabel = _shortLabel;
13728            pss = _pss;
13729            id = _id;
13730            hasActivities = _hasActivities;
13731        }
13732
13733        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13734            isProc = false;
13735            label = _label;
13736            shortLabel = _shortLabel;
13737            pss = _pss;
13738            id = _id;
13739            hasActivities = false;
13740        }
13741    }
13742
13743    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13744            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13745        if (sort && !isCompact) {
13746            Collections.sort(items, new Comparator<MemItem>() {
13747                @Override
13748                public int compare(MemItem lhs, MemItem rhs) {
13749                    if (lhs.pss < rhs.pss) {
13750                        return 1;
13751                    } else if (lhs.pss > rhs.pss) {
13752                        return -1;
13753                    }
13754                    return 0;
13755                }
13756            });
13757        }
13758
13759        for (int i=0; i<items.size(); i++) {
13760            MemItem mi = items.get(i);
13761            if (!isCompact) {
13762                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13763            } else if (mi.isProc) {
13764                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13765                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13766                pw.println(mi.hasActivities ? ",a" : ",e");
13767            } else {
13768                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13769                pw.println(mi.pss);
13770            }
13771            if (mi.subitems != null) {
13772                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13773                        true, isCompact);
13774            }
13775        }
13776    }
13777
13778    // These are in KB.
13779    static final long[] DUMP_MEM_BUCKETS = new long[] {
13780        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13781        120*1024, 160*1024, 200*1024,
13782        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13783        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13784    };
13785
13786    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13787            boolean stackLike) {
13788        int start = label.lastIndexOf('.');
13789        if (start >= 0) start++;
13790        else start = 0;
13791        int end = label.length();
13792        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13793            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13794                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13795                out.append(bucket);
13796                out.append(stackLike ? "MB." : "MB ");
13797                out.append(label, start, end);
13798                return;
13799            }
13800        }
13801        out.append(memKB/1024);
13802        out.append(stackLike ? "MB." : "MB ");
13803        out.append(label, start, end);
13804    }
13805
13806    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13807            ProcessList.NATIVE_ADJ,
13808            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13809            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13810            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13811            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13812            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13813    };
13814    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13815            "Native",
13816            "System", "Persistent", "Foreground",
13817            "Visible", "Perceptible",
13818            "Heavy Weight", "Backup",
13819            "A Services", "Home",
13820            "Previous", "B Services", "Cached"
13821    };
13822    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13823            "native",
13824            "sys", "pers", "fore",
13825            "vis", "percept",
13826            "heavy", "backup",
13827            "servicea", "home",
13828            "prev", "serviceb", "cached"
13829    };
13830
13831    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13832            long realtime, boolean isCheckinRequest, boolean isCompact) {
13833        if (isCheckinRequest || isCompact) {
13834            // short checkin version
13835            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13836        } else {
13837            pw.println("Applications Memory Usage (kB):");
13838            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13839        }
13840    }
13841
13842    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13843            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13844        boolean dumpDetails = false;
13845        boolean dumpFullDetails = false;
13846        boolean dumpDalvik = false;
13847        boolean oomOnly = false;
13848        boolean isCompact = false;
13849        boolean localOnly = false;
13850
13851        int opti = 0;
13852        while (opti < args.length) {
13853            String opt = args[opti];
13854            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13855                break;
13856            }
13857            opti++;
13858            if ("-a".equals(opt)) {
13859                dumpDetails = true;
13860                dumpFullDetails = true;
13861                dumpDalvik = true;
13862            } else if ("-d".equals(opt)) {
13863                dumpDalvik = true;
13864            } else if ("-c".equals(opt)) {
13865                isCompact = true;
13866            } else if ("--oom".equals(opt)) {
13867                oomOnly = true;
13868            } else if ("--local".equals(opt)) {
13869                localOnly = true;
13870            } else if ("-h".equals(opt)) {
13871                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13872                pw.println("  -a: include all available information for each process.");
13873                pw.println("  -d: include dalvik details when dumping process details.");
13874                pw.println("  -c: dump in a compact machine-parseable representation.");
13875                pw.println("  --oom: only show processes organized by oom adj.");
13876                pw.println("  --local: only collect details locally, don't call process.");
13877                pw.println("If [process] is specified it can be the name or ");
13878                pw.println("pid of a specific process to dump.");
13879                return;
13880            } else {
13881                pw.println("Unknown argument: " + opt + "; use -h for help");
13882            }
13883        }
13884
13885        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13886        long uptime = SystemClock.uptimeMillis();
13887        long realtime = SystemClock.elapsedRealtime();
13888        final long[] tmpLong = new long[1];
13889
13890        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13891        if (procs == null) {
13892            // No Java processes.  Maybe they want to print a native process.
13893            if (args != null && args.length > opti
13894                    && args[opti].charAt(0) != '-') {
13895                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13896                        = new ArrayList<ProcessCpuTracker.Stats>();
13897                updateCpuStatsNow();
13898                int findPid = -1;
13899                try {
13900                    findPid = Integer.parseInt(args[opti]);
13901                } catch (NumberFormatException e) {
13902                }
13903                synchronized (mProcessCpuTracker) {
13904                    final int N = mProcessCpuTracker.countStats();
13905                    for (int i=0; i<N; i++) {
13906                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13907                        if (st.pid == findPid || (st.baseName != null
13908                                && st.baseName.equals(args[opti]))) {
13909                            nativeProcs.add(st);
13910                        }
13911                    }
13912                }
13913                if (nativeProcs.size() > 0) {
13914                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13915                            isCompact);
13916                    Debug.MemoryInfo mi = null;
13917                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13918                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13919                        final int pid = r.pid;
13920                        if (!isCheckinRequest && dumpDetails) {
13921                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13922                        }
13923                        if (mi == null) {
13924                            mi = new Debug.MemoryInfo();
13925                        }
13926                        if (dumpDetails || (!brief && !oomOnly)) {
13927                            Debug.getMemoryInfo(pid, mi);
13928                        } else {
13929                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13930                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13931                        }
13932                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13933                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13934                        if (isCheckinRequest) {
13935                            pw.println();
13936                        }
13937                    }
13938                    return;
13939                }
13940            }
13941            pw.println("No process found for: " + args[opti]);
13942            return;
13943        }
13944
13945        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13946            dumpDetails = true;
13947        }
13948
13949        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13950
13951        String[] innerArgs = new String[args.length-opti];
13952        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13953
13954        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13955        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13956        long nativePss=0, dalvikPss=0, otherPss=0;
13957        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13958
13959        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13960        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13961                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13962
13963        long totalPss = 0;
13964        long cachedPss = 0;
13965
13966        Debug.MemoryInfo mi = null;
13967        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13968            final ProcessRecord r = procs.get(i);
13969            final IApplicationThread thread;
13970            final int pid;
13971            final int oomAdj;
13972            final boolean hasActivities;
13973            synchronized (this) {
13974                thread = r.thread;
13975                pid = r.pid;
13976                oomAdj = r.getSetAdjWithServices();
13977                hasActivities = r.activities.size() > 0;
13978            }
13979            if (thread != null) {
13980                if (!isCheckinRequest && dumpDetails) {
13981                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13982                }
13983                if (mi == null) {
13984                    mi = new Debug.MemoryInfo();
13985                }
13986                if (dumpDetails || (!brief && !oomOnly)) {
13987                    Debug.getMemoryInfo(pid, mi);
13988                } else {
13989                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13990                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13991                }
13992                if (dumpDetails) {
13993                    if (localOnly) {
13994                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13995                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13996                        if (isCheckinRequest) {
13997                            pw.println();
13998                        }
13999                    } else {
14000                        try {
14001                            pw.flush();
14002                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14003                                    dumpDalvik, innerArgs);
14004                        } catch (RemoteException e) {
14005                            if (!isCheckinRequest) {
14006                                pw.println("Got RemoteException!");
14007                                pw.flush();
14008                            }
14009                        }
14010                    }
14011                }
14012
14013                final long myTotalPss = mi.getTotalPss();
14014                final long myTotalUss = mi.getTotalUss();
14015
14016                synchronized (this) {
14017                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14018                        // Record this for posterity if the process has been stable.
14019                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14020                    }
14021                }
14022
14023                if (!isCheckinRequest && mi != null) {
14024                    totalPss += myTotalPss;
14025                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14026                            (hasActivities ? " / activities)" : ")"),
14027                            r.processName, myTotalPss, pid, hasActivities);
14028                    procMems.add(pssItem);
14029                    procMemsMap.put(pid, pssItem);
14030
14031                    nativePss += mi.nativePss;
14032                    dalvikPss += mi.dalvikPss;
14033                    otherPss += mi.otherPss;
14034                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14035                        long mem = mi.getOtherPss(j);
14036                        miscPss[j] += mem;
14037                        otherPss -= mem;
14038                    }
14039
14040                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14041                        cachedPss += myTotalPss;
14042                    }
14043
14044                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14045                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14046                                || oomIndex == (oomPss.length-1)) {
14047                            oomPss[oomIndex] += myTotalPss;
14048                            if (oomProcs[oomIndex] == null) {
14049                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14050                            }
14051                            oomProcs[oomIndex].add(pssItem);
14052                            break;
14053                        }
14054                    }
14055                }
14056            }
14057        }
14058
14059        long nativeProcTotalPss = 0;
14060
14061        if (!isCheckinRequest && procs.size() > 1) {
14062            // If we are showing aggregations, also look for native processes to
14063            // include so that our aggregations are more accurate.
14064            updateCpuStatsNow();
14065            synchronized (mProcessCpuTracker) {
14066                final int N = mProcessCpuTracker.countStats();
14067                for (int i=0; i<N; i++) {
14068                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14069                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14070                        if (mi == null) {
14071                            mi = new Debug.MemoryInfo();
14072                        }
14073                        if (!brief && !oomOnly) {
14074                            Debug.getMemoryInfo(st.pid, mi);
14075                        } else {
14076                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14077                            mi.nativePrivateDirty = (int)tmpLong[0];
14078                        }
14079
14080                        final long myTotalPss = mi.getTotalPss();
14081                        totalPss += myTotalPss;
14082                        nativeProcTotalPss += myTotalPss;
14083
14084                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14085                                st.name, myTotalPss, st.pid, false);
14086                        procMems.add(pssItem);
14087
14088                        nativePss += mi.nativePss;
14089                        dalvikPss += mi.dalvikPss;
14090                        otherPss += mi.otherPss;
14091                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14092                            long mem = mi.getOtherPss(j);
14093                            miscPss[j] += mem;
14094                            otherPss -= mem;
14095                        }
14096                        oomPss[0] += myTotalPss;
14097                        if (oomProcs[0] == null) {
14098                            oomProcs[0] = new ArrayList<MemItem>();
14099                        }
14100                        oomProcs[0].add(pssItem);
14101                    }
14102                }
14103            }
14104
14105            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14106
14107            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14108            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14109            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14110            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14111                String label = Debug.MemoryInfo.getOtherLabel(j);
14112                catMems.add(new MemItem(label, label, miscPss[j], j));
14113            }
14114
14115            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14116            for (int j=0; j<oomPss.length; j++) {
14117                if (oomPss[j] != 0) {
14118                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14119                            : DUMP_MEM_OOM_LABEL[j];
14120                    MemItem item = new MemItem(label, label, oomPss[j],
14121                            DUMP_MEM_OOM_ADJ[j]);
14122                    item.subitems = oomProcs[j];
14123                    oomMems.add(item);
14124                }
14125            }
14126
14127            if (!brief && !oomOnly && !isCompact) {
14128                pw.println();
14129                pw.println("Total PSS by process:");
14130                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14131                pw.println();
14132            }
14133            if (!isCompact) {
14134                pw.println("Total PSS by OOM adjustment:");
14135            }
14136            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14137            if (!brief && !oomOnly) {
14138                PrintWriter out = categoryPw != null ? categoryPw : pw;
14139                if (!isCompact) {
14140                    out.println();
14141                    out.println("Total PSS by category:");
14142                }
14143                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14144            }
14145            if (!isCompact) {
14146                pw.println();
14147            }
14148            MemInfoReader memInfo = new MemInfoReader();
14149            memInfo.readMemInfo();
14150            if (nativeProcTotalPss > 0) {
14151                synchronized (this) {
14152                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14153                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14154                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14155                            nativeProcTotalPss);
14156                }
14157            }
14158            if (!brief) {
14159                if (!isCompact) {
14160                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14161                    pw.print(" kB (status ");
14162                    switch (mLastMemoryLevel) {
14163                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14164                            pw.println("normal)");
14165                            break;
14166                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14167                            pw.println("moderate)");
14168                            break;
14169                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14170                            pw.println("low)");
14171                            break;
14172                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14173                            pw.println("critical)");
14174                            break;
14175                        default:
14176                            pw.print(mLastMemoryLevel);
14177                            pw.println(")");
14178                            break;
14179                    }
14180                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14181                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14182                            pw.print(cachedPss); pw.print(" cached pss + ");
14183                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14184                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14185                } else {
14186                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14187                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14188                            + memInfo.getFreeSizeKb()); pw.print(",");
14189                    pw.println(totalPss - cachedPss);
14190                }
14191            }
14192            if (!isCompact) {
14193                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14194                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14195                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14196                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14197                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14198                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14199                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14200                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14201                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14202                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14203                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14204            }
14205            if (!brief) {
14206                if (memInfo.getZramTotalSizeKb() != 0) {
14207                    if (!isCompact) {
14208                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14209                                pw.print(" kB physical used for ");
14210                                pw.print(memInfo.getSwapTotalSizeKb()
14211                                        - memInfo.getSwapFreeSizeKb());
14212                                pw.print(" kB in swap (");
14213                                pw.print(memInfo.getSwapTotalSizeKb());
14214                                pw.println(" kB total swap)");
14215                    } else {
14216                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14217                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14218                                pw.println(memInfo.getSwapFreeSizeKb());
14219                    }
14220                }
14221                final int[] SINGLE_LONG_FORMAT = new int[] {
14222                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14223                };
14224                long[] longOut = new long[1];
14225                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14226                        SINGLE_LONG_FORMAT, null, longOut, null);
14227                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14228                longOut[0] = 0;
14229                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14230                        SINGLE_LONG_FORMAT, null, longOut, null);
14231                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14232                longOut[0] = 0;
14233                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14234                        SINGLE_LONG_FORMAT, null, longOut, null);
14235                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14236                longOut[0] = 0;
14237                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14238                        SINGLE_LONG_FORMAT, null, longOut, null);
14239                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14240                if (!isCompact) {
14241                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14242                        pw.print("      KSM: "); pw.print(sharing);
14243                                pw.print(" kB saved from shared ");
14244                                pw.print(shared); pw.println(" kB");
14245                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14246                                pw.print(voltile); pw.println(" kB volatile");
14247                    }
14248                    pw.print("   Tuning: ");
14249                    pw.print(ActivityManager.staticGetMemoryClass());
14250                    pw.print(" (large ");
14251                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14252                    pw.print("), oom ");
14253                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14254                    pw.print(" kB");
14255                    pw.print(", restore limit ");
14256                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14257                    pw.print(" kB");
14258                    if (ActivityManager.isLowRamDeviceStatic()) {
14259                        pw.print(" (low-ram)");
14260                    }
14261                    if (ActivityManager.isHighEndGfx()) {
14262                        pw.print(" (high-end-gfx)");
14263                    }
14264                    pw.println();
14265                } else {
14266                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14267                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14268                    pw.println(voltile);
14269                    pw.print("tuning,");
14270                    pw.print(ActivityManager.staticGetMemoryClass());
14271                    pw.print(',');
14272                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14273                    pw.print(',');
14274                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14275                    if (ActivityManager.isLowRamDeviceStatic()) {
14276                        pw.print(",low-ram");
14277                    }
14278                    if (ActivityManager.isHighEndGfx()) {
14279                        pw.print(",high-end-gfx");
14280                    }
14281                    pw.println();
14282                }
14283            }
14284        }
14285    }
14286
14287    /**
14288     * Searches array of arguments for the specified string
14289     * @param args array of argument strings
14290     * @param value value to search for
14291     * @return true if the value is contained in the array
14292     */
14293    private static boolean scanArgs(String[] args, String value) {
14294        if (args != null) {
14295            for (String arg : args) {
14296                if (value.equals(arg)) {
14297                    return true;
14298                }
14299            }
14300        }
14301        return false;
14302    }
14303
14304    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14305            ContentProviderRecord cpr, boolean always) {
14306        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14307
14308        if (!inLaunching || always) {
14309            synchronized (cpr) {
14310                cpr.launchingApp = null;
14311                cpr.notifyAll();
14312            }
14313            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14314            String names[] = cpr.info.authority.split(";");
14315            for (int j = 0; j < names.length; j++) {
14316                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14317            }
14318        }
14319
14320        for (int i=0; i<cpr.connections.size(); i++) {
14321            ContentProviderConnection conn = cpr.connections.get(i);
14322            if (conn.waiting) {
14323                // If this connection is waiting for the provider, then we don't
14324                // need to mess with its process unless we are always removing
14325                // or for some reason the provider is not currently launching.
14326                if (inLaunching && !always) {
14327                    continue;
14328                }
14329            }
14330            ProcessRecord capp = conn.client;
14331            conn.dead = true;
14332            if (conn.stableCount > 0) {
14333                if (!capp.persistent && capp.thread != null
14334                        && capp.pid != 0
14335                        && capp.pid != MY_PID) {
14336                    capp.kill("depends on provider "
14337                            + cpr.name.flattenToShortString()
14338                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14339                }
14340            } else if (capp.thread != null && conn.provider.provider != null) {
14341                try {
14342                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14343                } catch (RemoteException e) {
14344                }
14345                // In the protocol here, we don't expect the client to correctly
14346                // clean up this connection, we'll just remove it.
14347                cpr.connections.remove(i);
14348                conn.client.conProviders.remove(conn);
14349            }
14350        }
14351
14352        if (inLaunching && always) {
14353            mLaunchingProviders.remove(cpr);
14354        }
14355        return inLaunching;
14356    }
14357
14358    /**
14359     * Main code for cleaning up a process when it has gone away.  This is
14360     * called both as a result of the process dying, or directly when stopping
14361     * a process when running in single process mode.
14362     *
14363     * @return Returns true if the given process has been restarted, so the
14364     * app that was passed in must remain on the process lists.
14365     */
14366    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14367            boolean restarting, boolean allowRestart, int index) {
14368        if (index >= 0) {
14369            removeLruProcessLocked(app);
14370            ProcessList.remove(app.pid);
14371        }
14372
14373        mProcessesToGc.remove(app);
14374        mPendingPssProcesses.remove(app);
14375
14376        // Dismiss any open dialogs.
14377        if (app.crashDialog != null && !app.forceCrashReport) {
14378            app.crashDialog.dismiss();
14379            app.crashDialog = null;
14380        }
14381        if (app.anrDialog != null) {
14382            app.anrDialog.dismiss();
14383            app.anrDialog = null;
14384        }
14385        if (app.waitDialog != null) {
14386            app.waitDialog.dismiss();
14387            app.waitDialog = null;
14388        }
14389
14390        app.crashing = false;
14391        app.notResponding = false;
14392
14393        app.resetPackageList(mProcessStats);
14394        app.unlinkDeathRecipient();
14395        app.makeInactive(mProcessStats);
14396        app.waitingToKill = null;
14397        app.forcingToForeground = null;
14398        updateProcessForegroundLocked(app, false, false);
14399        app.foregroundActivities = false;
14400        app.hasShownUi = false;
14401        app.treatLikeActivity = false;
14402        app.hasAboveClient = false;
14403        app.hasClientActivities = false;
14404
14405        mServices.killServicesLocked(app, allowRestart);
14406
14407        boolean restart = false;
14408
14409        // Remove published content providers.
14410        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14411            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14412            final boolean always = app.bad || !allowRestart;
14413            if (removeDyingProviderLocked(app, cpr, always) || always) {
14414                // We left the provider in the launching list, need to
14415                // restart it.
14416                restart = true;
14417            }
14418
14419            cpr.provider = null;
14420            cpr.proc = null;
14421        }
14422        app.pubProviders.clear();
14423
14424        // Take care of any launching providers waiting for this process.
14425        if (checkAppInLaunchingProvidersLocked(app, false)) {
14426            restart = true;
14427        }
14428
14429        // Unregister from connected content providers.
14430        if (!app.conProviders.isEmpty()) {
14431            for (int i=0; i<app.conProviders.size(); i++) {
14432                ContentProviderConnection conn = app.conProviders.get(i);
14433                conn.provider.connections.remove(conn);
14434            }
14435            app.conProviders.clear();
14436        }
14437
14438        // At this point there may be remaining entries in mLaunchingProviders
14439        // where we were the only one waiting, so they are no longer of use.
14440        // Look for these and clean up if found.
14441        // XXX Commented out for now.  Trying to figure out a way to reproduce
14442        // the actual situation to identify what is actually going on.
14443        if (false) {
14444            for (int i=0; i<mLaunchingProviders.size(); i++) {
14445                ContentProviderRecord cpr = (ContentProviderRecord)
14446                        mLaunchingProviders.get(i);
14447                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14448                    synchronized (cpr) {
14449                        cpr.launchingApp = null;
14450                        cpr.notifyAll();
14451                    }
14452                }
14453            }
14454        }
14455
14456        skipCurrentReceiverLocked(app);
14457
14458        // Unregister any receivers.
14459        for (int i=app.receivers.size()-1; i>=0; i--) {
14460            removeReceiverLocked(app.receivers.valueAt(i));
14461        }
14462        app.receivers.clear();
14463
14464        // If the app is undergoing backup, tell the backup manager about it
14465        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14466            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14467                    + mBackupTarget.appInfo + " died during backup");
14468            try {
14469                IBackupManager bm = IBackupManager.Stub.asInterface(
14470                        ServiceManager.getService(Context.BACKUP_SERVICE));
14471                bm.agentDisconnected(app.info.packageName);
14472            } catch (RemoteException e) {
14473                // can't happen; backup manager is local
14474            }
14475        }
14476
14477        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14478            ProcessChangeItem item = mPendingProcessChanges.get(i);
14479            if (item.pid == app.pid) {
14480                mPendingProcessChanges.remove(i);
14481                mAvailProcessChanges.add(item);
14482            }
14483        }
14484        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14485
14486        // If the caller is restarting this app, then leave it in its
14487        // current lists and let the caller take care of it.
14488        if (restarting) {
14489            return false;
14490        }
14491
14492        if (!app.persistent || app.isolated) {
14493            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14494                    "Removing non-persistent process during cleanup: " + app);
14495            mProcessNames.remove(app.processName, app.uid);
14496            mIsolatedProcesses.remove(app.uid);
14497            if (mHeavyWeightProcess == app) {
14498                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14499                        mHeavyWeightProcess.userId, 0));
14500                mHeavyWeightProcess = null;
14501            }
14502        } else if (!app.removed) {
14503            // This app is persistent, so we need to keep its record around.
14504            // If it is not already on the pending app list, add it there
14505            // and start a new process for it.
14506            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14507                mPersistentStartingProcesses.add(app);
14508                restart = true;
14509            }
14510        }
14511        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14512                "Clean-up removing on hold: " + app);
14513        mProcessesOnHold.remove(app);
14514
14515        if (app == mHomeProcess) {
14516            mHomeProcess = null;
14517        }
14518        if (app == mPreviousProcess) {
14519            mPreviousProcess = null;
14520        }
14521
14522        if (restart && !app.isolated) {
14523            // We have components that still need to be running in the
14524            // process, so re-launch it.
14525            if (index < 0) {
14526                ProcessList.remove(app.pid);
14527            }
14528            mProcessNames.put(app.processName, app.uid, app);
14529            startProcessLocked(app, "restart", app.processName);
14530            return true;
14531        } else if (app.pid > 0 && app.pid != MY_PID) {
14532            // Goodbye!
14533            boolean removed;
14534            synchronized (mPidsSelfLocked) {
14535                mPidsSelfLocked.remove(app.pid);
14536                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14537            }
14538            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14539            if (app.isolated) {
14540                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14541            }
14542            app.setPid(0);
14543        }
14544        return false;
14545    }
14546
14547    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14548        // Look through the content providers we are waiting to have launched,
14549        // and if any run in this process then either schedule a restart of
14550        // the process or kill the client waiting for it if this process has
14551        // gone bad.
14552        int NL = mLaunchingProviders.size();
14553        boolean restart = false;
14554        for (int i=0; i<NL; i++) {
14555            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14556            if (cpr.launchingApp == app) {
14557                if (!alwaysBad && !app.bad) {
14558                    restart = true;
14559                } else {
14560                    removeDyingProviderLocked(app, cpr, true);
14561                    // cpr should have been removed from mLaunchingProviders
14562                    NL = mLaunchingProviders.size();
14563                    i--;
14564                }
14565            }
14566        }
14567        return restart;
14568    }
14569
14570    // =========================================================
14571    // SERVICES
14572    // =========================================================
14573
14574    @Override
14575    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14576            int flags) {
14577        enforceNotIsolatedCaller("getServices");
14578        synchronized (this) {
14579            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14580        }
14581    }
14582
14583    @Override
14584    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14585        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14586        synchronized (this) {
14587            return mServices.getRunningServiceControlPanelLocked(name);
14588        }
14589    }
14590
14591    @Override
14592    public ComponentName startService(IApplicationThread caller, Intent service,
14593            String resolvedType, int userId) {
14594        enforceNotIsolatedCaller("startService");
14595        // Refuse possible leaked file descriptors
14596        if (service != null && service.hasFileDescriptors() == true) {
14597            throw new IllegalArgumentException("File descriptors passed in Intent");
14598        }
14599
14600        if (DEBUG_SERVICE)
14601            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14602        synchronized(this) {
14603            final int callingPid = Binder.getCallingPid();
14604            final int callingUid = Binder.getCallingUid();
14605            final long origId = Binder.clearCallingIdentity();
14606            ComponentName res = mServices.startServiceLocked(caller, service,
14607                    resolvedType, callingPid, callingUid, userId);
14608            Binder.restoreCallingIdentity(origId);
14609            return res;
14610        }
14611    }
14612
14613    ComponentName startServiceInPackage(int uid,
14614            Intent service, String resolvedType, int userId) {
14615        synchronized(this) {
14616            if (DEBUG_SERVICE)
14617                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14618            final long origId = Binder.clearCallingIdentity();
14619            ComponentName res = mServices.startServiceLocked(null, service,
14620                    resolvedType, -1, uid, userId);
14621            Binder.restoreCallingIdentity(origId);
14622            return res;
14623        }
14624    }
14625
14626    @Override
14627    public int stopService(IApplicationThread caller, Intent service,
14628            String resolvedType, int userId) {
14629        enforceNotIsolatedCaller("stopService");
14630        // Refuse possible leaked file descriptors
14631        if (service != null && service.hasFileDescriptors() == true) {
14632            throw new IllegalArgumentException("File descriptors passed in Intent");
14633        }
14634
14635        synchronized(this) {
14636            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14637        }
14638    }
14639
14640    @Override
14641    public IBinder peekService(Intent service, String resolvedType) {
14642        enforceNotIsolatedCaller("peekService");
14643        // Refuse possible leaked file descriptors
14644        if (service != null && service.hasFileDescriptors() == true) {
14645            throw new IllegalArgumentException("File descriptors passed in Intent");
14646        }
14647        synchronized(this) {
14648            return mServices.peekServiceLocked(service, resolvedType);
14649        }
14650    }
14651
14652    @Override
14653    public boolean stopServiceToken(ComponentName className, IBinder token,
14654            int startId) {
14655        synchronized(this) {
14656            return mServices.stopServiceTokenLocked(className, token, startId);
14657        }
14658    }
14659
14660    @Override
14661    public void setServiceForeground(ComponentName className, IBinder token,
14662            int id, Notification notification, boolean removeNotification) {
14663        synchronized(this) {
14664            mServices.setServiceForegroundLocked(className, token, id, notification,
14665                    removeNotification);
14666        }
14667    }
14668
14669    @Override
14670    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14671            boolean requireFull, String name, String callerPackage) {
14672        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14673                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14674    }
14675
14676    int unsafeConvertIncomingUser(int userId) {
14677        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14678                ? mCurrentUserId : userId;
14679    }
14680
14681    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14682            int allowMode, String name, String callerPackage) {
14683        final int callingUserId = UserHandle.getUserId(callingUid);
14684        if (callingUserId == userId) {
14685            return userId;
14686        }
14687
14688        // Note that we may be accessing mCurrentUserId outside of a lock...
14689        // shouldn't be a big deal, if this is being called outside
14690        // of a locked context there is intrinsically a race with
14691        // the value the caller will receive and someone else changing it.
14692        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14693        // we will switch to the calling user if access to the current user fails.
14694        int targetUserId = unsafeConvertIncomingUser(userId);
14695
14696        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14697            final boolean allow;
14698            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14699                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14700                // If the caller has this permission, they always pass go.  And collect $200.
14701                allow = true;
14702            } else if (allowMode == ALLOW_FULL_ONLY) {
14703                // We require full access, sucks to be you.
14704                allow = false;
14705            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14706                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14707                // If the caller does not have either permission, they are always doomed.
14708                allow = false;
14709            } else if (allowMode == ALLOW_NON_FULL) {
14710                // We are blanket allowing non-full access, you lucky caller!
14711                allow = true;
14712            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14713                // We may or may not allow this depending on whether the two users are
14714                // in the same profile.
14715                synchronized (mUserProfileGroupIdsSelfLocked) {
14716                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14717                            UserInfo.NO_PROFILE_GROUP_ID);
14718                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14719                            UserInfo.NO_PROFILE_GROUP_ID);
14720                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14721                            && callingProfile == targetProfile;
14722                }
14723            } else {
14724                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14725            }
14726            if (!allow) {
14727                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14728                    // In this case, they would like to just execute as their
14729                    // owner user instead of failing.
14730                    targetUserId = callingUserId;
14731                } else {
14732                    StringBuilder builder = new StringBuilder(128);
14733                    builder.append("Permission Denial: ");
14734                    builder.append(name);
14735                    if (callerPackage != null) {
14736                        builder.append(" from ");
14737                        builder.append(callerPackage);
14738                    }
14739                    builder.append(" asks to run as user ");
14740                    builder.append(userId);
14741                    builder.append(" but is calling from user ");
14742                    builder.append(UserHandle.getUserId(callingUid));
14743                    builder.append("; this requires ");
14744                    builder.append(INTERACT_ACROSS_USERS_FULL);
14745                    if (allowMode != ALLOW_FULL_ONLY) {
14746                        builder.append(" or ");
14747                        builder.append(INTERACT_ACROSS_USERS);
14748                    }
14749                    String msg = builder.toString();
14750                    Slog.w(TAG, msg);
14751                    throw new SecurityException(msg);
14752                }
14753            }
14754        }
14755        if (!allowAll && targetUserId < 0) {
14756            throw new IllegalArgumentException(
14757                    "Call does not support special user #" + targetUserId);
14758        }
14759        // Check shell permission
14760        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14761            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14762                    targetUserId)) {
14763                throw new SecurityException("Shell does not have permission to access user "
14764                        + targetUserId + "\n " + Debug.getCallers(3));
14765            }
14766        }
14767        return targetUserId;
14768    }
14769
14770    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14771            String className, int flags) {
14772        boolean result = false;
14773        // For apps that don't have pre-defined UIDs, check for permission
14774        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14775            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14776                if (ActivityManager.checkUidPermission(
14777                        INTERACT_ACROSS_USERS,
14778                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14779                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14780                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14781                            + " requests FLAG_SINGLE_USER, but app does not hold "
14782                            + INTERACT_ACROSS_USERS;
14783                    Slog.w(TAG, msg);
14784                    throw new SecurityException(msg);
14785                }
14786                // Permission passed
14787                result = true;
14788            }
14789        } else if ("system".equals(componentProcessName)) {
14790            result = true;
14791        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14792            // Phone app and persistent apps are allowed to export singleuser providers.
14793            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14794                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14795        }
14796        if (DEBUG_MU) {
14797            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14798                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14799        }
14800        return result;
14801    }
14802
14803    /**
14804     * Checks to see if the caller is in the same app as the singleton
14805     * component, or the component is in a special app. It allows special apps
14806     * to export singleton components but prevents exporting singleton
14807     * components for regular apps.
14808     */
14809    boolean isValidSingletonCall(int callingUid, int componentUid) {
14810        int componentAppId = UserHandle.getAppId(componentUid);
14811        return UserHandle.isSameApp(callingUid, componentUid)
14812                || componentAppId == Process.SYSTEM_UID
14813                || componentAppId == Process.PHONE_UID
14814                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14815                        == PackageManager.PERMISSION_GRANTED;
14816    }
14817
14818    public int bindService(IApplicationThread caller, IBinder token,
14819            Intent service, String resolvedType,
14820            IServiceConnection connection, int flags, int userId) {
14821        enforceNotIsolatedCaller("bindService");
14822
14823        // Refuse possible leaked file descriptors
14824        if (service != null && service.hasFileDescriptors() == true) {
14825            throw new IllegalArgumentException("File descriptors passed in Intent");
14826        }
14827
14828        synchronized(this) {
14829            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14830                    connection, flags, userId);
14831        }
14832    }
14833
14834    public boolean unbindService(IServiceConnection connection) {
14835        synchronized (this) {
14836            return mServices.unbindServiceLocked(connection);
14837        }
14838    }
14839
14840    public void publishService(IBinder token, Intent intent, IBinder service) {
14841        // Refuse possible leaked file descriptors
14842        if (intent != null && intent.hasFileDescriptors() == true) {
14843            throw new IllegalArgumentException("File descriptors passed in Intent");
14844        }
14845
14846        synchronized(this) {
14847            if (!(token instanceof ServiceRecord)) {
14848                throw new IllegalArgumentException("Invalid service token");
14849            }
14850            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14851        }
14852    }
14853
14854    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14855        // Refuse possible leaked file descriptors
14856        if (intent != null && intent.hasFileDescriptors() == true) {
14857            throw new IllegalArgumentException("File descriptors passed in Intent");
14858        }
14859
14860        synchronized(this) {
14861            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14862        }
14863    }
14864
14865    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14866        synchronized(this) {
14867            if (!(token instanceof ServiceRecord)) {
14868                throw new IllegalArgumentException("Invalid service token");
14869            }
14870            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14871        }
14872    }
14873
14874    // =========================================================
14875    // BACKUP AND RESTORE
14876    // =========================================================
14877
14878    // Cause the target app to be launched if necessary and its backup agent
14879    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14880    // activity manager to announce its creation.
14881    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14882        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14883        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14884
14885        synchronized(this) {
14886            // !!! TODO: currently no check here that we're already bound
14887            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14888            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14889            synchronized (stats) {
14890                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14891            }
14892
14893            // Backup agent is now in use, its package can't be stopped.
14894            try {
14895                AppGlobals.getPackageManager().setPackageStoppedState(
14896                        app.packageName, false, UserHandle.getUserId(app.uid));
14897            } catch (RemoteException e) {
14898            } catch (IllegalArgumentException e) {
14899                Slog.w(TAG, "Failed trying to unstop package "
14900                        + app.packageName + ": " + e);
14901            }
14902
14903            BackupRecord r = new BackupRecord(ss, app, backupMode);
14904            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14905                    ? new ComponentName(app.packageName, app.backupAgentName)
14906                    : new ComponentName("android", "FullBackupAgent");
14907            // startProcessLocked() returns existing proc's record if it's already running
14908            ProcessRecord proc = startProcessLocked(app.processName, app,
14909                    false, 0, "backup", hostingName, false, false, false);
14910            if (proc == null) {
14911                Slog.e(TAG, "Unable to start backup agent process " + r);
14912                return false;
14913            }
14914
14915            r.app = proc;
14916            mBackupTarget = r;
14917            mBackupAppName = app.packageName;
14918
14919            // Try not to kill the process during backup
14920            updateOomAdjLocked(proc);
14921
14922            // If the process is already attached, schedule the creation of the backup agent now.
14923            // If it is not yet live, this will be done when it attaches to the framework.
14924            if (proc.thread != null) {
14925                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14926                try {
14927                    proc.thread.scheduleCreateBackupAgent(app,
14928                            compatibilityInfoForPackageLocked(app), backupMode);
14929                } catch (RemoteException e) {
14930                    // Will time out on the backup manager side
14931                }
14932            } else {
14933                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14934            }
14935            // Invariants: at this point, the target app process exists and the application
14936            // is either already running or in the process of coming up.  mBackupTarget and
14937            // mBackupAppName describe the app, so that when it binds back to the AM we
14938            // know that it's scheduled for a backup-agent operation.
14939        }
14940
14941        return true;
14942    }
14943
14944    @Override
14945    public void clearPendingBackup() {
14946        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14947        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14948
14949        synchronized (this) {
14950            mBackupTarget = null;
14951            mBackupAppName = null;
14952        }
14953    }
14954
14955    // A backup agent has just come up
14956    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14957        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14958                + " = " + agent);
14959
14960        synchronized(this) {
14961            if (!agentPackageName.equals(mBackupAppName)) {
14962                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14963                return;
14964            }
14965        }
14966
14967        long oldIdent = Binder.clearCallingIdentity();
14968        try {
14969            IBackupManager bm = IBackupManager.Stub.asInterface(
14970                    ServiceManager.getService(Context.BACKUP_SERVICE));
14971            bm.agentConnected(agentPackageName, agent);
14972        } catch (RemoteException e) {
14973            // can't happen; the backup manager service is local
14974        } catch (Exception e) {
14975            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14976            e.printStackTrace();
14977        } finally {
14978            Binder.restoreCallingIdentity(oldIdent);
14979        }
14980    }
14981
14982    // done with this agent
14983    public void unbindBackupAgent(ApplicationInfo appInfo) {
14984        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14985        if (appInfo == null) {
14986            Slog.w(TAG, "unbind backup agent for null app");
14987            return;
14988        }
14989
14990        synchronized(this) {
14991            try {
14992                if (mBackupAppName == null) {
14993                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14994                    return;
14995                }
14996
14997                if (!mBackupAppName.equals(appInfo.packageName)) {
14998                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14999                    return;
15000                }
15001
15002                // Not backing this app up any more; reset its OOM adjustment
15003                final ProcessRecord proc = mBackupTarget.app;
15004                updateOomAdjLocked(proc);
15005
15006                // If the app crashed during backup, 'thread' will be null here
15007                if (proc.thread != null) {
15008                    try {
15009                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15010                                compatibilityInfoForPackageLocked(appInfo));
15011                    } catch (Exception e) {
15012                        Slog.e(TAG, "Exception when unbinding backup agent:");
15013                        e.printStackTrace();
15014                    }
15015                }
15016            } finally {
15017                mBackupTarget = null;
15018                mBackupAppName = null;
15019            }
15020        }
15021    }
15022    // =========================================================
15023    // BROADCASTS
15024    // =========================================================
15025
15026    private final List getStickiesLocked(String action, IntentFilter filter,
15027            List cur, int userId) {
15028        final ContentResolver resolver = mContext.getContentResolver();
15029        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15030        if (stickies == null) {
15031            return cur;
15032        }
15033        final ArrayList<Intent> list = stickies.get(action);
15034        if (list == null) {
15035            return cur;
15036        }
15037        int N = list.size();
15038        for (int i=0; i<N; i++) {
15039            Intent intent = list.get(i);
15040            if (filter.match(resolver, intent, true, TAG) >= 0) {
15041                if (cur == null) {
15042                    cur = new ArrayList<Intent>();
15043                }
15044                cur.add(intent);
15045            }
15046        }
15047        return cur;
15048    }
15049
15050    boolean isPendingBroadcastProcessLocked(int pid) {
15051        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15052                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15053    }
15054
15055    void skipPendingBroadcastLocked(int pid) {
15056            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15057            for (BroadcastQueue queue : mBroadcastQueues) {
15058                queue.skipPendingBroadcastLocked(pid);
15059            }
15060    }
15061
15062    // The app just attached; send any pending broadcasts that it should receive
15063    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15064        boolean didSomething = false;
15065        for (BroadcastQueue queue : mBroadcastQueues) {
15066            didSomething |= queue.sendPendingBroadcastsLocked(app);
15067        }
15068        return didSomething;
15069    }
15070
15071    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15072            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15073        enforceNotIsolatedCaller("registerReceiver");
15074        int callingUid;
15075        int callingPid;
15076        synchronized(this) {
15077            ProcessRecord callerApp = null;
15078            if (caller != null) {
15079                callerApp = getRecordForAppLocked(caller);
15080                if (callerApp == null) {
15081                    throw new SecurityException(
15082                            "Unable to find app for caller " + caller
15083                            + " (pid=" + Binder.getCallingPid()
15084                            + ") when registering receiver " + receiver);
15085                }
15086                if (callerApp.info.uid != Process.SYSTEM_UID &&
15087                        !callerApp.pkgList.containsKey(callerPackage) &&
15088                        !"android".equals(callerPackage)) {
15089                    throw new SecurityException("Given caller package " + callerPackage
15090                            + " is not running in process " + callerApp);
15091                }
15092                callingUid = callerApp.info.uid;
15093                callingPid = callerApp.pid;
15094            } else {
15095                callerPackage = null;
15096                callingUid = Binder.getCallingUid();
15097                callingPid = Binder.getCallingPid();
15098            }
15099
15100            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15101                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15102
15103            List allSticky = null;
15104
15105            // Look for any matching sticky broadcasts...
15106            Iterator actions = filter.actionsIterator();
15107            if (actions != null) {
15108                while (actions.hasNext()) {
15109                    String action = (String)actions.next();
15110                    allSticky = getStickiesLocked(action, filter, allSticky,
15111                            UserHandle.USER_ALL);
15112                    allSticky = getStickiesLocked(action, filter, allSticky,
15113                            UserHandle.getUserId(callingUid));
15114                }
15115            } else {
15116                allSticky = getStickiesLocked(null, filter, allSticky,
15117                        UserHandle.USER_ALL);
15118                allSticky = getStickiesLocked(null, filter, allSticky,
15119                        UserHandle.getUserId(callingUid));
15120            }
15121
15122            // The first sticky in the list is returned directly back to
15123            // the client.
15124            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15125
15126            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15127                    + ": " + sticky);
15128
15129            if (receiver == null) {
15130                return sticky;
15131            }
15132
15133            ReceiverList rl
15134                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15135            if (rl == null) {
15136                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15137                        userId, receiver);
15138                if (rl.app != null) {
15139                    rl.app.receivers.add(rl);
15140                } else {
15141                    try {
15142                        receiver.asBinder().linkToDeath(rl, 0);
15143                    } catch (RemoteException e) {
15144                        return sticky;
15145                    }
15146                    rl.linkedToDeath = true;
15147                }
15148                mRegisteredReceivers.put(receiver.asBinder(), rl);
15149            } else if (rl.uid != callingUid) {
15150                throw new IllegalArgumentException(
15151                        "Receiver requested to register for uid " + callingUid
15152                        + " was previously registered for uid " + rl.uid);
15153            } else if (rl.pid != callingPid) {
15154                throw new IllegalArgumentException(
15155                        "Receiver requested to register for pid " + callingPid
15156                        + " was previously registered for pid " + rl.pid);
15157            } else if (rl.userId != userId) {
15158                throw new IllegalArgumentException(
15159                        "Receiver requested to register for user " + userId
15160                        + " was previously registered for user " + rl.userId);
15161            }
15162            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15163                    permission, callingUid, userId);
15164            rl.add(bf);
15165            if (!bf.debugCheck()) {
15166                Slog.w(TAG, "==> For Dynamic broadast");
15167            }
15168            mReceiverResolver.addFilter(bf);
15169
15170            // Enqueue broadcasts for all existing stickies that match
15171            // this filter.
15172            if (allSticky != null) {
15173                ArrayList receivers = new ArrayList();
15174                receivers.add(bf);
15175
15176                int N = allSticky.size();
15177                for (int i=0; i<N; i++) {
15178                    Intent intent = (Intent)allSticky.get(i);
15179                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15180                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15181                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15182                            null, null, false, true, true, -1);
15183                    queue.enqueueParallelBroadcastLocked(r);
15184                    queue.scheduleBroadcastsLocked();
15185                }
15186            }
15187
15188            return sticky;
15189        }
15190    }
15191
15192    public void unregisterReceiver(IIntentReceiver receiver) {
15193        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15194
15195        final long origId = Binder.clearCallingIdentity();
15196        try {
15197            boolean doTrim = false;
15198
15199            synchronized(this) {
15200                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15201                if (rl != null) {
15202                    if (rl.curBroadcast != null) {
15203                        BroadcastRecord r = rl.curBroadcast;
15204                        final boolean doNext = finishReceiverLocked(
15205                                receiver.asBinder(), r.resultCode, r.resultData,
15206                                r.resultExtras, r.resultAbort);
15207                        if (doNext) {
15208                            doTrim = true;
15209                            r.queue.processNextBroadcast(false);
15210                        }
15211                    }
15212
15213                    if (rl.app != null) {
15214                        rl.app.receivers.remove(rl);
15215                    }
15216                    removeReceiverLocked(rl);
15217                    if (rl.linkedToDeath) {
15218                        rl.linkedToDeath = false;
15219                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15220                    }
15221                }
15222            }
15223
15224            // If we actually concluded any broadcasts, we might now be able
15225            // to trim the recipients' apps from our working set
15226            if (doTrim) {
15227                trimApplications();
15228                return;
15229            }
15230
15231        } finally {
15232            Binder.restoreCallingIdentity(origId);
15233        }
15234    }
15235
15236    void removeReceiverLocked(ReceiverList rl) {
15237        mRegisteredReceivers.remove(rl.receiver.asBinder());
15238        int N = rl.size();
15239        for (int i=0; i<N; i++) {
15240            mReceiverResolver.removeFilter(rl.get(i));
15241        }
15242    }
15243
15244    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15245        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15246            ProcessRecord r = mLruProcesses.get(i);
15247            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15248                try {
15249                    r.thread.dispatchPackageBroadcast(cmd, packages);
15250                } catch (RemoteException ex) {
15251                }
15252            }
15253        }
15254    }
15255
15256    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15257            int callingUid, int[] users) {
15258        List<ResolveInfo> receivers = null;
15259        try {
15260            HashSet<ComponentName> singleUserReceivers = null;
15261            boolean scannedFirstReceivers = false;
15262            for (int user : users) {
15263                // Skip users that have Shell restrictions
15264                if (callingUid == Process.SHELL_UID
15265                        && getUserManagerLocked().hasUserRestriction(
15266                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15267                    continue;
15268                }
15269                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15270                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15271                if (user != 0 && newReceivers != null) {
15272                    // If this is not the primary user, we need to check for
15273                    // any receivers that should be filtered out.
15274                    for (int i=0; i<newReceivers.size(); i++) {
15275                        ResolveInfo ri = newReceivers.get(i);
15276                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15277                            newReceivers.remove(i);
15278                            i--;
15279                        }
15280                    }
15281                }
15282                if (newReceivers != null && newReceivers.size() == 0) {
15283                    newReceivers = null;
15284                }
15285                if (receivers == null) {
15286                    receivers = newReceivers;
15287                } else if (newReceivers != null) {
15288                    // We need to concatenate the additional receivers
15289                    // found with what we have do far.  This would be easy,
15290                    // but we also need to de-dup any receivers that are
15291                    // singleUser.
15292                    if (!scannedFirstReceivers) {
15293                        // Collect any single user receivers we had already retrieved.
15294                        scannedFirstReceivers = true;
15295                        for (int i=0; i<receivers.size(); i++) {
15296                            ResolveInfo ri = receivers.get(i);
15297                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15298                                ComponentName cn = new ComponentName(
15299                                        ri.activityInfo.packageName, ri.activityInfo.name);
15300                                if (singleUserReceivers == null) {
15301                                    singleUserReceivers = new HashSet<ComponentName>();
15302                                }
15303                                singleUserReceivers.add(cn);
15304                            }
15305                        }
15306                    }
15307                    // Add the new results to the existing results, tracking
15308                    // and de-dupping single user receivers.
15309                    for (int i=0; i<newReceivers.size(); i++) {
15310                        ResolveInfo ri = newReceivers.get(i);
15311                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15312                            ComponentName cn = new ComponentName(
15313                                    ri.activityInfo.packageName, ri.activityInfo.name);
15314                            if (singleUserReceivers == null) {
15315                                singleUserReceivers = new HashSet<ComponentName>();
15316                            }
15317                            if (!singleUserReceivers.contains(cn)) {
15318                                singleUserReceivers.add(cn);
15319                                receivers.add(ri);
15320                            }
15321                        } else {
15322                            receivers.add(ri);
15323                        }
15324                    }
15325                }
15326            }
15327        } catch (RemoteException ex) {
15328            // pm is in same process, this will never happen.
15329        }
15330        return receivers;
15331    }
15332
15333    private final int broadcastIntentLocked(ProcessRecord callerApp,
15334            String callerPackage, Intent intent, String resolvedType,
15335            IIntentReceiver resultTo, int resultCode, String resultData,
15336            Bundle map, String requiredPermission, int appOp,
15337            boolean ordered, boolean sticky, int callingPid, int callingUid,
15338            int userId) {
15339        intent = new Intent(intent);
15340
15341        // By default broadcasts do not go to stopped apps.
15342        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15343
15344        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15345            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15346            + " ordered=" + ordered + " userid=" + userId);
15347        if ((resultTo != null) && !ordered) {
15348            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15349        }
15350
15351        userId = handleIncomingUser(callingPid, callingUid, userId,
15352                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15353
15354        // Make sure that the user who is receiving this broadcast is started.
15355        // If not, we will just skip it.
15356
15357        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15358            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15359                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15360                Slog.w(TAG, "Skipping broadcast of " + intent
15361                        + ": user " + userId + " is stopped");
15362                return ActivityManager.BROADCAST_SUCCESS;
15363            }
15364        }
15365
15366        /*
15367         * Prevent non-system code (defined here to be non-persistent
15368         * processes) from sending protected broadcasts.
15369         */
15370        int callingAppId = UserHandle.getAppId(callingUid);
15371        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15372            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15373            || callingAppId == Process.NFC_UID || callingUid == 0) {
15374            // Always okay.
15375        } else if (callerApp == null || !callerApp.persistent) {
15376            try {
15377                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15378                        intent.getAction())) {
15379                    String msg = "Permission Denial: not allowed to send broadcast "
15380                            + intent.getAction() + " from pid="
15381                            + callingPid + ", uid=" + callingUid;
15382                    Slog.w(TAG, msg);
15383                    throw new SecurityException(msg);
15384                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15385                    // Special case for compatibility: we don't want apps to send this,
15386                    // but historically it has not been protected and apps may be using it
15387                    // to poke their own app widget.  So, instead of making it protected,
15388                    // just limit it to the caller.
15389                    if (callerApp == null) {
15390                        String msg = "Permission Denial: not allowed to send broadcast "
15391                                + intent.getAction() + " from unknown caller.";
15392                        Slog.w(TAG, msg);
15393                        throw new SecurityException(msg);
15394                    } else if (intent.getComponent() != null) {
15395                        // They are good enough to send to an explicit component...  verify
15396                        // it is being sent to the calling app.
15397                        if (!intent.getComponent().getPackageName().equals(
15398                                callerApp.info.packageName)) {
15399                            String msg = "Permission Denial: not allowed to send broadcast "
15400                                    + intent.getAction() + " to "
15401                                    + intent.getComponent().getPackageName() + " from "
15402                                    + callerApp.info.packageName;
15403                            Slog.w(TAG, msg);
15404                            throw new SecurityException(msg);
15405                        }
15406                    } else {
15407                        // Limit broadcast to their own package.
15408                        intent.setPackage(callerApp.info.packageName);
15409                    }
15410                }
15411            } catch (RemoteException e) {
15412                Slog.w(TAG, "Remote exception", e);
15413                return ActivityManager.BROADCAST_SUCCESS;
15414            }
15415        }
15416
15417        // Handle special intents: if this broadcast is from the package
15418        // manager about a package being removed, we need to remove all of
15419        // its activities from the history stack.
15420        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15421                intent.getAction());
15422        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15423                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15424                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15425                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15426                || uidRemoved) {
15427            if (checkComponentPermission(
15428                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15429                    callingPid, callingUid, -1, true)
15430                    == PackageManager.PERMISSION_GRANTED) {
15431                if (uidRemoved) {
15432                    final Bundle intentExtras = intent.getExtras();
15433                    final int uid = intentExtras != null
15434                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15435                    if (uid >= 0) {
15436                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15437                        synchronized (bs) {
15438                            bs.removeUidStatsLocked(uid);
15439                        }
15440                        mAppOpsService.uidRemoved(uid);
15441                    }
15442                } else {
15443                    // If resources are unavailable just force stop all
15444                    // those packages and flush the attribute cache as well.
15445                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15446                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15447                        if (list != null && (list.length > 0)) {
15448                            for (String pkg : list) {
15449                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15450                                        "storage unmount");
15451                            }
15452                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15453                            sendPackageBroadcastLocked(
15454                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15455                        }
15456                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15457                            intent.getAction())) {
15458                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15459                    } else {
15460                        Uri data = intent.getData();
15461                        String ssp;
15462                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15463                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15464                                    intent.getAction());
15465                            boolean fullUninstall = removed &&
15466                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15467                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15468                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15469                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15470                                        false, fullUninstall, userId,
15471                                        removed ? "pkg removed" : "pkg changed");
15472                            }
15473                            if (removed) {
15474                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15475                                        new String[] {ssp}, userId);
15476                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15477                                    mAppOpsService.packageRemoved(
15478                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15479
15480                                    // Remove all permissions granted from/to this package
15481                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15482                                }
15483                            }
15484                        }
15485                    }
15486                }
15487            } else {
15488                String msg = "Permission Denial: " + intent.getAction()
15489                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15490                        + ", uid=" + callingUid + ")"
15491                        + " requires "
15492                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15493                Slog.w(TAG, msg);
15494                throw new SecurityException(msg);
15495            }
15496
15497        // Special case for adding a package: by default turn on compatibility
15498        // mode.
15499        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15500            Uri data = intent.getData();
15501            String ssp;
15502            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15503                mCompatModePackages.handlePackageAddedLocked(ssp,
15504                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15505            }
15506        }
15507
15508        /*
15509         * If this is the time zone changed action, queue up a message that will reset the timezone
15510         * of all currently running processes. This message will get queued up before the broadcast
15511         * happens.
15512         */
15513        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15514            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15515        }
15516
15517        /*
15518         * If the user set the time, let all running processes know.
15519         */
15520        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15521            final int is24Hour = intent.getBooleanExtra(
15522                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15523            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15524            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15525            synchronized (stats) {
15526                stats.noteCurrentTimeChangedLocked();
15527            }
15528        }
15529
15530        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15531            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15532        }
15533
15534        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15535            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15536            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15537        }
15538
15539        // Add to the sticky list if requested.
15540        if (sticky) {
15541            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15542                    callingPid, callingUid)
15543                    != PackageManager.PERMISSION_GRANTED) {
15544                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15545                        + callingPid + ", uid=" + callingUid
15546                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15547                Slog.w(TAG, msg);
15548                throw new SecurityException(msg);
15549            }
15550            if (requiredPermission != null) {
15551                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15552                        + " and enforce permission " + requiredPermission);
15553                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15554            }
15555            if (intent.getComponent() != null) {
15556                throw new SecurityException(
15557                        "Sticky broadcasts can't target a specific component");
15558            }
15559            // We use userId directly here, since the "all" target is maintained
15560            // as a separate set of sticky broadcasts.
15561            if (userId != UserHandle.USER_ALL) {
15562                // But first, if this is not a broadcast to all users, then
15563                // make sure it doesn't conflict with an existing broadcast to
15564                // all users.
15565                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15566                        UserHandle.USER_ALL);
15567                if (stickies != null) {
15568                    ArrayList<Intent> list = stickies.get(intent.getAction());
15569                    if (list != null) {
15570                        int N = list.size();
15571                        int i;
15572                        for (i=0; i<N; i++) {
15573                            if (intent.filterEquals(list.get(i))) {
15574                                throw new IllegalArgumentException(
15575                                        "Sticky broadcast " + intent + " for user "
15576                                        + userId + " conflicts with existing global broadcast");
15577                            }
15578                        }
15579                    }
15580                }
15581            }
15582            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15583            if (stickies == null) {
15584                stickies = new ArrayMap<String, ArrayList<Intent>>();
15585                mStickyBroadcasts.put(userId, stickies);
15586            }
15587            ArrayList<Intent> list = stickies.get(intent.getAction());
15588            if (list == null) {
15589                list = new ArrayList<Intent>();
15590                stickies.put(intent.getAction(), list);
15591            }
15592            int N = list.size();
15593            int i;
15594            for (i=0; i<N; i++) {
15595                if (intent.filterEquals(list.get(i))) {
15596                    // This sticky already exists, replace it.
15597                    list.set(i, new Intent(intent));
15598                    break;
15599                }
15600            }
15601            if (i >= N) {
15602                list.add(new Intent(intent));
15603            }
15604        }
15605
15606        int[] users;
15607        if (userId == UserHandle.USER_ALL) {
15608            // Caller wants broadcast to go to all started users.
15609            users = mStartedUserArray;
15610        } else {
15611            // Caller wants broadcast to go to one specific user.
15612            users = new int[] {userId};
15613        }
15614
15615        // Figure out who all will receive this broadcast.
15616        List receivers = null;
15617        List<BroadcastFilter> registeredReceivers = null;
15618        // Need to resolve the intent to interested receivers...
15619        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15620                 == 0) {
15621            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15622        }
15623        if (intent.getComponent() == null) {
15624            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15625                // Query one target user at a time, excluding shell-restricted users
15626                UserManagerService ums = getUserManagerLocked();
15627                for (int i = 0; i < users.length; i++) {
15628                    if (ums.hasUserRestriction(
15629                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15630                        continue;
15631                    }
15632                    List<BroadcastFilter> registeredReceiversForUser =
15633                            mReceiverResolver.queryIntent(intent,
15634                                    resolvedType, false, users[i]);
15635                    if (registeredReceivers == null) {
15636                        registeredReceivers = registeredReceiversForUser;
15637                    } else if (registeredReceiversForUser != null) {
15638                        registeredReceivers.addAll(registeredReceiversForUser);
15639                    }
15640                }
15641            } else {
15642                registeredReceivers = mReceiverResolver.queryIntent(intent,
15643                        resolvedType, false, userId);
15644            }
15645        }
15646
15647        final boolean replacePending =
15648                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15649
15650        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15651                + " replacePending=" + replacePending);
15652
15653        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15654        if (!ordered && NR > 0) {
15655            // If we are not serializing this broadcast, then send the
15656            // registered receivers separately so they don't wait for the
15657            // components to be launched.
15658            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15659            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15660                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15661                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15662                    ordered, sticky, false, userId);
15663            if (DEBUG_BROADCAST) Slog.v(
15664                    TAG, "Enqueueing parallel broadcast " + r);
15665            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15666            if (!replaced) {
15667                queue.enqueueParallelBroadcastLocked(r);
15668                queue.scheduleBroadcastsLocked();
15669            }
15670            registeredReceivers = null;
15671            NR = 0;
15672        }
15673
15674        // Merge into one list.
15675        int ir = 0;
15676        if (receivers != null) {
15677            // A special case for PACKAGE_ADDED: do not allow the package
15678            // being added to see this broadcast.  This prevents them from
15679            // using this as a back door to get run as soon as they are
15680            // installed.  Maybe in the future we want to have a special install
15681            // broadcast or such for apps, but we'd like to deliberately make
15682            // this decision.
15683            String skipPackages[] = null;
15684            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15685                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15686                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15687                Uri data = intent.getData();
15688                if (data != null) {
15689                    String pkgName = data.getSchemeSpecificPart();
15690                    if (pkgName != null) {
15691                        skipPackages = new String[] { pkgName };
15692                    }
15693                }
15694            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15695                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15696            }
15697            if (skipPackages != null && (skipPackages.length > 0)) {
15698                for (String skipPackage : skipPackages) {
15699                    if (skipPackage != null) {
15700                        int NT = receivers.size();
15701                        for (int it=0; it<NT; it++) {
15702                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15703                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15704                                receivers.remove(it);
15705                                it--;
15706                                NT--;
15707                            }
15708                        }
15709                    }
15710                }
15711            }
15712
15713            int NT = receivers != null ? receivers.size() : 0;
15714            int it = 0;
15715            ResolveInfo curt = null;
15716            BroadcastFilter curr = null;
15717            while (it < NT && ir < NR) {
15718                if (curt == null) {
15719                    curt = (ResolveInfo)receivers.get(it);
15720                }
15721                if (curr == null) {
15722                    curr = registeredReceivers.get(ir);
15723                }
15724                if (curr.getPriority() >= curt.priority) {
15725                    // Insert this broadcast record into the final list.
15726                    receivers.add(it, curr);
15727                    ir++;
15728                    curr = null;
15729                    it++;
15730                    NT++;
15731                } else {
15732                    // Skip to the next ResolveInfo in the final list.
15733                    it++;
15734                    curt = null;
15735                }
15736            }
15737        }
15738        while (ir < NR) {
15739            if (receivers == null) {
15740                receivers = new ArrayList();
15741            }
15742            receivers.add(registeredReceivers.get(ir));
15743            ir++;
15744        }
15745
15746        if ((receivers != null && receivers.size() > 0)
15747                || resultTo != null) {
15748            BroadcastQueue queue = broadcastQueueForIntent(intent);
15749            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15750                    callerPackage, callingPid, callingUid, resolvedType,
15751                    requiredPermission, appOp, receivers, resultTo, resultCode,
15752                    resultData, map, ordered, sticky, false, userId);
15753            if (DEBUG_BROADCAST) Slog.v(
15754                    TAG, "Enqueueing ordered broadcast " + r
15755                    + ": prev had " + queue.mOrderedBroadcasts.size());
15756            if (DEBUG_BROADCAST) {
15757                int seq = r.intent.getIntExtra("seq", -1);
15758                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15759            }
15760            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15761            if (!replaced) {
15762                queue.enqueueOrderedBroadcastLocked(r);
15763                queue.scheduleBroadcastsLocked();
15764            }
15765        }
15766
15767        return ActivityManager.BROADCAST_SUCCESS;
15768    }
15769
15770    final Intent verifyBroadcastLocked(Intent intent) {
15771        // Refuse possible leaked file descriptors
15772        if (intent != null && intent.hasFileDescriptors() == true) {
15773            throw new IllegalArgumentException("File descriptors passed in Intent");
15774        }
15775
15776        int flags = intent.getFlags();
15777
15778        if (!mProcessesReady) {
15779            // if the caller really truly claims to know what they're doing, go
15780            // ahead and allow the broadcast without launching any receivers
15781            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15782                intent = new Intent(intent);
15783                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15784            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15785                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15786                        + " before boot completion");
15787                throw new IllegalStateException("Cannot broadcast before boot completed");
15788            }
15789        }
15790
15791        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15792            throw new IllegalArgumentException(
15793                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15794        }
15795
15796        return intent;
15797    }
15798
15799    public final int broadcastIntent(IApplicationThread caller,
15800            Intent intent, String resolvedType, IIntentReceiver resultTo,
15801            int resultCode, String resultData, Bundle map,
15802            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15803        enforceNotIsolatedCaller("broadcastIntent");
15804        synchronized(this) {
15805            intent = verifyBroadcastLocked(intent);
15806
15807            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15808            final int callingPid = Binder.getCallingPid();
15809            final int callingUid = Binder.getCallingUid();
15810            final long origId = Binder.clearCallingIdentity();
15811            int res = broadcastIntentLocked(callerApp,
15812                    callerApp != null ? callerApp.info.packageName : null,
15813                    intent, resolvedType, resultTo,
15814                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15815                    callingPid, callingUid, userId);
15816            Binder.restoreCallingIdentity(origId);
15817            return res;
15818        }
15819    }
15820
15821    int broadcastIntentInPackage(String packageName, int uid,
15822            Intent intent, String resolvedType, IIntentReceiver resultTo,
15823            int resultCode, String resultData, Bundle map,
15824            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15825        synchronized(this) {
15826            intent = verifyBroadcastLocked(intent);
15827
15828            final long origId = Binder.clearCallingIdentity();
15829            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15830                    resultTo, resultCode, resultData, map, requiredPermission,
15831                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15832            Binder.restoreCallingIdentity(origId);
15833            return res;
15834        }
15835    }
15836
15837    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15838        // Refuse possible leaked file descriptors
15839        if (intent != null && intent.hasFileDescriptors() == true) {
15840            throw new IllegalArgumentException("File descriptors passed in Intent");
15841        }
15842
15843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15844                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15845
15846        synchronized(this) {
15847            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15848                    != PackageManager.PERMISSION_GRANTED) {
15849                String msg = "Permission Denial: unbroadcastIntent() from pid="
15850                        + Binder.getCallingPid()
15851                        + ", uid=" + Binder.getCallingUid()
15852                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15853                Slog.w(TAG, msg);
15854                throw new SecurityException(msg);
15855            }
15856            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15857            if (stickies != null) {
15858                ArrayList<Intent> list = stickies.get(intent.getAction());
15859                if (list != null) {
15860                    int N = list.size();
15861                    int i;
15862                    for (i=0; i<N; i++) {
15863                        if (intent.filterEquals(list.get(i))) {
15864                            list.remove(i);
15865                            break;
15866                        }
15867                    }
15868                    if (list.size() <= 0) {
15869                        stickies.remove(intent.getAction());
15870                    }
15871                }
15872                if (stickies.size() <= 0) {
15873                    mStickyBroadcasts.remove(userId);
15874                }
15875            }
15876        }
15877    }
15878
15879    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15880            String resultData, Bundle resultExtras, boolean resultAbort) {
15881        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15882        if (r == null) {
15883            Slog.w(TAG, "finishReceiver called but not found on queue");
15884            return false;
15885        }
15886
15887        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15888    }
15889
15890    void backgroundServicesFinishedLocked(int userId) {
15891        for (BroadcastQueue queue : mBroadcastQueues) {
15892            queue.backgroundServicesFinishedLocked(userId);
15893        }
15894    }
15895
15896    public void finishReceiver(IBinder who, int resultCode, String resultData,
15897            Bundle resultExtras, boolean resultAbort) {
15898        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15899
15900        // Refuse possible leaked file descriptors
15901        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15902            throw new IllegalArgumentException("File descriptors passed in Bundle");
15903        }
15904
15905        final long origId = Binder.clearCallingIdentity();
15906        try {
15907            boolean doNext = false;
15908            BroadcastRecord r;
15909
15910            synchronized(this) {
15911                r = broadcastRecordForReceiverLocked(who);
15912                if (r != null) {
15913                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15914                        resultData, resultExtras, resultAbort, true);
15915                }
15916            }
15917
15918            if (doNext) {
15919                r.queue.processNextBroadcast(false);
15920            }
15921            trimApplications();
15922        } finally {
15923            Binder.restoreCallingIdentity(origId);
15924        }
15925    }
15926
15927    // =========================================================
15928    // INSTRUMENTATION
15929    // =========================================================
15930
15931    public boolean startInstrumentation(ComponentName className,
15932            String profileFile, int flags, Bundle arguments,
15933            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15934            int userId, String abiOverride) {
15935        enforceNotIsolatedCaller("startInstrumentation");
15936        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15937                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15938        // Refuse possible leaked file descriptors
15939        if (arguments != null && arguments.hasFileDescriptors()) {
15940            throw new IllegalArgumentException("File descriptors passed in Bundle");
15941        }
15942
15943        synchronized(this) {
15944            InstrumentationInfo ii = null;
15945            ApplicationInfo ai = null;
15946            try {
15947                ii = mContext.getPackageManager().getInstrumentationInfo(
15948                    className, STOCK_PM_FLAGS);
15949                ai = AppGlobals.getPackageManager().getApplicationInfo(
15950                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15951            } catch (PackageManager.NameNotFoundException e) {
15952            } catch (RemoteException e) {
15953            }
15954            if (ii == null) {
15955                reportStartInstrumentationFailure(watcher, className,
15956                        "Unable to find instrumentation info for: " + className);
15957                return false;
15958            }
15959            if (ai == null) {
15960                reportStartInstrumentationFailure(watcher, className,
15961                        "Unable to find instrumentation target package: " + ii.targetPackage);
15962                return false;
15963            }
15964
15965            int match = mContext.getPackageManager().checkSignatures(
15966                    ii.targetPackage, ii.packageName);
15967            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15968                String msg = "Permission Denial: starting instrumentation "
15969                        + className + " from pid="
15970                        + Binder.getCallingPid()
15971                        + ", uid=" + Binder.getCallingPid()
15972                        + " not allowed because package " + ii.packageName
15973                        + " does not have a signature matching the target "
15974                        + ii.targetPackage;
15975                reportStartInstrumentationFailure(watcher, className, msg);
15976                throw new SecurityException(msg);
15977            }
15978
15979            final long origId = Binder.clearCallingIdentity();
15980            // Instrumentation can kill and relaunch even persistent processes
15981            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15982                    "start instr");
15983            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15984            app.instrumentationClass = className;
15985            app.instrumentationInfo = ai;
15986            app.instrumentationProfileFile = profileFile;
15987            app.instrumentationArguments = arguments;
15988            app.instrumentationWatcher = watcher;
15989            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15990            app.instrumentationResultClass = className;
15991            Binder.restoreCallingIdentity(origId);
15992        }
15993
15994        return true;
15995    }
15996
15997    /**
15998     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15999     * error to the logs, but if somebody is watching, send the report there too.  This enables
16000     * the "am" command to report errors with more information.
16001     *
16002     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16003     * @param cn The component name of the instrumentation.
16004     * @param report The error report.
16005     */
16006    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16007            ComponentName cn, String report) {
16008        Slog.w(TAG, report);
16009        try {
16010            if (watcher != null) {
16011                Bundle results = new Bundle();
16012                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16013                results.putString("Error", report);
16014                watcher.instrumentationStatus(cn, -1, results);
16015            }
16016        } catch (RemoteException e) {
16017            Slog.w(TAG, e);
16018        }
16019    }
16020
16021    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16022        if (app.instrumentationWatcher != null) {
16023            try {
16024                // NOTE:  IInstrumentationWatcher *must* be oneway here
16025                app.instrumentationWatcher.instrumentationFinished(
16026                    app.instrumentationClass,
16027                    resultCode,
16028                    results);
16029            } catch (RemoteException e) {
16030            }
16031        }
16032        if (app.instrumentationUiAutomationConnection != null) {
16033            try {
16034                app.instrumentationUiAutomationConnection.shutdown();
16035            } catch (RemoteException re) {
16036                /* ignore */
16037            }
16038            // Only a UiAutomation can set this flag and now that
16039            // it is finished we make sure it is reset to its default.
16040            mUserIsMonkey = false;
16041        }
16042        app.instrumentationWatcher = null;
16043        app.instrumentationUiAutomationConnection = null;
16044        app.instrumentationClass = null;
16045        app.instrumentationInfo = null;
16046        app.instrumentationProfileFile = null;
16047        app.instrumentationArguments = null;
16048
16049        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16050                "finished inst");
16051    }
16052
16053    public void finishInstrumentation(IApplicationThread target,
16054            int resultCode, Bundle results) {
16055        int userId = UserHandle.getCallingUserId();
16056        // Refuse possible leaked file descriptors
16057        if (results != null && results.hasFileDescriptors()) {
16058            throw new IllegalArgumentException("File descriptors passed in Intent");
16059        }
16060
16061        synchronized(this) {
16062            ProcessRecord app = getRecordForAppLocked(target);
16063            if (app == null) {
16064                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16065                return;
16066            }
16067            final long origId = Binder.clearCallingIdentity();
16068            finishInstrumentationLocked(app, resultCode, results);
16069            Binder.restoreCallingIdentity(origId);
16070        }
16071    }
16072
16073    // =========================================================
16074    // CONFIGURATION
16075    // =========================================================
16076
16077    public ConfigurationInfo getDeviceConfigurationInfo() {
16078        ConfigurationInfo config = new ConfigurationInfo();
16079        synchronized (this) {
16080            config.reqTouchScreen = mConfiguration.touchscreen;
16081            config.reqKeyboardType = mConfiguration.keyboard;
16082            config.reqNavigation = mConfiguration.navigation;
16083            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16084                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16085                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16086            }
16087            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16088                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16089                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16090            }
16091            config.reqGlEsVersion = GL_ES_VERSION;
16092        }
16093        return config;
16094    }
16095
16096    ActivityStack getFocusedStack() {
16097        return mStackSupervisor.getFocusedStack();
16098    }
16099
16100    public Configuration getConfiguration() {
16101        Configuration ci;
16102        synchronized(this) {
16103            ci = new Configuration(mConfiguration);
16104        }
16105        return ci;
16106    }
16107
16108    public void updatePersistentConfiguration(Configuration values) {
16109        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16110                "updateConfiguration()");
16111        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16112                "updateConfiguration()");
16113        if (values == null) {
16114            throw new NullPointerException("Configuration must not be null");
16115        }
16116
16117        synchronized(this) {
16118            final long origId = Binder.clearCallingIdentity();
16119            updateConfigurationLocked(values, null, true, false);
16120            Binder.restoreCallingIdentity(origId);
16121        }
16122    }
16123
16124    public void updateConfiguration(Configuration values) {
16125        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16126                "updateConfiguration()");
16127
16128        synchronized(this) {
16129            if (values == null && mWindowManager != null) {
16130                // sentinel: fetch the current configuration from the window manager
16131                values = mWindowManager.computeNewConfiguration();
16132            }
16133
16134            if (mWindowManager != null) {
16135                mProcessList.applyDisplaySize(mWindowManager);
16136            }
16137
16138            final long origId = Binder.clearCallingIdentity();
16139            if (values != null) {
16140                Settings.System.clearConfiguration(values);
16141            }
16142            updateConfigurationLocked(values, null, false, false);
16143            Binder.restoreCallingIdentity(origId);
16144        }
16145    }
16146
16147    /**
16148     * Do either or both things: (1) change the current configuration, and (2)
16149     * make sure the given activity is running with the (now) current
16150     * configuration.  Returns true if the activity has been left running, or
16151     * false if <var>starting</var> is being destroyed to match the new
16152     * configuration.
16153     * @param persistent TODO
16154     */
16155    boolean updateConfigurationLocked(Configuration values,
16156            ActivityRecord starting, boolean persistent, boolean initLocale) {
16157        int changes = 0;
16158
16159        if (values != null) {
16160            Configuration newConfig = new Configuration(mConfiguration);
16161            changes = newConfig.updateFrom(values);
16162            if (changes != 0) {
16163                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16164                    Slog.i(TAG, "Updating configuration to: " + values);
16165                }
16166
16167                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16168
16169                if (values.locale != null && !initLocale) {
16170                    saveLocaleLocked(values.locale,
16171                                     !values.locale.equals(mConfiguration.locale),
16172                                     values.userSetLocale);
16173                }
16174
16175                mConfigurationSeq++;
16176                if (mConfigurationSeq <= 0) {
16177                    mConfigurationSeq = 1;
16178                }
16179                newConfig.seq = mConfigurationSeq;
16180                mConfiguration = newConfig;
16181                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16182                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16183                //mUsageStatsService.noteStartConfig(newConfig);
16184
16185                final Configuration configCopy = new Configuration(mConfiguration);
16186
16187                // TODO: If our config changes, should we auto dismiss any currently
16188                // showing dialogs?
16189                mShowDialogs = shouldShowDialogs(newConfig);
16190
16191                AttributeCache ac = AttributeCache.instance();
16192                if (ac != null) {
16193                    ac.updateConfiguration(configCopy);
16194                }
16195
16196                // Make sure all resources in our process are updated
16197                // right now, so that anyone who is going to retrieve
16198                // resource values after we return will be sure to get
16199                // the new ones.  This is especially important during
16200                // boot, where the first config change needs to guarantee
16201                // all resources have that config before following boot
16202                // code is executed.
16203                mSystemThread.applyConfigurationToResources(configCopy);
16204
16205                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16206                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16207                    msg.obj = new Configuration(configCopy);
16208                    mHandler.sendMessage(msg);
16209                }
16210
16211                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16212                    ProcessRecord app = mLruProcesses.get(i);
16213                    try {
16214                        if (app.thread != null) {
16215                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16216                                    + app.processName + " new config " + mConfiguration);
16217                            app.thread.scheduleConfigurationChanged(configCopy);
16218                        }
16219                    } catch (Exception e) {
16220                    }
16221                }
16222                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16223                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16224                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16225                        | Intent.FLAG_RECEIVER_FOREGROUND);
16226                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16227                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16228                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16229                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16230                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16231                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16232                    broadcastIntentLocked(null, null, intent,
16233                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16234                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16235                }
16236            }
16237        }
16238
16239        boolean kept = true;
16240        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16241        // mainStack is null during startup.
16242        if (mainStack != null) {
16243            if (changes != 0 && starting == null) {
16244                // If the configuration changed, and the caller is not already
16245                // in the process of starting an activity, then find the top
16246                // activity to check if its configuration needs to change.
16247                starting = mainStack.topRunningActivityLocked(null);
16248            }
16249
16250            if (starting != null) {
16251                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16252                // And we need to make sure at this point that all other activities
16253                // are made visible with the correct configuration.
16254                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16255            }
16256        }
16257
16258        if (values != null && mWindowManager != null) {
16259            mWindowManager.setNewConfiguration(mConfiguration);
16260        }
16261
16262        return kept;
16263    }
16264
16265    /**
16266     * Decide based on the configuration whether we should shouw the ANR,
16267     * crash, etc dialogs.  The idea is that if there is no affordnace to
16268     * press the on-screen buttons, we shouldn't show the dialog.
16269     *
16270     * A thought: SystemUI might also want to get told about this, the Power
16271     * dialog / global actions also might want different behaviors.
16272     */
16273    private static final boolean shouldShowDialogs(Configuration config) {
16274        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16275                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16276    }
16277
16278    /**
16279     * Save the locale.  You must be inside a synchronized (this) block.
16280     */
16281    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16282        if(isDiff) {
16283            SystemProperties.set("user.language", l.getLanguage());
16284            SystemProperties.set("user.region", l.getCountry());
16285        }
16286
16287        if(isPersist) {
16288            SystemProperties.set("persist.sys.language", l.getLanguage());
16289            SystemProperties.set("persist.sys.country", l.getCountry());
16290            SystemProperties.set("persist.sys.localevar", l.getVariant());
16291
16292            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16293        }
16294    }
16295
16296    @Override
16297    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16298        synchronized (this) {
16299            ActivityRecord srec = ActivityRecord.forToken(token);
16300            if (srec.task != null && srec.task.stack != null) {
16301                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16302            }
16303        }
16304        return false;
16305    }
16306
16307    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16308            Intent resultData) {
16309
16310        synchronized (this) {
16311            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16312            if (stack != null) {
16313                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16314            }
16315            return false;
16316        }
16317    }
16318
16319    public int getLaunchedFromUid(IBinder activityToken) {
16320        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16321        if (srec == null) {
16322            return -1;
16323        }
16324        return srec.launchedFromUid;
16325    }
16326
16327    public String getLaunchedFromPackage(IBinder activityToken) {
16328        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16329        if (srec == null) {
16330            return null;
16331        }
16332        return srec.launchedFromPackage;
16333    }
16334
16335    // =========================================================
16336    // LIFETIME MANAGEMENT
16337    // =========================================================
16338
16339    // Returns which broadcast queue the app is the current [or imminent] receiver
16340    // on, or 'null' if the app is not an active broadcast recipient.
16341    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16342        BroadcastRecord r = app.curReceiver;
16343        if (r != null) {
16344            return r.queue;
16345        }
16346
16347        // It's not the current receiver, but it might be starting up to become one
16348        synchronized (this) {
16349            for (BroadcastQueue queue : mBroadcastQueues) {
16350                r = queue.mPendingBroadcast;
16351                if (r != null && r.curApp == app) {
16352                    // found it; report which queue it's in
16353                    return queue;
16354                }
16355            }
16356        }
16357
16358        return null;
16359    }
16360
16361    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16362            boolean doingAll, long now) {
16363        if (mAdjSeq == app.adjSeq) {
16364            // This adjustment has already been computed.
16365            return app.curRawAdj;
16366        }
16367
16368        if (app.thread == null) {
16369            app.adjSeq = mAdjSeq;
16370            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16371            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16372            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16373        }
16374
16375        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16376        app.adjSource = null;
16377        app.adjTarget = null;
16378        app.empty = false;
16379        app.cached = false;
16380
16381        final int activitiesSize = app.activities.size();
16382
16383        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16384            // The max adjustment doesn't allow this app to be anything
16385            // below foreground, so it is not worth doing work for it.
16386            app.adjType = "fixed";
16387            app.adjSeq = mAdjSeq;
16388            app.curRawAdj = app.maxAdj;
16389            app.foregroundActivities = false;
16390            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16391            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16392            // System processes can do UI, and when they do we want to have
16393            // them trim their memory after the user leaves the UI.  To
16394            // facilitate this, here we need to determine whether or not it
16395            // is currently showing UI.
16396            app.systemNoUi = true;
16397            if (app == TOP_APP) {
16398                app.systemNoUi = false;
16399            } else if (activitiesSize > 0) {
16400                for (int j = 0; j < activitiesSize; j++) {
16401                    final ActivityRecord r = app.activities.get(j);
16402                    if (r.visible) {
16403                        app.systemNoUi = false;
16404                    }
16405                }
16406            }
16407            if (!app.systemNoUi) {
16408                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16409            }
16410            return (app.curAdj=app.maxAdj);
16411        }
16412
16413        app.systemNoUi = false;
16414
16415        // Determine the importance of the process, starting with most
16416        // important to least, and assign an appropriate OOM adjustment.
16417        int adj;
16418        int schedGroup;
16419        int procState;
16420        boolean foregroundActivities = false;
16421        BroadcastQueue queue;
16422        if (app == TOP_APP) {
16423            // The last app on the list is the foreground app.
16424            adj = ProcessList.FOREGROUND_APP_ADJ;
16425            schedGroup = Process.THREAD_GROUP_DEFAULT;
16426            app.adjType = "top-activity";
16427            foregroundActivities = true;
16428            procState = ActivityManager.PROCESS_STATE_TOP;
16429        } else if (app.instrumentationClass != null) {
16430            // Don't want to kill running instrumentation.
16431            adj = ProcessList.FOREGROUND_APP_ADJ;
16432            schedGroup = Process.THREAD_GROUP_DEFAULT;
16433            app.adjType = "instrumentation";
16434            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16435        } else if ((queue = isReceivingBroadcast(app)) != null) {
16436            // An app that is currently receiving a broadcast also
16437            // counts as being in the foreground for OOM killer purposes.
16438            // It's placed in a sched group based on the nature of the
16439            // broadcast as reflected by which queue it's active in.
16440            adj = ProcessList.FOREGROUND_APP_ADJ;
16441            schedGroup = (queue == mFgBroadcastQueue)
16442                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16443            app.adjType = "broadcast";
16444            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16445        } else if (app.executingServices.size() > 0) {
16446            // An app that is currently executing a service callback also
16447            // counts as being in the foreground.
16448            adj = ProcessList.FOREGROUND_APP_ADJ;
16449            schedGroup = app.execServicesFg ?
16450                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16451            app.adjType = "exec-service";
16452            procState = ActivityManager.PROCESS_STATE_SERVICE;
16453            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16454        } else {
16455            // As far as we know the process is empty.  We may change our mind later.
16456            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16457            // At this point we don't actually know the adjustment.  Use the cached adj
16458            // value that the caller wants us to.
16459            adj = cachedAdj;
16460            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16461            app.cached = true;
16462            app.empty = true;
16463            app.adjType = "cch-empty";
16464        }
16465
16466        // Examine all activities if not already foreground.
16467        if (!foregroundActivities && activitiesSize > 0) {
16468            for (int j = 0; j < activitiesSize; j++) {
16469                final ActivityRecord r = app.activities.get(j);
16470                if (r.app != app) {
16471                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16472                            + app + "?!?");
16473                    continue;
16474                }
16475                if (r.visible) {
16476                    // App has a visible activity; only upgrade adjustment.
16477                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16478                        adj = ProcessList.VISIBLE_APP_ADJ;
16479                        app.adjType = "visible";
16480                    }
16481                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16482                        procState = ActivityManager.PROCESS_STATE_TOP;
16483                    }
16484                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16485                    app.cached = false;
16486                    app.empty = false;
16487                    foregroundActivities = true;
16488                    break;
16489                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16490                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16491                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16492                        app.adjType = "pausing";
16493                    }
16494                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16495                        procState = ActivityManager.PROCESS_STATE_TOP;
16496                    }
16497                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16498                    app.cached = false;
16499                    app.empty = false;
16500                    foregroundActivities = true;
16501                } else if (r.state == ActivityState.STOPPING) {
16502                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16503                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16504                        app.adjType = "stopping";
16505                    }
16506                    // For the process state, we will at this point consider the
16507                    // process to be cached.  It will be cached either as an activity
16508                    // or empty depending on whether the activity is finishing.  We do
16509                    // this so that we can treat the process as cached for purposes of
16510                    // memory trimming (determing current memory level, trim command to
16511                    // send to process) since there can be an arbitrary number of stopping
16512                    // processes and they should soon all go into the cached state.
16513                    if (!r.finishing) {
16514                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16515                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16516                        }
16517                    }
16518                    app.cached = false;
16519                    app.empty = false;
16520                    foregroundActivities = true;
16521                } else {
16522                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16523                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16524                        app.adjType = "cch-act";
16525                    }
16526                }
16527            }
16528        }
16529
16530        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16531            if (app.foregroundServices) {
16532                // The user is aware of this app, so make it visible.
16533                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16534                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16535                app.cached = false;
16536                app.adjType = "fg-service";
16537                schedGroup = Process.THREAD_GROUP_DEFAULT;
16538            } else if (app.forcingToForeground != null) {
16539                // The user is aware of this app, so make it visible.
16540                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16541                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16542                app.cached = false;
16543                app.adjType = "force-fg";
16544                app.adjSource = app.forcingToForeground;
16545                schedGroup = Process.THREAD_GROUP_DEFAULT;
16546            }
16547        }
16548
16549        if (app == mHeavyWeightProcess) {
16550            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16551                // We don't want to kill the current heavy-weight process.
16552                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16553                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16554                app.cached = false;
16555                app.adjType = "heavy";
16556            }
16557            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16558                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16559            }
16560        }
16561
16562        if (app == mHomeProcess) {
16563            if (adj > ProcessList.HOME_APP_ADJ) {
16564                // This process is hosting what we currently consider to be the
16565                // home app, so we don't want to let it go into the background.
16566                adj = ProcessList.HOME_APP_ADJ;
16567                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16568                app.cached = false;
16569                app.adjType = "home";
16570            }
16571            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16572                procState = ActivityManager.PROCESS_STATE_HOME;
16573            }
16574        }
16575
16576        if (app == mPreviousProcess && app.activities.size() > 0) {
16577            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16578                // This was the previous process that showed UI to the user.
16579                // We want to try to keep it around more aggressively, to give
16580                // a good experience around switching between two apps.
16581                adj = ProcessList.PREVIOUS_APP_ADJ;
16582                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16583                app.cached = false;
16584                app.adjType = "previous";
16585            }
16586            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16587                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16588            }
16589        }
16590
16591        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16592                + " reason=" + app.adjType);
16593
16594        // By default, we use the computed adjustment.  It may be changed if
16595        // there are applications dependent on our services or providers, but
16596        // this gives us a baseline and makes sure we don't get into an
16597        // infinite recursion.
16598        app.adjSeq = mAdjSeq;
16599        app.curRawAdj = adj;
16600        app.hasStartedServices = false;
16601
16602        if (mBackupTarget != null && app == mBackupTarget.app) {
16603            // If possible we want to avoid killing apps while they're being backed up
16604            if (adj > ProcessList.BACKUP_APP_ADJ) {
16605                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16606                adj = ProcessList.BACKUP_APP_ADJ;
16607                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16608                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16609                }
16610                app.adjType = "backup";
16611                app.cached = false;
16612            }
16613            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16614                procState = ActivityManager.PROCESS_STATE_BACKUP;
16615            }
16616        }
16617
16618        boolean mayBeTop = false;
16619
16620        for (int is = app.services.size()-1;
16621                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16622                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16623                        || procState > ActivityManager.PROCESS_STATE_TOP);
16624                is--) {
16625            ServiceRecord s = app.services.valueAt(is);
16626            if (s.startRequested) {
16627                app.hasStartedServices = true;
16628                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16629                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16630                }
16631                if (app.hasShownUi && app != mHomeProcess) {
16632                    // If this process has shown some UI, let it immediately
16633                    // go to the LRU list because it may be pretty heavy with
16634                    // UI stuff.  We'll tag it with a label just to help
16635                    // debug and understand what is going on.
16636                    if (adj > ProcessList.SERVICE_ADJ) {
16637                        app.adjType = "cch-started-ui-services";
16638                    }
16639                } else {
16640                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16641                        // This service has seen some activity within
16642                        // recent memory, so we will keep its process ahead
16643                        // of the background processes.
16644                        if (adj > ProcessList.SERVICE_ADJ) {
16645                            adj = ProcessList.SERVICE_ADJ;
16646                            app.adjType = "started-services";
16647                            app.cached = false;
16648                        }
16649                    }
16650                    // If we have let the service slide into the background
16651                    // state, still have some text describing what it is doing
16652                    // even though the service no longer has an impact.
16653                    if (adj > ProcessList.SERVICE_ADJ) {
16654                        app.adjType = "cch-started-services";
16655                    }
16656                }
16657            }
16658            for (int conni = s.connections.size()-1;
16659                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16660                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16661                            || procState > ActivityManager.PROCESS_STATE_TOP);
16662                    conni--) {
16663                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16664                for (int i = 0;
16665                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16666                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16667                                || procState > ActivityManager.PROCESS_STATE_TOP);
16668                        i++) {
16669                    // XXX should compute this based on the max of
16670                    // all connected clients.
16671                    ConnectionRecord cr = clist.get(i);
16672                    if (cr.binding.client == app) {
16673                        // Binding to ourself is not interesting.
16674                        continue;
16675                    }
16676                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16677                        ProcessRecord client = cr.binding.client;
16678                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16679                                TOP_APP, doingAll, now);
16680                        int clientProcState = client.curProcState;
16681                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16682                            // If the other app is cached for any reason, for purposes here
16683                            // we are going to consider it empty.  The specific cached state
16684                            // doesn't propagate except under certain conditions.
16685                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16686                        }
16687                        String adjType = null;
16688                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16689                            // Not doing bind OOM management, so treat
16690                            // this guy more like a started service.
16691                            if (app.hasShownUi && app != mHomeProcess) {
16692                                // If this process has shown some UI, let it immediately
16693                                // go to the LRU list because it may be pretty heavy with
16694                                // UI stuff.  We'll tag it with a label just to help
16695                                // debug and understand what is going on.
16696                                if (adj > clientAdj) {
16697                                    adjType = "cch-bound-ui-services";
16698                                }
16699                                app.cached = false;
16700                                clientAdj = adj;
16701                                clientProcState = procState;
16702                            } else {
16703                                if (now >= (s.lastActivity
16704                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16705                                    // This service has not seen activity within
16706                                    // recent memory, so allow it to drop to the
16707                                    // LRU list if there is no other reason to keep
16708                                    // it around.  We'll also tag it with a label just
16709                                    // to help debug and undertand what is going on.
16710                                    if (adj > clientAdj) {
16711                                        adjType = "cch-bound-services";
16712                                    }
16713                                    clientAdj = adj;
16714                                }
16715                            }
16716                        }
16717                        if (adj > clientAdj) {
16718                            // If this process has recently shown UI, and
16719                            // the process that is binding to it is less
16720                            // important than being visible, then we don't
16721                            // care about the binding as much as we care
16722                            // about letting this process get into the LRU
16723                            // list to be killed and restarted if needed for
16724                            // memory.
16725                            if (app.hasShownUi && app != mHomeProcess
16726                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16727                                adjType = "cch-bound-ui-services";
16728                            } else {
16729                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16730                                        |Context.BIND_IMPORTANT)) != 0) {
16731                                    adj = clientAdj;
16732                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16733                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16734                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16735                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16736                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16737                                    adj = clientAdj;
16738                                } else {
16739                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16740                                        adj = ProcessList.VISIBLE_APP_ADJ;
16741                                    }
16742                                }
16743                                if (!client.cached) {
16744                                    app.cached = false;
16745                                }
16746                                adjType = "service";
16747                            }
16748                        }
16749                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16750                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16751                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16752                            }
16753                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16754                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16755                                    // Special handling of clients who are in the top state.
16756                                    // We *may* want to consider this process to be in the
16757                                    // top state as well, but only if there is not another
16758                                    // reason for it to be running.  Being on the top is a
16759                                    // special state, meaning you are specifically running
16760                                    // for the current top app.  If the process is already
16761                                    // running in the background for some other reason, it
16762                                    // is more important to continue considering it to be
16763                                    // in the background state.
16764                                    mayBeTop = true;
16765                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16766                                } else {
16767                                    // Special handling for above-top states (persistent
16768                                    // processes).  These should not bring the current process
16769                                    // into the top state, since they are not on top.  Instead
16770                                    // give them the best state after that.
16771                                    clientProcState =
16772                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16773                                }
16774                            }
16775                        } else {
16776                            if (clientProcState <
16777                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16778                                clientProcState =
16779                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16780                            }
16781                        }
16782                        if (procState > clientProcState) {
16783                            procState = clientProcState;
16784                        }
16785                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16786                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16787                            app.pendingUiClean = true;
16788                        }
16789                        if (adjType != null) {
16790                            app.adjType = adjType;
16791                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16792                                    .REASON_SERVICE_IN_USE;
16793                            app.adjSource = cr.binding.client;
16794                            app.adjSourceProcState = clientProcState;
16795                            app.adjTarget = s.name;
16796                        }
16797                    }
16798                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16799                        app.treatLikeActivity = true;
16800                    }
16801                    final ActivityRecord a = cr.activity;
16802                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16803                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16804                                (a.visible || a.state == ActivityState.RESUMED
16805                                 || a.state == ActivityState.PAUSING)) {
16806                            adj = ProcessList.FOREGROUND_APP_ADJ;
16807                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16808                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16809                            }
16810                            app.cached = false;
16811                            app.adjType = "service";
16812                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16813                                    .REASON_SERVICE_IN_USE;
16814                            app.adjSource = a;
16815                            app.adjSourceProcState = procState;
16816                            app.adjTarget = s.name;
16817                        }
16818                    }
16819                }
16820            }
16821        }
16822
16823        for (int provi = app.pubProviders.size()-1;
16824                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16825                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16826                        || procState > ActivityManager.PROCESS_STATE_TOP);
16827                provi--) {
16828            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16829            for (int i = cpr.connections.size()-1;
16830                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16831                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16832                            || procState > ActivityManager.PROCESS_STATE_TOP);
16833                    i--) {
16834                ContentProviderConnection conn = cpr.connections.get(i);
16835                ProcessRecord client = conn.client;
16836                if (client == app) {
16837                    // Being our own client is not interesting.
16838                    continue;
16839                }
16840                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16841                int clientProcState = client.curProcState;
16842                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16843                    // If the other app is cached for any reason, for purposes here
16844                    // we are going to consider it empty.
16845                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16846                }
16847                if (adj > clientAdj) {
16848                    if (app.hasShownUi && app != mHomeProcess
16849                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16850                        app.adjType = "cch-ui-provider";
16851                    } else {
16852                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16853                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16854                        app.adjType = "provider";
16855                    }
16856                    app.cached &= client.cached;
16857                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16858                            .REASON_PROVIDER_IN_USE;
16859                    app.adjSource = client;
16860                    app.adjSourceProcState = clientProcState;
16861                    app.adjTarget = cpr.name;
16862                }
16863                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16864                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16865                        // Special handling of clients who are in the top state.
16866                        // We *may* want to consider this process to be in the
16867                        // top state as well, but only if there is not another
16868                        // reason for it to be running.  Being on the top is a
16869                        // special state, meaning you are specifically running
16870                        // for the current top app.  If the process is already
16871                        // running in the background for some other reason, it
16872                        // is more important to continue considering it to be
16873                        // in the background state.
16874                        mayBeTop = true;
16875                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16876                    } else {
16877                        // Special handling for above-top states (persistent
16878                        // processes).  These should not bring the current process
16879                        // into the top state, since they are not on top.  Instead
16880                        // give them the best state after that.
16881                        clientProcState =
16882                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16883                    }
16884                }
16885                if (procState > clientProcState) {
16886                    procState = clientProcState;
16887                }
16888                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16889                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16890                }
16891            }
16892            // If the provider has external (non-framework) process
16893            // dependencies, ensure that its adjustment is at least
16894            // FOREGROUND_APP_ADJ.
16895            if (cpr.hasExternalProcessHandles()) {
16896                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16897                    adj = ProcessList.FOREGROUND_APP_ADJ;
16898                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16899                    app.cached = false;
16900                    app.adjType = "provider";
16901                    app.adjTarget = cpr.name;
16902                }
16903                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16904                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16905                }
16906            }
16907        }
16908
16909        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16910            // A client of one of our services or providers is in the top state.  We
16911            // *may* want to be in the top state, but not if we are already running in
16912            // the background for some other reason.  For the decision here, we are going
16913            // to pick out a few specific states that we want to remain in when a client
16914            // is top (states that tend to be longer-term) and otherwise allow it to go
16915            // to the top state.
16916            switch (procState) {
16917                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16918                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16919                case ActivityManager.PROCESS_STATE_SERVICE:
16920                    // These all are longer-term states, so pull them up to the top
16921                    // of the background states, but not all the way to the top state.
16922                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16923                    break;
16924                default:
16925                    // Otherwise, top is a better choice, so take it.
16926                    procState = ActivityManager.PROCESS_STATE_TOP;
16927                    break;
16928            }
16929        }
16930
16931        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16932            if (app.hasClientActivities) {
16933                // This is a cached process, but with client activities.  Mark it so.
16934                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16935                app.adjType = "cch-client-act";
16936            } else if (app.treatLikeActivity) {
16937                // This is a cached process, but somebody wants us to treat it like it has
16938                // an activity, okay!
16939                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16940                app.adjType = "cch-as-act";
16941            }
16942        }
16943
16944        if (adj == ProcessList.SERVICE_ADJ) {
16945            if (doingAll) {
16946                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16947                mNewNumServiceProcs++;
16948                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16949                if (!app.serviceb) {
16950                    // This service isn't far enough down on the LRU list to
16951                    // normally be a B service, but if we are low on RAM and it
16952                    // is large we want to force it down since we would prefer to
16953                    // keep launcher over it.
16954                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16955                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16956                        app.serviceHighRam = true;
16957                        app.serviceb = true;
16958                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16959                    } else {
16960                        mNewNumAServiceProcs++;
16961                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16962                    }
16963                } else {
16964                    app.serviceHighRam = false;
16965                }
16966            }
16967            if (app.serviceb) {
16968                adj = ProcessList.SERVICE_B_ADJ;
16969            }
16970        }
16971
16972        app.curRawAdj = adj;
16973
16974        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16975        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16976        if (adj > app.maxAdj) {
16977            adj = app.maxAdj;
16978            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16979                schedGroup = Process.THREAD_GROUP_DEFAULT;
16980            }
16981        }
16982
16983        // Do final modification to adj.  Everything we do between here and applying
16984        // the final setAdj must be done in this function, because we will also use
16985        // it when computing the final cached adj later.  Note that we don't need to
16986        // worry about this for max adj above, since max adj will always be used to
16987        // keep it out of the cached vaues.
16988        app.curAdj = app.modifyRawOomAdj(adj);
16989        app.curSchedGroup = schedGroup;
16990        app.curProcState = procState;
16991        app.foregroundActivities = foregroundActivities;
16992
16993        return app.curRawAdj;
16994    }
16995
16996    /**
16997     * Schedule PSS collection of a process.
16998     */
16999    void requestPssLocked(ProcessRecord proc, int procState) {
17000        if (mPendingPssProcesses.contains(proc)) {
17001            return;
17002        }
17003        if (mPendingPssProcesses.size() == 0) {
17004            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17005        }
17006        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17007        proc.pssProcState = procState;
17008        mPendingPssProcesses.add(proc);
17009    }
17010
17011    /**
17012     * Schedule PSS collection of all processes.
17013     */
17014    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17015        if (!always) {
17016            if (now < (mLastFullPssTime +
17017                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17018                return;
17019            }
17020        }
17021        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17022        mLastFullPssTime = now;
17023        mFullPssPending = true;
17024        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17025        mPendingPssProcesses.clear();
17026        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17027            ProcessRecord app = mLruProcesses.get(i);
17028            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17029                app.pssProcState = app.setProcState;
17030                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17031                        isSleeping(), now);
17032                mPendingPssProcesses.add(app);
17033            }
17034        }
17035        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17036    }
17037
17038    /**
17039     * Ask a given process to GC right now.
17040     */
17041    final void performAppGcLocked(ProcessRecord app) {
17042        try {
17043            app.lastRequestedGc = SystemClock.uptimeMillis();
17044            if (app.thread != null) {
17045                if (app.reportLowMemory) {
17046                    app.reportLowMemory = false;
17047                    app.thread.scheduleLowMemory();
17048                } else {
17049                    app.thread.processInBackground();
17050                }
17051            }
17052        } catch (Exception e) {
17053            // whatever.
17054        }
17055    }
17056
17057    /**
17058     * Returns true if things are idle enough to perform GCs.
17059     */
17060    private final boolean canGcNowLocked() {
17061        boolean processingBroadcasts = false;
17062        for (BroadcastQueue q : mBroadcastQueues) {
17063            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17064                processingBroadcasts = true;
17065            }
17066        }
17067        return !processingBroadcasts
17068                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17069    }
17070
17071    /**
17072     * Perform GCs on all processes that are waiting for it, but only
17073     * if things are idle.
17074     */
17075    final void performAppGcsLocked() {
17076        final int N = mProcessesToGc.size();
17077        if (N <= 0) {
17078            return;
17079        }
17080        if (canGcNowLocked()) {
17081            while (mProcessesToGc.size() > 0) {
17082                ProcessRecord proc = mProcessesToGc.remove(0);
17083                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17084                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17085                            <= SystemClock.uptimeMillis()) {
17086                        // To avoid spamming the system, we will GC processes one
17087                        // at a time, waiting a few seconds between each.
17088                        performAppGcLocked(proc);
17089                        scheduleAppGcsLocked();
17090                        return;
17091                    } else {
17092                        // It hasn't been long enough since we last GCed this
17093                        // process...  put it in the list to wait for its time.
17094                        addProcessToGcListLocked(proc);
17095                        break;
17096                    }
17097                }
17098            }
17099
17100            scheduleAppGcsLocked();
17101        }
17102    }
17103
17104    /**
17105     * If all looks good, perform GCs on all processes waiting for them.
17106     */
17107    final void performAppGcsIfAppropriateLocked() {
17108        if (canGcNowLocked()) {
17109            performAppGcsLocked();
17110            return;
17111        }
17112        // Still not idle, wait some more.
17113        scheduleAppGcsLocked();
17114    }
17115
17116    /**
17117     * Schedule the execution of all pending app GCs.
17118     */
17119    final void scheduleAppGcsLocked() {
17120        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17121
17122        if (mProcessesToGc.size() > 0) {
17123            // Schedule a GC for the time to the next process.
17124            ProcessRecord proc = mProcessesToGc.get(0);
17125            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17126
17127            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17128            long now = SystemClock.uptimeMillis();
17129            if (when < (now+GC_TIMEOUT)) {
17130                when = now + GC_TIMEOUT;
17131            }
17132            mHandler.sendMessageAtTime(msg, when);
17133        }
17134    }
17135
17136    /**
17137     * Add a process to the array of processes waiting to be GCed.  Keeps the
17138     * list in sorted order by the last GC time.  The process can't already be
17139     * on the list.
17140     */
17141    final void addProcessToGcListLocked(ProcessRecord proc) {
17142        boolean added = false;
17143        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17144            if (mProcessesToGc.get(i).lastRequestedGc <
17145                    proc.lastRequestedGc) {
17146                added = true;
17147                mProcessesToGc.add(i+1, proc);
17148                break;
17149            }
17150        }
17151        if (!added) {
17152            mProcessesToGc.add(0, proc);
17153        }
17154    }
17155
17156    /**
17157     * Set up to ask a process to GC itself.  This will either do it
17158     * immediately, or put it on the list of processes to gc the next
17159     * time things are idle.
17160     */
17161    final void scheduleAppGcLocked(ProcessRecord app) {
17162        long now = SystemClock.uptimeMillis();
17163        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17164            return;
17165        }
17166        if (!mProcessesToGc.contains(app)) {
17167            addProcessToGcListLocked(app);
17168            scheduleAppGcsLocked();
17169        }
17170    }
17171
17172    final void checkExcessivePowerUsageLocked(boolean doKills) {
17173        updateCpuStatsNow();
17174
17175        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17176        boolean doWakeKills = doKills;
17177        boolean doCpuKills = doKills;
17178        if (mLastPowerCheckRealtime == 0) {
17179            doWakeKills = false;
17180        }
17181        if (mLastPowerCheckUptime == 0) {
17182            doCpuKills = false;
17183        }
17184        if (stats.isScreenOn()) {
17185            doWakeKills = false;
17186        }
17187        final long curRealtime = SystemClock.elapsedRealtime();
17188        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17189        final long curUptime = SystemClock.uptimeMillis();
17190        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17191        mLastPowerCheckRealtime = curRealtime;
17192        mLastPowerCheckUptime = curUptime;
17193        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17194            doWakeKills = false;
17195        }
17196        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17197            doCpuKills = false;
17198        }
17199        int i = mLruProcesses.size();
17200        while (i > 0) {
17201            i--;
17202            ProcessRecord app = mLruProcesses.get(i);
17203            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17204                long wtime;
17205                synchronized (stats) {
17206                    wtime = stats.getProcessWakeTime(app.info.uid,
17207                            app.pid, curRealtime);
17208                }
17209                long wtimeUsed = wtime - app.lastWakeTime;
17210                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17211                if (DEBUG_POWER) {
17212                    StringBuilder sb = new StringBuilder(128);
17213                    sb.append("Wake for ");
17214                    app.toShortString(sb);
17215                    sb.append(": over ");
17216                    TimeUtils.formatDuration(realtimeSince, sb);
17217                    sb.append(" used ");
17218                    TimeUtils.formatDuration(wtimeUsed, sb);
17219                    sb.append(" (");
17220                    sb.append((wtimeUsed*100)/realtimeSince);
17221                    sb.append("%)");
17222                    Slog.i(TAG, sb.toString());
17223                    sb.setLength(0);
17224                    sb.append("CPU for ");
17225                    app.toShortString(sb);
17226                    sb.append(": over ");
17227                    TimeUtils.formatDuration(uptimeSince, sb);
17228                    sb.append(" used ");
17229                    TimeUtils.formatDuration(cputimeUsed, sb);
17230                    sb.append(" (");
17231                    sb.append((cputimeUsed*100)/uptimeSince);
17232                    sb.append("%)");
17233                    Slog.i(TAG, sb.toString());
17234                }
17235                // If a process has held a wake lock for more
17236                // than 50% of the time during this period,
17237                // that sounds bad.  Kill!
17238                if (doWakeKills && realtimeSince > 0
17239                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17240                    synchronized (stats) {
17241                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17242                                realtimeSince, wtimeUsed);
17243                    }
17244                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17245                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17246                } else if (doCpuKills && uptimeSince > 0
17247                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17248                    synchronized (stats) {
17249                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17250                                uptimeSince, cputimeUsed);
17251                    }
17252                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17253                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17254                } else {
17255                    app.lastWakeTime = wtime;
17256                    app.lastCpuTime = app.curCpuTime;
17257                }
17258            }
17259        }
17260    }
17261
17262    private final boolean applyOomAdjLocked(ProcessRecord app,
17263            ProcessRecord TOP_APP, boolean doingAll, long now) {
17264        boolean success = true;
17265
17266        if (app.curRawAdj != app.setRawAdj) {
17267            app.setRawAdj = app.curRawAdj;
17268        }
17269
17270        int changes = 0;
17271
17272        if (app.curAdj != app.setAdj) {
17273            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17274            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17275                TAG, "Set " + app.pid + " " + app.processName +
17276                " adj " + app.curAdj + ": " + app.adjType);
17277            app.setAdj = app.curAdj;
17278        }
17279
17280        if (app.setSchedGroup != app.curSchedGroup) {
17281            app.setSchedGroup = app.curSchedGroup;
17282            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17283                    "Setting process group of " + app.processName
17284                    + " to " + app.curSchedGroup);
17285            if (app.waitingToKill != null &&
17286                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17287                app.kill(app.waitingToKill, true);
17288                success = false;
17289            } else {
17290                if (true) {
17291                    long oldId = Binder.clearCallingIdentity();
17292                    try {
17293                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17294                    } catch (Exception e) {
17295                        Slog.w(TAG, "Failed setting process group of " + app.pid
17296                                + " to " + app.curSchedGroup);
17297                        e.printStackTrace();
17298                    } finally {
17299                        Binder.restoreCallingIdentity(oldId);
17300                    }
17301                } else {
17302                    if (app.thread != null) {
17303                        try {
17304                            app.thread.setSchedulingGroup(app.curSchedGroup);
17305                        } catch (RemoteException e) {
17306                        }
17307                    }
17308                }
17309                Process.setSwappiness(app.pid,
17310                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17311            }
17312        }
17313        if (app.repForegroundActivities != app.foregroundActivities) {
17314            app.repForegroundActivities = app.foregroundActivities;
17315            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17316        }
17317        if (app.repProcState != app.curProcState) {
17318            app.repProcState = app.curProcState;
17319            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17320            if (app.thread != null) {
17321                try {
17322                    if (false) {
17323                        //RuntimeException h = new RuntimeException("here");
17324                        Slog.i(TAG, "Sending new process state " + app.repProcState
17325                                + " to " + app /*, h*/);
17326                    }
17327                    app.thread.setProcessState(app.repProcState);
17328                } catch (RemoteException e) {
17329                }
17330            }
17331        }
17332        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17333                app.setProcState)) {
17334            app.lastStateTime = now;
17335            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17336                    isSleeping(), now);
17337            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17338                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17339                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17340                    + (app.nextPssTime-now) + ": " + app);
17341        } else {
17342            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17343                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17344                requestPssLocked(app, app.setProcState);
17345                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17346                        isSleeping(), now);
17347            } else if (false && DEBUG_PSS) {
17348                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17349            }
17350        }
17351        if (app.setProcState != app.curProcState) {
17352            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17353                    "Proc state change of " + app.processName
17354                    + " to " + app.curProcState);
17355            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17356            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17357            if (setImportant && !curImportant) {
17358                // This app is no longer something we consider important enough to allow to
17359                // use arbitrary amounts of battery power.  Note
17360                // its current wake lock time to later know to kill it if
17361                // it is not behaving well.
17362                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17363                synchronized (stats) {
17364                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17365                            app.pid, SystemClock.elapsedRealtime());
17366                }
17367                app.lastCpuTime = app.curCpuTime;
17368
17369            }
17370            app.setProcState = app.curProcState;
17371            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17372                app.notCachedSinceIdle = false;
17373            }
17374            if (!doingAll) {
17375                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17376            } else {
17377                app.procStateChanged = true;
17378            }
17379        }
17380
17381        if (changes != 0) {
17382            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17383            int i = mPendingProcessChanges.size()-1;
17384            ProcessChangeItem item = null;
17385            while (i >= 0) {
17386                item = mPendingProcessChanges.get(i);
17387                if (item.pid == app.pid) {
17388                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17389                    break;
17390                }
17391                i--;
17392            }
17393            if (i < 0) {
17394                // No existing item in pending changes; need a new one.
17395                final int NA = mAvailProcessChanges.size();
17396                if (NA > 0) {
17397                    item = mAvailProcessChanges.remove(NA-1);
17398                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17399                } else {
17400                    item = new ProcessChangeItem();
17401                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17402                }
17403                item.changes = 0;
17404                item.pid = app.pid;
17405                item.uid = app.info.uid;
17406                if (mPendingProcessChanges.size() == 0) {
17407                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17408                            "*** Enqueueing dispatch processes changed!");
17409                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17410                }
17411                mPendingProcessChanges.add(item);
17412            }
17413            item.changes |= changes;
17414            item.processState = app.repProcState;
17415            item.foregroundActivities = app.repForegroundActivities;
17416            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17417                    + Integer.toHexString(System.identityHashCode(item))
17418                    + " " + app.toShortString() + ": changes=" + item.changes
17419                    + " procState=" + item.processState
17420                    + " foreground=" + item.foregroundActivities
17421                    + " type=" + app.adjType + " source=" + app.adjSource
17422                    + " target=" + app.adjTarget);
17423        }
17424
17425        return success;
17426    }
17427
17428    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17429        if (proc.thread != null) {
17430            if (proc.baseProcessTracker != null) {
17431                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17432            }
17433            if (proc.repProcState >= 0) {
17434                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17435                        proc.repProcState);
17436            }
17437        }
17438    }
17439
17440    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17441            ProcessRecord TOP_APP, boolean doingAll, long now) {
17442        if (app.thread == null) {
17443            return false;
17444        }
17445
17446        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17447
17448        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17449    }
17450
17451    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17452            boolean oomAdj) {
17453        if (isForeground != proc.foregroundServices) {
17454            proc.foregroundServices = isForeground;
17455            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17456                    proc.info.uid);
17457            if (isForeground) {
17458                if (curProcs == null) {
17459                    curProcs = new ArrayList<ProcessRecord>();
17460                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17461                }
17462                if (!curProcs.contains(proc)) {
17463                    curProcs.add(proc);
17464                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17465                            proc.info.packageName, proc.info.uid);
17466                }
17467            } else {
17468                if (curProcs != null) {
17469                    if (curProcs.remove(proc)) {
17470                        mBatteryStatsService.noteEvent(
17471                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17472                                proc.info.packageName, proc.info.uid);
17473                        if (curProcs.size() <= 0) {
17474                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17475                        }
17476                    }
17477                }
17478            }
17479            if (oomAdj) {
17480                updateOomAdjLocked();
17481            }
17482        }
17483    }
17484
17485    private final ActivityRecord resumedAppLocked() {
17486        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17487        String pkg;
17488        int uid;
17489        if (act != null) {
17490            pkg = act.packageName;
17491            uid = act.info.applicationInfo.uid;
17492        } else {
17493            pkg = null;
17494            uid = -1;
17495        }
17496        // Has the UID or resumed package name changed?
17497        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17498                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17499            if (mCurResumedPackage != null) {
17500                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17501                        mCurResumedPackage, mCurResumedUid);
17502            }
17503            mCurResumedPackage = pkg;
17504            mCurResumedUid = uid;
17505            if (mCurResumedPackage != null) {
17506                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17507                        mCurResumedPackage, mCurResumedUid);
17508            }
17509        }
17510        return act;
17511    }
17512
17513    final boolean updateOomAdjLocked(ProcessRecord app) {
17514        final ActivityRecord TOP_ACT = resumedAppLocked();
17515        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17516        final boolean wasCached = app.cached;
17517
17518        mAdjSeq++;
17519
17520        // This is the desired cached adjusment we want to tell it to use.
17521        // If our app is currently cached, we know it, and that is it.  Otherwise,
17522        // we don't know it yet, and it needs to now be cached we will then
17523        // need to do a complete oom adj.
17524        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17525                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17526        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17527                SystemClock.uptimeMillis());
17528        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17529            // Changed to/from cached state, so apps after it in the LRU
17530            // list may also be changed.
17531            updateOomAdjLocked();
17532        }
17533        return success;
17534    }
17535
17536    final void updateOomAdjLocked() {
17537        final ActivityRecord TOP_ACT = resumedAppLocked();
17538        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17539        final long now = SystemClock.uptimeMillis();
17540        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17541        final int N = mLruProcesses.size();
17542
17543        if (false) {
17544            RuntimeException e = new RuntimeException();
17545            e.fillInStackTrace();
17546            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17547        }
17548
17549        mAdjSeq++;
17550        mNewNumServiceProcs = 0;
17551        mNewNumAServiceProcs = 0;
17552
17553        final int emptyProcessLimit;
17554        final int cachedProcessLimit;
17555        if (mProcessLimit <= 0) {
17556            emptyProcessLimit = cachedProcessLimit = 0;
17557        } else if (mProcessLimit == 1) {
17558            emptyProcessLimit = 1;
17559            cachedProcessLimit = 0;
17560        } else {
17561            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17562            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17563        }
17564
17565        // Let's determine how many processes we have running vs.
17566        // how many slots we have for background processes; we may want
17567        // to put multiple processes in a slot of there are enough of
17568        // them.
17569        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17570                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17571        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17572        if (numEmptyProcs > cachedProcessLimit) {
17573            // If there are more empty processes than our limit on cached
17574            // processes, then use the cached process limit for the factor.
17575            // This ensures that the really old empty processes get pushed
17576            // down to the bottom, so if we are running low on memory we will
17577            // have a better chance at keeping around more cached processes
17578            // instead of a gazillion empty processes.
17579            numEmptyProcs = cachedProcessLimit;
17580        }
17581        int emptyFactor = numEmptyProcs/numSlots;
17582        if (emptyFactor < 1) emptyFactor = 1;
17583        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17584        if (cachedFactor < 1) cachedFactor = 1;
17585        int stepCached = 0;
17586        int stepEmpty = 0;
17587        int numCached = 0;
17588        int numEmpty = 0;
17589        int numTrimming = 0;
17590
17591        mNumNonCachedProcs = 0;
17592        mNumCachedHiddenProcs = 0;
17593
17594        // First update the OOM adjustment for each of the
17595        // application processes based on their current state.
17596        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17597        int nextCachedAdj = curCachedAdj+1;
17598        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17599        int nextEmptyAdj = curEmptyAdj+2;
17600        for (int i=N-1; i>=0; i--) {
17601            ProcessRecord app = mLruProcesses.get(i);
17602            if (!app.killedByAm && app.thread != null) {
17603                app.procStateChanged = false;
17604                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17605
17606                // If we haven't yet assigned the final cached adj
17607                // to the process, do that now.
17608                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17609                    switch (app.curProcState) {
17610                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17611                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17612                            // This process is a cached process holding activities...
17613                            // assign it the next cached value for that type, and then
17614                            // step that cached level.
17615                            app.curRawAdj = curCachedAdj;
17616                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17617                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17618                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17619                                    + ")");
17620                            if (curCachedAdj != nextCachedAdj) {
17621                                stepCached++;
17622                                if (stepCached >= cachedFactor) {
17623                                    stepCached = 0;
17624                                    curCachedAdj = nextCachedAdj;
17625                                    nextCachedAdj += 2;
17626                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17627                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17628                                    }
17629                                }
17630                            }
17631                            break;
17632                        default:
17633                            // For everything else, assign next empty cached process
17634                            // level and bump that up.  Note that this means that
17635                            // long-running services that have dropped down to the
17636                            // cached level will be treated as empty (since their process
17637                            // state is still as a service), which is what we want.
17638                            app.curRawAdj = curEmptyAdj;
17639                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17640                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17641                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17642                                    + ")");
17643                            if (curEmptyAdj != nextEmptyAdj) {
17644                                stepEmpty++;
17645                                if (stepEmpty >= emptyFactor) {
17646                                    stepEmpty = 0;
17647                                    curEmptyAdj = nextEmptyAdj;
17648                                    nextEmptyAdj += 2;
17649                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17650                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17651                                    }
17652                                }
17653                            }
17654                            break;
17655                    }
17656                }
17657
17658                applyOomAdjLocked(app, TOP_APP, true, now);
17659
17660                // Count the number of process types.
17661                switch (app.curProcState) {
17662                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17663                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17664                        mNumCachedHiddenProcs++;
17665                        numCached++;
17666                        if (numCached > cachedProcessLimit) {
17667                            app.kill("cached #" + numCached, true);
17668                        }
17669                        break;
17670                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17671                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17672                                && app.lastActivityTime < oldTime) {
17673                            app.kill("empty for "
17674                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17675                                    / 1000) + "s", true);
17676                        } else {
17677                            numEmpty++;
17678                            if (numEmpty > emptyProcessLimit) {
17679                                app.kill("empty #" + numEmpty, true);
17680                            }
17681                        }
17682                        break;
17683                    default:
17684                        mNumNonCachedProcs++;
17685                        break;
17686                }
17687
17688                if (app.isolated && app.services.size() <= 0) {
17689                    // If this is an isolated process, and there are no
17690                    // services running in it, then the process is no longer
17691                    // needed.  We agressively kill these because we can by
17692                    // definition not re-use the same process again, and it is
17693                    // good to avoid having whatever code was running in them
17694                    // left sitting around after no longer needed.
17695                    app.kill("isolated not needed", true);
17696                }
17697
17698                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17699                        && !app.killedByAm) {
17700                    numTrimming++;
17701                }
17702            }
17703        }
17704
17705        mNumServiceProcs = mNewNumServiceProcs;
17706
17707        // Now determine the memory trimming level of background processes.
17708        // Unfortunately we need to start at the back of the list to do this
17709        // properly.  We only do this if the number of background apps we
17710        // are managing to keep around is less than half the maximum we desire;
17711        // if we are keeping a good number around, we'll let them use whatever
17712        // memory they want.
17713        final int numCachedAndEmpty = numCached + numEmpty;
17714        int memFactor;
17715        if (numCached <= ProcessList.TRIM_CACHED_APPS
17716                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17717            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17718                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17719            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17720                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17721            } else {
17722                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17723            }
17724        } else {
17725            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17726        }
17727        // We always allow the memory level to go up (better).  We only allow it to go
17728        // down if we are in a state where that is allowed, *and* the total number of processes
17729        // has gone down since last time.
17730        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17731                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17732                + " last=" + mLastNumProcesses);
17733        if (memFactor > mLastMemoryLevel) {
17734            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17735                memFactor = mLastMemoryLevel;
17736                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17737            }
17738        }
17739        mLastMemoryLevel = memFactor;
17740        mLastNumProcesses = mLruProcesses.size();
17741        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17742        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17743        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17744            if (mLowRamStartTime == 0) {
17745                mLowRamStartTime = now;
17746            }
17747            int step = 0;
17748            int fgTrimLevel;
17749            switch (memFactor) {
17750                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17751                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17752                    break;
17753                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17754                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17755                    break;
17756                default:
17757                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17758                    break;
17759            }
17760            int factor = numTrimming/3;
17761            int minFactor = 2;
17762            if (mHomeProcess != null) minFactor++;
17763            if (mPreviousProcess != null) minFactor++;
17764            if (factor < minFactor) factor = minFactor;
17765            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17766            for (int i=N-1; i>=0; i--) {
17767                ProcessRecord app = mLruProcesses.get(i);
17768                if (allChanged || app.procStateChanged) {
17769                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17770                    app.procStateChanged = false;
17771                }
17772                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17773                        && !app.killedByAm) {
17774                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17775                        try {
17776                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17777                                    "Trimming memory of " + app.processName
17778                                    + " to " + curLevel);
17779                            app.thread.scheduleTrimMemory(curLevel);
17780                        } catch (RemoteException e) {
17781                        }
17782                        if (false) {
17783                            // For now we won't do this; our memory trimming seems
17784                            // to be good enough at this point that destroying
17785                            // activities causes more harm than good.
17786                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17787                                    && app != mHomeProcess && app != mPreviousProcess) {
17788                                // Need to do this on its own message because the stack may not
17789                                // be in a consistent state at this point.
17790                                // For these apps we will also finish their activities
17791                                // to help them free memory.
17792                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17793                            }
17794                        }
17795                    }
17796                    app.trimMemoryLevel = curLevel;
17797                    step++;
17798                    if (step >= factor) {
17799                        step = 0;
17800                        switch (curLevel) {
17801                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17802                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17803                                break;
17804                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17805                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17806                                break;
17807                        }
17808                    }
17809                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17810                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17811                            && app.thread != null) {
17812                        try {
17813                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17814                                    "Trimming memory of heavy-weight " + app.processName
17815                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17816                            app.thread.scheduleTrimMemory(
17817                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17818                        } catch (RemoteException e) {
17819                        }
17820                    }
17821                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17822                } else {
17823                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17824                            || app.systemNoUi) && app.pendingUiClean) {
17825                        // If this application is now in the background and it
17826                        // had done UI, then give it the special trim level to
17827                        // have it free UI resources.
17828                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17829                        if (app.trimMemoryLevel < level && app.thread != null) {
17830                            try {
17831                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17832                                        "Trimming memory of bg-ui " + app.processName
17833                                        + " to " + level);
17834                                app.thread.scheduleTrimMemory(level);
17835                            } catch (RemoteException e) {
17836                            }
17837                        }
17838                        app.pendingUiClean = false;
17839                    }
17840                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17841                        try {
17842                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17843                                    "Trimming memory of fg " + app.processName
17844                                    + " to " + fgTrimLevel);
17845                            app.thread.scheduleTrimMemory(fgTrimLevel);
17846                        } catch (RemoteException e) {
17847                        }
17848                    }
17849                    app.trimMemoryLevel = fgTrimLevel;
17850                }
17851            }
17852        } else {
17853            if (mLowRamStartTime != 0) {
17854                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17855                mLowRamStartTime = 0;
17856            }
17857            for (int i=N-1; i>=0; i--) {
17858                ProcessRecord app = mLruProcesses.get(i);
17859                if (allChanged || app.procStateChanged) {
17860                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17861                    app.procStateChanged = false;
17862                }
17863                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17864                        || app.systemNoUi) && app.pendingUiClean) {
17865                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17866                            && app.thread != null) {
17867                        try {
17868                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17869                                    "Trimming memory of ui hidden " + app.processName
17870                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17871                            app.thread.scheduleTrimMemory(
17872                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17873                        } catch (RemoteException e) {
17874                        }
17875                    }
17876                    app.pendingUiClean = false;
17877                }
17878                app.trimMemoryLevel = 0;
17879            }
17880        }
17881
17882        if (mAlwaysFinishActivities) {
17883            // Need to do this on its own message because the stack may not
17884            // be in a consistent state at this point.
17885            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17886        }
17887
17888        if (allChanged) {
17889            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17890        }
17891
17892        if (mProcessStats.shouldWriteNowLocked(now)) {
17893            mHandler.post(new Runnable() {
17894                @Override public void run() {
17895                    synchronized (ActivityManagerService.this) {
17896                        mProcessStats.writeStateAsyncLocked();
17897                    }
17898                }
17899            });
17900        }
17901
17902        if (DEBUG_OOM_ADJ) {
17903            if (false) {
17904                RuntimeException here = new RuntimeException("here");
17905                here.fillInStackTrace();
17906                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17907            } else {
17908                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17909            }
17910        }
17911    }
17912
17913    final void trimApplications() {
17914        synchronized (this) {
17915            int i;
17916
17917            // First remove any unused application processes whose package
17918            // has been removed.
17919            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17920                final ProcessRecord app = mRemovedProcesses.get(i);
17921                if (app.activities.size() == 0
17922                        && app.curReceiver == null && app.services.size() == 0) {
17923                    Slog.i(
17924                        TAG, "Exiting empty application process "
17925                        + app.processName + " ("
17926                        + (app.thread != null ? app.thread.asBinder() : null)
17927                        + ")\n");
17928                    if (app.pid > 0 && app.pid != MY_PID) {
17929                        app.kill("empty", false);
17930                    } else {
17931                        try {
17932                            app.thread.scheduleExit();
17933                        } catch (Exception e) {
17934                            // Ignore exceptions.
17935                        }
17936                    }
17937                    cleanUpApplicationRecordLocked(app, false, true, -1);
17938                    mRemovedProcesses.remove(i);
17939
17940                    if (app.persistent) {
17941                        addAppLocked(app.info, false, null /* ABI override */);
17942                    }
17943                }
17944            }
17945
17946            // Now update the oom adj for all processes.
17947            updateOomAdjLocked();
17948        }
17949    }
17950
17951    /** This method sends the specified signal to each of the persistent apps */
17952    public void signalPersistentProcesses(int sig) throws RemoteException {
17953        if (sig != Process.SIGNAL_USR1) {
17954            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17955        }
17956
17957        synchronized (this) {
17958            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17959                    != PackageManager.PERMISSION_GRANTED) {
17960                throw new SecurityException("Requires permission "
17961                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17962            }
17963
17964            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17965                ProcessRecord r = mLruProcesses.get(i);
17966                if (r.thread != null && r.persistent) {
17967                    Process.sendSignal(r.pid, sig);
17968                }
17969            }
17970        }
17971    }
17972
17973    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17974        if (proc == null || proc == mProfileProc) {
17975            proc = mProfileProc;
17976            profileType = mProfileType;
17977            clearProfilerLocked();
17978        }
17979        if (proc == null) {
17980            return;
17981        }
17982        try {
17983            proc.thread.profilerControl(false, null, profileType);
17984        } catch (RemoteException e) {
17985            throw new IllegalStateException("Process disappeared");
17986        }
17987    }
17988
17989    private void clearProfilerLocked() {
17990        if (mProfileFd != null) {
17991            try {
17992                mProfileFd.close();
17993            } catch (IOException e) {
17994            }
17995        }
17996        mProfileApp = null;
17997        mProfileProc = null;
17998        mProfileFile = null;
17999        mProfileType = 0;
18000        mAutoStopProfiler = false;
18001        mSamplingInterval = 0;
18002    }
18003
18004    public boolean profileControl(String process, int userId, boolean start,
18005            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18006
18007        try {
18008            synchronized (this) {
18009                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18010                // its own permission.
18011                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18012                        != PackageManager.PERMISSION_GRANTED) {
18013                    throw new SecurityException("Requires permission "
18014                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18015                }
18016
18017                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18018                    throw new IllegalArgumentException("null profile info or fd");
18019                }
18020
18021                ProcessRecord proc = null;
18022                if (process != null) {
18023                    proc = findProcessLocked(process, userId, "profileControl");
18024                }
18025
18026                if (start && (proc == null || proc.thread == null)) {
18027                    throw new IllegalArgumentException("Unknown process: " + process);
18028                }
18029
18030                if (start) {
18031                    stopProfilerLocked(null, 0);
18032                    setProfileApp(proc.info, proc.processName, profilerInfo);
18033                    mProfileProc = proc;
18034                    mProfileType = profileType;
18035                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18036                    try {
18037                        fd = fd.dup();
18038                    } catch (IOException e) {
18039                        fd = null;
18040                    }
18041                    profilerInfo.profileFd = fd;
18042                    proc.thread.profilerControl(start, profilerInfo, profileType);
18043                    fd = null;
18044                    mProfileFd = null;
18045                } else {
18046                    stopProfilerLocked(proc, profileType);
18047                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18048                        try {
18049                            profilerInfo.profileFd.close();
18050                        } catch (IOException e) {
18051                        }
18052                    }
18053                }
18054
18055                return true;
18056            }
18057        } catch (RemoteException e) {
18058            throw new IllegalStateException("Process disappeared");
18059        } finally {
18060            if (profilerInfo != null && profilerInfo.profileFd != null) {
18061                try {
18062                    profilerInfo.profileFd.close();
18063                } catch (IOException e) {
18064                }
18065            }
18066        }
18067    }
18068
18069    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18070        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18071                userId, true, ALLOW_FULL_ONLY, callName, null);
18072        ProcessRecord proc = null;
18073        try {
18074            int pid = Integer.parseInt(process);
18075            synchronized (mPidsSelfLocked) {
18076                proc = mPidsSelfLocked.get(pid);
18077            }
18078        } catch (NumberFormatException e) {
18079        }
18080
18081        if (proc == null) {
18082            ArrayMap<String, SparseArray<ProcessRecord>> all
18083                    = mProcessNames.getMap();
18084            SparseArray<ProcessRecord> procs = all.get(process);
18085            if (procs != null && procs.size() > 0) {
18086                proc = procs.valueAt(0);
18087                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18088                    for (int i=1; i<procs.size(); i++) {
18089                        ProcessRecord thisProc = procs.valueAt(i);
18090                        if (thisProc.userId == userId) {
18091                            proc = thisProc;
18092                            break;
18093                        }
18094                    }
18095                }
18096            }
18097        }
18098
18099        return proc;
18100    }
18101
18102    public boolean dumpHeap(String process, int userId, boolean managed,
18103            String path, ParcelFileDescriptor fd) throws RemoteException {
18104
18105        try {
18106            synchronized (this) {
18107                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18108                // its own permission (same as profileControl).
18109                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18110                        != PackageManager.PERMISSION_GRANTED) {
18111                    throw new SecurityException("Requires permission "
18112                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18113                }
18114
18115                if (fd == null) {
18116                    throw new IllegalArgumentException("null fd");
18117                }
18118
18119                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18120                if (proc == null || proc.thread == null) {
18121                    throw new IllegalArgumentException("Unknown process: " + process);
18122                }
18123
18124                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18125                if (!isDebuggable) {
18126                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18127                        throw new SecurityException("Process not debuggable: " + proc);
18128                    }
18129                }
18130
18131                proc.thread.dumpHeap(managed, path, fd);
18132                fd = null;
18133                return true;
18134            }
18135        } catch (RemoteException e) {
18136            throw new IllegalStateException("Process disappeared");
18137        } finally {
18138            if (fd != null) {
18139                try {
18140                    fd.close();
18141                } catch (IOException e) {
18142                }
18143            }
18144        }
18145    }
18146
18147    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18148    public void monitor() {
18149        synchronized (this) { }
18150    }
18151
18152    void onCoreSettingsChange(Bundle settings) {
18153        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18154            ProcessRecord processRecord = mLruProcesses.get(i);
18155            try {
18156                if (processRecord.thread != null) {
18157                    processRecord.thread.setCoreSettings(settings);
18158                }
18159            } catch (RemoteException re) {
18160                /* ignore */
18161            }
18162        }
18163    }
18164
18165    // Multi-user methods
18166
18167    /**
18168     * Start user, if its not already running, but don't bring it to foreground.
18169     */
18170    @Override
18171    public boolean startUserInBackground(final int userId) {
18172        return startUser(userId, /* foreground */ false);
18173    }
18174
18175    /**
18176     * Start user, if its not already running, and bring it to foreground.
18177     */
18178    boolean startUserInForeground(final int userId, Dialog dlg) {
18179        boolean result = startUser(userId, /* foreground */ true);
18180        dlg.dismiss();
18181        return result;
18182    }
18183
18184    /**
18185     * Refreshes the list of users related to the current user when either a
18186     * user switch happens or when a new related user is started in the
18187     * background.
18188     */
18189    private void updateCurrentProfileIdsLocked() {
18190        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18191                mCurrentUserId, false /* enabledOnly */);
18192        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18193        for (int i = 0; i < currentProfileIds.length; i++) {
18194            currentProfileIds[i] = profiles.get(i).id;
18195        }
18196        mCurrentProfileIds = currentProfileIds;
18197
18198        synchronized (mUserProfileGroupIdsSelfLocked) {
18199            mUserProfileGroupIdsSelfLocked.clear();
18200            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18201            for (int i = 0; i < users.size(); i++) {
18202                UserInfo user = users.get(i);
18203                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18204                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18205                }
18206            }
18207        }
18208    }
18209
18210    private Set getProfileIdsLocked(int userId) {
18211        Set userIds = new HashSet<Integer>();
18212        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18213                userId, false /* enabledOnly */);
18214        for (UserInfo user : profiles) {
18215            userIds.add(Integer.valueOf(user.id));
18216        }
18217        return userIds;
18218    }
18219
18220    @Override
18221    public boolean switchUser(final int userId) {
18222        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18223        String userName;
18224        synchronized (this) {
18225            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18226            if (userInfo == null) {
18227                Slog.w(TAG, "No user info for user #" + userId);
18228                return false;
18229            }
18230            if (userInfo.isManagedProfile()) {
18231                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18232                return false;
18233            }
18234            userName = userInfo.name;
18235            mTargetUserId = userId;
18236        }
18237        mHandler.removeMessages(START_USER_SWITCH_MSG);
18238        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18239        return true;
18240    }
18241
18242    private void showUserSwitchDialog(int userId, String userName) {
18243        // The dialog will show and then initiate the user switch by calling startUserInForeground
18244        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18245                true /* above system */);
18246        d.show();
18247    }
18248
18249    private boolean startUser(final int userId, final boolean foreground) {
18250        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18251                != PackageManager.PERMISSION_GRANTED) {
18252            String msg = "Permission Denial: switchUser() from pid="
18253                    + Binder.getCallingPid()
18254                    + ", uid=" + Binder.getCallingUid()
18255                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18256            Slog.w(TAG, msg);
18257            throw new SecurityException(msg);
18258        }
18259
18260        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18261
18262        final long ident = Binder.clearCallingIdentity();
18263        try {
18264            synchronized (this) {
18265                final int oldUserId = mCurrentUserId;
18266                if (oldUserId == userId) {
18267                    return true;
18268                }
18269
18270                mStackSupervisor.setLockTaskModeLocked(null, false);
18271
18272                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18273                if (userInfo == null) {
18274                    Slog.w(TAG, "No user info for user #" + userId);
18275                    return false;
18276                }
18277                if (foreground && userInfo.isManagedProfile()) {
18278                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18279                    return false;
18280                }
18281
18282                if (foreground) {
18283                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18284                            R.anim.screen_user_enter);
18285                }
18286
18287                boolean needStart = false;
18288
18289                // If the user we are switching to is not currently started, then
18290                // we need to start it now.
18291                if (mStartedUsers.get(userId) == null) {
18292                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18293                    updateStartedUserArrayLocked();
18294                    needStart = true;
18295                }
18296
18297                final Integer userIdInt = Integer.valueOf(userId);
18298                mUserLru.remove(userIdInt);
18299                mUserLru.add(userIdInt);
18300
18301                if (foreground) {
18302                    mCurrentUserId = userId;
18303                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18304                    updateCurrentProfileIdsLocked();
18305                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18306                    // Once the internal notion of the active user has switched, we lock the device
18307                    // with the option to show the user switcher on the keyguard.
18308                    mWindowManager.lockNow(null);
18309                } else {
18310                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18311                    updateCurrentProfileIdsLocked();
18312                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18313                    mUserLru.remove(currentUserIdInt);
18314                    mUserLru.add(currentUserIdInt);
18315                }
18316
18317                final UserStartedState uss = mStartedUsers.get(userId);
18318
18319                // Make sure user is in the started state.  If it is currently
18320                // stopping, we need to knock that off.
18321                if (uss.mState == UserStartedState.STATE_STOPPING) {
18322                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18323                    // so we can just fairly silently bring the user back from
18324                    // the almost-dead.
18325                    uss.mState = UserStartedState.STATE_RUNNING;
18326                    updateStartedUserArrayLocked();
18327                    needStart = true;
18328                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18329                    // This means ACTION_SHUTDOWN has been sent, so we will
18330                    // need to treat this as a new boot of the user.
18331                    uss.mState = UserStartedState.STATE_BOOTING;
18332                    updateStartedUserArrayLocked();
18333                    needStart = true;
18334                }
18335
18336                if (uss.mState == UserStartedState.STATE_BOOTING) {
18337                    // Booting up a new user, need to tell system services about it.
18338                    // Note that this is on the same handler as scheduling of broadcasts,
18339                    // which is important because it needs to go first.
18340                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18341                }
18342
18343                if (foreground) {
18344                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18345                            oldUserId));
18346                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18347                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18348                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18349                            oldUserId, userId, uss));
18350                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18351                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18352                }
18353
18354                if (needStart) {
18355                    // Send USER_STARTED broadcast
18356                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18357                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18358                            | Intent.FLAG_RECEIVER_FOREGROUND);
18359                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18360                    broadcastIntentLocked(null, null, intent,
18361                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18362                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18363                }
18364
18365                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18366                    if (userId != UserHandle.USER_OWNER) {
18367                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18368                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18369                        broadcastIntentLocked(null, null, intent, null,
18370                                new IIntentReceiver.Stub() {
18371                                    public void performReceive(Intent intent, int resultCode,
18372                                            String data, Bundle extras, boolean ordered,
18373                                            boolean sticky, int sendingUser) {
18374                                        onUserInitialized(uss, foreground, oldUserId, userId);
18375                                    }
18376                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18377                                true, false, MY_PID, Process.SYSTEM_UID,
18378                                userId);
18379                        uss.initializing = true;
18380                    } else {
18381                        getUserManagerLocked().makeInitialized(userInfo.id);
18382                    }
18383                }
18384
18385                if (foreground) {
18386                    if (!uss.initializing) {
18387                        moveUserToForeground(uss, oldUserId, userId);
18388                    }
18389                } else {
18390                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18391                }
18392
18393                if (needStart) {
18394                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18395                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18396                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18397                    broadcastIntentLocked(null, null, intent,
18398                            null, new IIntentReceiver.Stub() {
18399                                @Override
18400                                public void performReceive(Intent intent, int resultCode, String data,
18401                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18402                                        throws RemoteException {
18403                                }
18404                            }, 0, null, null,
18405                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18406                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18407                }
18408            }
18409        } finally {
18410            Binder.restoreCallingIdentity(ident);
18411        }
18412
18413        return true;
18414    }
18415
18416    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18417        long ident = Binder.clearCallingIdentity();
18418        try {
18419            Intent intent;
18420            if (oldUserId >= 0) {
18421                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18422                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18423                int count = profiles.size();
18424                for (int i = 0; i < count; i++) {
18425                    int profileUserId = profiles.get(i).id;
18426                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18427                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18428                            | Intent.FLAG_RECEIVER_FOREGROUND);
18429                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18430                    broadcastIntentLocked(null, null, intent,
18431                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18432                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18433                }
18434            }
18435            if (newUserId >= 0) {
18436                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18437                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18438                int count = profiles.size();
18439                for (int i = 0; i < count; i++) {
18440                    int profileUserId = profiles.get(i).id;
18441                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18442                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18443                            | Intent.FLAG_RECEIVER_FOREGROUND);
18444                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18445                    broadcastIntentLocked(null, null, intent,
18446                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18447                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18448                }
18449                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18450                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18451                        | Intent.FLAG_RECEIVER_FOREGROUND);
18452                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18453                broadcastIntentLocked(null, null, intent,
18454                        null, null, 0, null, null,
18455                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18456                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18457            }
18458        } finally {
18459            Binder.restoreCallingIdentity(ident);
18460        }
18461    }
18462
18463    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18464            final int newUserId) {
18465        final int N = mUserSwitchObservers.beginBroadcast();
18466        if (N > 0) {
18467            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18468                int mCount = 0;
18469                @Override
18470                public void sendResult(Bundle data) throws RemoteException {
18471                    synchronized (ActivityManagerService.this) {
18472                        if (mCurUserSwitchCallback == this) {
18473                            mCount++;
18474                            if (mCount == N) {
18475                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18476                            }
18477                        }
18478                    }
18479                }
18480            };
18481            synchronized (this) {
18482                uss.switching = true;
18483                mCurUserSwitchCallback = callback;
18484            }
18485            for (int i=0; i<N; i++) {
18486                try {
18487                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18488                            newUserId, callback);
18489                } catch (RemoteException e) {
18490                }
18491            }
18492        } else {
18493            synchronized (this) {
18494                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18495            }
18496        }
18497        mUserSwitchObservers.finishBroadcast();
18498    }
18499
18500    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18501        synchronized (this) {
18502            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18503            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18504        }
18505    }
18506
18507    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18508        mCurUserSwitchCallback = null;
18509        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18510        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18511                oldUserId, newUserId, uss));
18512    }
18513
18514    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18515        synchronized (this) {
18516            if (foreground) {
18517                moveUserToForeground(uss, oldUserId, newUserId);
18518            }
18519        }
18520
18521        completeSwitchAndInitalize(uss, newUserId, true, false);
18522    }
18523
18524    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18525        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18526        if (homeInFront) {
18527            startHomeActivityLocked(newUserId);
18528        } else {
18529            mStackSupervisor.resumeTopActivitiesLocked();
18530        }
18531        EventLogTags.writeAmSwitchUser(newUserId);
18532        getUserManagerLocked().userForeground(newUserId);
18533        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18534    }
18535
18536    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18537        completeSwitchAndInitalize(uss, newUserId, false, true);
18538    }
18539
18540    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18541            boolean clearInitializing, boolean clearSwitching) {
18542        boolean unfrozen = false;
18543        synchronized (this) {
18544            if (clearInitializing) {
18545                uss.initializing = false;
18546                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18547            }
18548            if (clearSwitching) {
18549                uss.switching = false;
18550            }
18551            if (!uss.switching && !uss.initializing) {
18552                mWindowManager.stopFreezingScreen();
18553                unfrozen = true;
18554            }
18555        }
18556        if (unfrozen) {
18557            final int N = mUserSwitchObservers.beginBroadcast();
18558            for (int i=0; i<N; i++) {
18559                try {
18560                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18561                } catch (RemoteException e) {
18562                }
18563            }
18564            mUserSwitchObservers.finishBroadcast();
18565        }
18566    }
18567
18568    void scheduleStartProfilesLocked() {
18569        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18570            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18571                    DateUtils.SECOND_IN_MILLIS);
18572        }
18573    }
18574
18575    void startProfilesLocked() {
18576        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18577        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18578                mCurrentUserId, false /* enabledOnly */);
18579        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18580        for (UserInfo user : profiles) {
18581            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18582                    && user.id != mCurrentUserId) {
18583                toStart.add(user);
18584            }
18585        }
18586        final int n = toStart.size();
18587        int i = 0;
18588        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18589            startUserInBackground(toStart.get(i).id);
18590        }
18591        if (i < n) {
18592            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18593        }
18594    }
18595
18596    void finishUserBoot(UserStartedState uss) {
18597        synchronized (this) {
18598            if (uss.mState == UserStartedState.STATE_BOOTING
18599                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18600                uss.mState = UserStartedState.STATE_RUNNING;
18601                final int userId = uss.mHandle.getIdentifier();
18602                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18603                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18604                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18605                broadcastIntentLocked(null, null, intent,
18606                        null, null, 0, null, null,
18607                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18608                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18609            }
18610        }
18611    }
18612
18613    void finishUserSwitch(UserStartedState uss) {
18614        synchronized (this) {
18615            finishUserBoot(uss);
18616
18617            startProfilesLocked();
18618
18619            int num = mUserLru.size();
18620            int i = 0;
18621            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18622                Integer oldUserId = mUserLru.get(i);
18623                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18624                if (oldUss == null) {
18625                    // Shouldn't happen, but be sane if it does.
18626                    mUserLru.remove(i);
18627                    num--;
18628                    continue;
18629                }
18630                if (oldUss.mState == UserStartedState.STATE_STOPPING
18631                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18632                    // This user is already stopping, doesn't count.
18633                    num--;
18634                    i++;
18635                    continue;
18636                }
18637                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18638                    // Owner and current can't be stopped, but count as running.
18639                    i++;
18640                    continue;
18641                }
18642                // This is a user to be stopped.
18643                stopUserLocked(oldUserId, null);
18644                num--;
18645                i++;
18646            }
18647        }
18648    }
18649
18650    @Override
18651    public int stopUser(final int userId, final IStopUserCallback callback) {
18652        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18653                != PackageManager.PERMISSION_GRANTED) {
18654            String msg = "Permission Denial: switchUser() from pid="
18655                    + Binder.getCallingPid()
18656                    + ", uid=" + Binder.getCallingUid()
18657                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18658            Slog.w(TAG, msg);
18659            throw new SecurityException(msg);
18660        }
18661        if (userId <= 0) {
18662            throw new IllegalArgumentException("Can't stop primary user " + userId);
18663        }
18664        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18665        synchronized (this) {
18666            return stopUserLocked(userId, callback);
18667        }
18668    }
18669
18670    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18671        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18672        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18673            return ActivityManager.USER_OP_IS_CURRENT;
18674        }
18675
18676        final UserStartedState uss = mStartedUsers.get(userId);
18677        if (uss == null) {
18678            // User is not started, nothing to do...  but we do need to
18679            // callback if requested.
18680            if (callback != null) {
18681                mHandler.post(new Runnable() {
18682                    @Override
18683                    public void run() {
18684                        try {
18685                            callback.userStopped(userId);
18686                        } catch (RemoteException e) {
18687                        }
18688                    }
18689                });
18690            }
18691            return ActivityManager.USER_OP_SUCCESS;
18692        }
18693
18694        if (callback != null) {
18695            uss.mStopCallbacks.add(callback);
18696        }
18697
18698        if (uss.mState != UserStartedState.STATE_STOPPING
18699                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18700            uss.mState = UserStartedState.STATE_STOPPING;
18701            updateStartedUserArrayLocked();
18702
18703            long ident = Binder.clearCallingIdentity();
18704            try {
18705                // We are going to broadcast ACTION_USER_STOPPING and then
18706                // once that is done send a final ACTION_SHUTDOWN and then
18707                // stop the user.
18708                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18709                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18710                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18711                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18712                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18713                // This is the result receiver for the final shutdown broadcast.
18714                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18715                    @Override
18716                    public void performReceive(Intent intent, int resultCode, String data,
18717                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18718                        finishUserStop(uss);
18719                    }
18720                };
18721                // This is the result receiver for the initial stopping broadcast.
18722                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18723                    @Override
18724                    public void performReceive(Intent intent, int resultCode, String data,
18725                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18726                        // On to the next.
18727                        synchronized (ActivityManagerService.this) {
18728                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18729                                // Whoops, we are being started back up.  Abort, abort!
18730                                return;
18731                            }
18732                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18733                        }
18734                        mBatteryStatsService.noteEvent(
18735                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18736                                Integer.toString(userId), userId);
18737                        mSystemServiceManager.stopUser(userId);
18738                        broadcastIntentLocked(null, null, shutdownIntent,
18739                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18740                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18741                    }
18742                };
18743                // Kick things off.
18744                broadcastIntentLocked(null, null, stoppingIntent,
18745                        null, stoppingReceiver, 0, null, null,
18746                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18747                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18748            } finally {
18749                Binder.restoreCallingIdentity(ident);
18750            }
18751        }
18752
18753        return ActivityManager.USER_OP_SUCCESS;
18754    }
18755
18756    void finishUserStop(UserStartedState uss) {
18757        final int userId = uss.mHandle.getIdentifier();
18758        boolean stopped;
18759        ArrayList<IStopUserCallback> callbacks;
18760        synchronized (this) {
18761            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18762            if (mStartedUsers.get(userId) != uss) {
18763                stopped = false;
18764            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18765                stopped = false;
18766            } else {
18767                stopped = true;
18768                // User can no longer run.
18769                mStartedUsers.remove(userId);
18770                mUserLru.remove(Integer.valueOf(userId));
18771                updateStartedUserArrayLocked();
18772
18773                // Clean up all state and processes associated with the user.
18774                // Kill all the processes for the user.
18775                forceStopUserLocked(userId, "finish user");
18776            }
18777
18778            // Explicitly remove the old information in mRecentTasks.
18779            removeRecentTasksForUserLocked(userId);
18780        }
18781
18782        for (int i=0; i<callbacks.size(); i++) {
18783            try {
18784                if (stopped) callbacks.get(i).userStopped(userId);
18785                else callbacks.get(i).userStopAborted(userId);
18786            } catch (RemoteException e) {
18787            }
18788        }
18789
18790        if (stopped) {
18791            mSystemServiceManager.cleanupUser(userId);
18792            synchronized (this) {
18793                mStackSupervisor.removeUserLocked(userId);
18794            }
18795        }
18796    }
18797
18798    @Override
18799    public UserInfo getCurrentUser() {
18800        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18801                != PackageManager.PERMISSION_GRANTED) && (
18802                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18803                != PackageManager.PERMISSION_GRANTED)) {
18804            String msg = "Permission Denial: getCurrentUser() from pid="
18805                    + Binder.getCallingPid()
18806                    + ", uid=" + Binder.getCallingUid()
18807                    + " requires " + INTERACT_ACROSS_USERS;
18808            Slog.w(TAG, msg);
18809            throw new SecurityException(msg);
18810        }
18811        synchronized (this) {
18812            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18813            return getUserManagerLocked().getUserInfo(userId);
18814        }
18815    }
18816
18817    int getCurrentUserIdLocked() {
18818        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18819    }
18820
18821    @Override
18822    public boolean isUserRunning(int userId, boolean orStopped) {
18823        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18824                != PackageManager.PERMISSION_GRANTED) {
18825            String msg = "Permission Denial: isUserRunning() from pid="
18826                    + Binder.getCallingPid()
18827                    + ", uid=" + Binder.getCallingUid()
18828                    + " requires " + INTERACT_ACROSS_USERS;
18829            Slog.w(TAG, msg);
18830            throw new SecurityException(msg);
18831        }
18832        synchronized (this) {
18833            return isUserRunningLocked(userId, orStopped);
18834        }
18835    }
18836
18837    boolean isUserRunningLocked(int userId, boolean orStopped) {
18838        UserStartedState state = mStartedUsers.get(userId);
18839        if (state == null) {
18840            return false;
18841        }
18842        if (orStopped) {
18843            return true;
18844        }
18845        return state.mState != UserStartedState.STATE_STOPPING
18846                && state.mState != UserStartedState.STATE_SHUTDOWN;
18847    }
18848
18849    @Override
18850    public int[] getRunningUserIds() {
18851        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18852                != PackageManager.PERMISSION_GRANTED) {
18853            String msg = "Permission Denial: isUserRunning() from pid="
18854                    + Binder.getCallingPid()
18855                    + ", uid=" + Binder.getCallingUid()
18856                    + " requires " + INTERACT_ACROSS_USERS;
18857            Slog.w(TAG, msg);
18858            throw new SecurityException(msg);
18859        }
18860        synchronized (this) {
18861            return mStartedUserArray;
18862        }
18863    }
18864
18865    private void updateStartedUserArrayLocked() {
18866        int num = 0;
18867        for (int i=0; i<mStartedUsers.size();  i++) {
18868            UserStartedState uss = mStartedUsers.valueAt(i);
18869            // This list does not include stopping users.
18870            if (uss.mState != UserStartedState.STATE_STOPPING
18871                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18872                num++;
18873            }
18874        }
18875        mStartedUserArray = new int[num];
18876        num = 0;
18877        for (int i=0; i<mStartedUsers.size();  i++) {
18878            UserStartedState uss = mStartedUsers.valueAt(i);
18879            if (uss.mState != UserStartedState.STATE_STOPPING
18880                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18881                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18882                num++;
18883            }
18884        }
18885    }
18886
18887    @Override
18888    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18889        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18890                != PackageManager.PERMISSION_GRANTED) {
18891            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18892                    + Binder.getCallingPid()
18893                    + ", uid=" + Binder.getCallingUid()
18894                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18895            Slog.w(TAG, msg);
18896            throw new SecurityException(msg);
18897        }
18898
18899        mUserSwitchObservers.register(observer);
18900    }
18901
18902    @Override
18903    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18904        mUserSwitchObservers.unregister(observer);
18905    }
18906
18907    private boolean userExists(int userId) {
18908        if (userId == 0) {
18909            return true;
18910        }
18911        UserManagerService ums = getUserManagerLocked();
18912        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18913    }
18914
18915    int[] getUsersLocked() {
18916        UserManagerService ums = getUserManagerLocked();
18917        return ums != null ? ums.getUserIds() : new int[] { 0 };
18918    }
18919
18920    UserManagerService getUserManagerLocked() {
18921        if (mUserManager == null) {
18922            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18923            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18924        }
18925        return mUserManager;
18926    }
18927
18928    private int applyUserId(int uid, int userId) {
18929        return UserHandle.getUid(userId, uid);
18930    }
18931
18932    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18933        if (info == null) return null;
18934        ApplicationInfo newInfo = new ApplicationInfo(info);
18935        newInfo.uid = applyUserId(info.uid, userId);
18936        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18937                + info.packageName;
18938        return newInfo;
18939    }
18940
18941    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18942        if (aInfo == null
18943                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18944            return aInfo;
18945        }
18946
18947        ActivityInfo info = new ActivityInfo(aInfo);
18948        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18949        return info;
18950    }
18951
18952    private final class LocalService extends ActivityManagerInternal {
18953        @Override
18954        public void goingToSleep() {
18955            ActivityManagerService.this.goingToSleep();
18956        }
18957
18958        @Override
18959        public void wakingUp() {
18960            ActivityManagerService.this.wakingUp();
18961        }
18962
18963        @Override
18964        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18965                String processName, String abiOverride, int uid, Runnable crashHandler) {
18966            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18967                    processName, abiOverride, uid, crashHandler);
18968        }
18969    }
18970
18971    /**
18972     * An implementation of IAppTask, that allows an app to manage its own tasks via
18973     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18974     * only the process that calls getAppTasks() can call the AppTask methods.
18975     */
18976    class AppTaskImpl extends IAppTask.Stub {
18977        private int mTaskId;
18978        private int mCallingUid;
18979
18980        public AppTaskImpl(int taskId, int callingUid) {
18981            mTaskId = taskId;
18982            mCallingUid = callingUid;
18983        }
18984
18985        private void checkCaller() {
18986            if (mCallingUid != Binder.getCallingUid()) {
18987                throw new SecurityException("Caller " + mCallingUid
18988                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18989            }
18990        }
18991
18992        @Override
18993        public void finishAndRemoveTask() {
18994            checkCaller();
18995
18996            synchronized (ActivityManagerService.this) {
18997                long origId = Binder.clearCallingIdentity();
18998                try {
18999                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19000                    if (tr == null) {
19001                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19002                    }
19003                    // Only kill the process if we are not a new document
19004                    int flags = tr.getBaseIntent().getFlags();
19005                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19006                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19007                    removeTaskByIdLocked(mTaskId,
19008                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19009                } finally {
19010                    Binder.restoreCallingIdentity(origId);
19011                }
19012            }
19013        }
19014
19015        @Override
19016        public ActivityManager.RecentTaskInfo getTaskInfo() {
19017            checkCaller();
19018
19019            synchronized (ActivityManagerService.this) {
19020                long origId = Binder.clearCallingIdentity();
19021                try {
19022                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19023                    if (tr == null) {
19024                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19025                    }
19026                    return createRecentTaskInfoFromTaskRecord(tr);
19027                } finally {
19028                    Binder.restoreCallingIdentity(origId);
19029                }
19030            }
19031        }
19032
19033        @Override
19034        public void moveToFront() {
19035            checkCaller();
19036
19037            final TaskRecord tr;
19038            synchronized (ActivityManagerService.this) {
19039                tr = recentTaskForIdLocked(mTaskId);
19040                if (tr == null) {
19041                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19042                }
19043                if (tr.getRootActivity() != null) {
19044                    moveTaskToFrontLocked(tr.taskId, 0, null);
19045                    return;
19046                }
19047            }
19048
19049            startActivityFromRecentsInner(tr.taskId, null);
19050        }
19051
19052        @Override
19053        public int startActivity(IBinder whoThread, String callingPackage,
19054                Intent intent, String resolvedType, Bundle options) {
19055            checkCaller();
19056
19057            int callingUser = UserHandle.getCallingUserId();
19058            TaskRecord tr;
19059            IApplicationThread appThread;
19060            synchronized (ActivityManagerService.this) {
19061                tr = recentTaskForIdLocked(mTaskId);
19062                if (tr == null) {
19063                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19064                }
19065                appThread = ApplicationThreadNative.asInterface(whoThread);
19066                if (appThread == null) {
19067                    throw new IllegalArgumentException("Bad app thread " + appThread);
19068                }
19069            }
19070            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19071                    resolvedType, null, null, null, null, 0, 0, null, null,
19072                    null, options, callingUser, null, tr);
19073        }
19074
19075        @Override
19076        public void setExcludeFromRecents(boolean exclude) {
19077            checkCaller();
19078
19079            synchronized (ActivityManagerService.this) {
19080                long origId = Binder.clearCallingIdentity();
19081                try {
19082                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19083                    if (tr == null) {
19084                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19085                    }
19086                    Intent intent = tr.getBaseIntent();
19087                    if (exclude) {
19088                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19089                    } else {
19090                        intent.setFlags(intent.getFlags()
19091                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19092                    }
19093                } finally {
19094                    Binder.restoreCallingIdentity(origId);
19095                }
19096            }
19097        }
19098    }
19099}
19100