ActivityManagerService.java revision ab4a81b3c625e33d04ae8070fcce6b6baee6522c
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        final SparseArray<ProcessMemInfo> infoMap
1610                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            infoMap.put(mi.pid, mi);
1614                        }
1615                        updateCpuStatsNow();
1616                        synchronized (mProcessCpuTracker) {
1617                            final int N = mProcessCpuTracker.countStats();
1618                            for (int i=0; i<N; i++) {
1619                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1620                                if (st.vsize > 0) {
1621                                    long pss = Debug.getPss(st.pid, null);
1622                                    if (pss > 0) {
1623                                        if (infoMap.indexOfKey(st.pid) < 0) {
1624                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1625                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1626                                            mi.pss = pss;
1627                                            memInfos.add(mi);
1628                                        }
1629                                    }
1630                                }
1631                            }
1632                        }
1633
1634                        long totalPss = 0;
1635                        for (int i=0, N=memInfos.size(); i<N; i++) {
1636                            ProcessMemInfo mi = memInfos.get(i);
1637                            if (mi.pss == 0) {
1638                                mi.pss = Debug.getPss(mi.pid, null);
1639                            }
1640                            totalPss += mi.pss;
1641                        }
1642                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1643                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1644                                if (lhs.oomAdj != rhs.oomAdj) {
1645                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1646                                }
1647                                if (lhs.pss != rhs.pss) {
1648                                    return lhs.pss < rhs.pss ? 1 : -1;
1649                                }
1650                                return 0;
1651                            }
1652                        });
1653
1654                        StringBuilder tag = new StringBuilder(128);
1655                        StringBuilder stack = new StringBuilder(128);
1656                        tag.append("Low on memory -- ");
1657                        appendMemBucket(tag, totalPss, "total", false);
1658                        appendMemBucket(stack, totalPss, "total", true);
1659
1660                        StringBuilder logBuilder = new StringBuilder(1024);
1661                        logBuilder.append("Low on memory:\n");
1662
1663                        boolean firstLine = true;
1664                        int lastOomAdj = Integer.MIN_VALUE;
1665                        for (int i=0, N=memInfos.size(); i<N; i++) {
1666                            ProcessMemInfo mi = memInfos.get(i);
1667
1668                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1669                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1670                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1671                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1672                                if (lastOomAdj != mi.oomAdj) {
1673                                    lastOomAdj = mi.oomAdj;
1674                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1675                                        tag.append(" / ");
1676                                    }
1677                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1678                                        if (firstLine) {
1679                                            stack.append(":");
1680                                            firstLine = false;
1681                                        }
1682                                        stack.append("\n\t at ");
1683                                    } else {
1684                                        stack.append("$");
1685                                    }
1686                                } else {
1687                                    tag.append(" ");
1688                                    stack.append("$");
1689                                }
1690                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1691                                    appendMemBucket(tag, mi.pss, mi.name, false);
1692                                }
1693                                appendMemBucket(stack, mi.pss, mi.name, true);
1694                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1695                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1696                                    stack.append("(");
1697                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1698                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1699                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1700                                            stack.append(":");
1701                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1702                                        }
1703                                    }
1704                                    stack.append(")");
1705                                }
1706                            }
1707
1708                            logBuilder.append("  ");
1709                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1710                            logBuilder.append(' ');
1711                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1712                            logBuilder.append(' ');
1713                            ProcessList.appendRamKb(logBuilder, mi.pss);
1714                            logBuilder.append(" kB: ");
1715                            logBuilder.append(mi.name);
1716                            logBuilder.append(" (");
1717                            logBuilder.append(mi.pid);
1718                            logBuilder.append(") ");
1719                            logBuilder.append(mi.adjType);
1720                            logBuilder.append('\n');
1721                            if (mi.adjReason != null) {
1722                                logBuilder.append("                      ");
1723                                logBuilder.append(mi.adjReason);
1724                                logBuilder.append('\n');
1725                            }
1726                        }
1727
1728                        logBuilder.append("           ");
1729                        ProcessList.appendRamKb(logBuilder, totalPss);
1730                        logBuilder.append(" kB: TOTAL\n");
1731
1732                        long[] infos = new long[Debug.MEMINFO_COUNT];
1733                        Debug.getMemInfo(infos);
1734                        logBuilder.append("  MemInfo: ");
1735                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1736                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1737                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1738                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1739                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1740                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1741                            logBuilder.append("  ZRAM: ");
1742                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1743                            logBuilder.append(" kB RAM, ");
1744                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1745                            logBuilder.append(" kB swap total, ");
1746                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1747                            logBuilder.append(" kB swap free\n");
1748                        }
1749                        Slog.i(TAG, logBuilder.toString());
1750
1751                        StringBuilder dropBuilder = new StringBuilder(1024);
1752                        /*
1753                        StringWriter oomSw = new StringWriter();
1754                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1755                        StringWriter catSw = new StringWriter();
1756                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1757                        String[] emptyArgs = new String[] { };
1758                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1759                        oomPw.flush();
1760                        String oomString = oomSw.toString();
1761                        */
1762                        dropBuilder.append(stack);
1763                        dropBuilder.append('\n');
1764                        dropBuilder.append('\n');
1765                        dropBuilder.append(logBuilder);
1766                        dropBuilder.append('\n');
1767                        /*
1768                        dropBuilder.append(oomString);
1769                        dropBuilder.append('\n');
1770                        */
1771                        StringWriter catSw = new StringWriter();
1772                        synchronized (ActivityManagerService.this) {
1773                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1774                            String[] emptyArgs = new String[] { };
1775                            catPw.println();
1776                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1777                            catPw.println();
1778                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1779                                    false, false, null);
1780                            catPw.println();
1781                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1782                            catPw.flush();
1783                        }
1784                        dropBuilder.append(catSw.toString());
1785                        addErrorToDropBox("lowmem", null, "system_server", null,
1786                                null, tag.toString(), dropBuilder.toString(), null, null);
1787                        //Slog.i(TAG, "Sent to dropbox:");
1788                        //Slog.i(TAG, dropBuilder.toString());
1789                        synchronized (ActivityManagerService.this) {
1790                            long now = SystemClock.uptimeMillis();
1791                            if (mLastMemUsageReportTime < now) {
1792                                mLastMemUsageReportTime = now;
1793                            }
1794                        }
1795                    }
1796                };
1797                thread.start();
1798                break;
1799            }
1800            case START_USER_SWITCH_MSG: {
1801                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1802                break;
1803            }
1804            case REPORT_USER_SWITCH_MSG: {
1805                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1806                break;
1807            }
1808            case CONTINUE_USER_SWITCH_MSG: {
1809                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1810                break;
1811            }
1812            case USER_SWITCH_TIMEOUT_MSG: {
1813                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1814                break;
1815            }
1816            case IMMERSIVE_MODE_LOCK_MSG: {
1817                final boolean nextState = (msg.arg1 != 0);
1818                if (mUpdateLock.isHeld() != nextState) {
1819                    if (DEBUG_IMMERSIVE) {
1820                        final ActivityRecord r = (ActivityRecord) msg.obj;
1821                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1822                    }
1823                    if (nextState) {
1824                        mUpdateLock.acquire();
1825                    } else {
1826                        mUpdateLock.release();
1827                    }
1828                }
1829                break;
1830            }
1831            case PERSIST_URI_GRANTS_MSG: {
1832                writeGrantedUriPermissions();
1833                break;
1834            }
1835            case REQUEST_ALL_PSS_MSG: {
1836                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1837                break;
1838            }
1839            case START_PROFILES_MSG: {
1840                synchronized (ActivityManagerService.this) {
1841                    startProfilesLocked();
1842                }
1843                break;
1844            }
1845            case UPDATE_TIME: {
1846                synchronized (ActivityManagerService.this) {
1847                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1848                        ProcessRecord r = mLruProcesses.get(i);
1849                        if (r.thread != null) {
1850                            try {
1851                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1852                            } catch (RemoteException ex) {
1853                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1854                            }
1855                        }
1856                    }
1857                }
1858                break;
1859            }
1860            case SYSTEM_USER_START_MSG: {
1861                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1862                        Integer.toString(msg.arg1), msg.arg1);
1863                mSystemServiceManager.startUser(msg.arg1);
1864                break;
1865            }
1866            case SYSTEM_USER_CURRENT_MSG: {
1867                mBatteryStatsService.noteEvent(
1868                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1869                        Integer.toString(msg.arg2), msg.arg2);
1870                mBatteryStatsService.noteEvent(
1871                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1872                        Integer.toString(msg.arg1), msg.arg1);
1873                mSystemServiceManager.switchUser(msg.arg1);
1874                mLockToAppRequest.clearPrompt();
1875                break;
1876            }
1877            case ENTER_ANIMATION_COMPLETE_MSG: {
1878                synchronized (ActivityManagerService.this) {
1879                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1880                    if (r != null && r.app != null && r.app.thread != null) {
1881                        try {
1882                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1883                        } catch (RemoteException e) {
1884                        }
1885                    }
1886                }
1887                break;
1888            }
1889            case FINISH_BOOTING_MSG: {
1890                if (msg.arg1 != 0) {
1891                    finishBooting();
1892                }
1893                if (msg.arg2 != 0) {
1894                    enableScreenAfterBoot();
1895                }
1896                break;
1897            }
1898            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1899                try {
1900                    Locale l = (Locale) msg.obj;
1901                    IBinder service = ServiceManager.getService("mount");
1902                    IMountService mountService = IMountService.Stub.asInterface(service);
1903                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1904                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1905                } catch (RemoteException e) {
1906                    Log.e(TAG, "Error storing locale for decryption UI", e);
1907                }
1908                break;
1909            }
1910            }
1911        }
1912    };
1913
1914    static final int COLLECT_PSS_BG_MSG = 1;
1915
1916    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1917        @Override
1918        public void handleMessage(Message msg) {
1919            switch (msg.what) {
1920            case COLLECT_PSS_BG_MSG: {
1921                long start = SystemClock.uptimeMillis();
1922                MemInfoReader memInfo = null;
1923                synchronized (ActivityManagerService.this) {
1924                    if (mFullPssPending) {
1925                        mFullPssPending = false;
1926                        memInfo = new MemInfoReader();
1927                    }
1928                }
1929                if (memInfo != null) {
1930                    updateCpuStatsNow();
1931                    long nativeTotalPss = 0;
1932                    synchronized (mProcessCpuTracker) {
1933                        final int N = mProcessCpuTracker.countStats();
1934                        for (int j=0; j<N; j++) {
1935                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1936                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1937                                // This is definitely an application process; skip it.
1938                                continue;
1939                            }
1940                            synchronized (mPidsSelfLocked) {
1941                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1942                                    // This is one of our own processes; skip it.
1943                                    continue;
1944                                }
1945                            }
1946                            nativeTotalPss += Debug.getPss(st.pid, null);
1947                        }
1948                    }
1949                    memInfo.readMemInfo();
1950                    synchronized (ActivityManagerService.this) {
1951                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1952                                + (SystemClock.uptimeMillis()-start) + "ms");
1953                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1954                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1955                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1956                                        +memInfo.getSlabSizeKb(),
1957                                nativeTotalPss);
1958                    }
1959                }
1960
1961                int i=0, num=0;
1962                long[] tmp = new long[1];
1963                do {
1964                    ProcessRecord proc;
1965                    int procState;
1966                    int pid;
1967                    synchronized (ActivityManagerService.this) {
1968                        if (i >= mPendingPssProcesses.size()) {
1969                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1970                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1971                            mPendingPssProcesses.clear();
1972                            return;
1973                        }
1974                        proc = mPendingPssProcesses.get(i);
1975                        procState = proc.pssProcState;
1976                        if (proc.thread != null && procState == proc.setProcState) {
1977                            pid = proc.pid;
1978                        } else {
1979                            proc = null;
1980                            pid = 0;
1981                        }
1982                        i++;
1983                    }
1984                    if (proc != null) {
1985                        long pss = Debug.getPss(pid, tmp);
1986                        synchronized (ActivityManagerService.this) {
1987                            if (proc.thread != null && proc.setProcState == procState
1988                                    && proc.pid == pid) {
1989                                num++;
1990                                proc.lastPssTime = SystemClock.uptimeMillis();
1991                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1992                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1993                                        + ": " + pss + " lastPss=" + proc.lastPss
1994                                        + " state=" + ProcessList.makeProcStateString(procState));
1995                                if (proc.initialIdlePss == 0) {
1996                                    proc.initialIdlePss = pss;
1997                                }
1998                                proc.lastPss = pss;
1999                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2000                                    proc.lastCachedPss = pss;
2001                                }
2002                            }
2003                        }
2004                    }
2005                } while (true);
2006            }
2007            }
2008        }
2009    };
2010
2011    /**
2012     * Monitor for package changes and update our internal state.
2013     */
2014    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2015        @Override
2016        public void onPackageRemoved(String packageName, int uid) {
2017            // Remove all tasks with activities in the specified package from the list of recent tasks
2018            final int eventUserId = getChangingUserId();
2019            synchronized (ActivityManagerService.this) {
2020                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2021                    TaskRecord tr = mRecentTasks.get(i);
2022                    if (tr.userId != eventUserId) continue;
2023
2024                    ComponentName cn = tr.intent.getComponent();
2025                    if (cn != null && cn.getPackageName().equals(packageName)) {
2026                        // If the package name matches, remove the task and kill the process
2027                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2028                    }
2029                }
2030            }
2031        }
2032
2033        @Override
2034        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2035            onPackageModified(packageName);
2036            return true;
2037        }
2038
2039        @Override
2040        public void onPackageModified(String packageName) {
2041            final int eventUserId = getChangingUserId();
2042            final IPackageManager pm = AppGlobals.getPackageManager();
2043            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2044                    new ArrayList<Pair<Intent, Integer>>();
2045            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2046            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2047            // Copy the list of recent tasks so that we don't hold onto the lock on
2048            // ActivityManagerService for long periods while checking if components exist.
2049            synchronized (ActivityManagerService.this) {
2050                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2051                    TaskRecord tr = mRecentTasks.get(i);
2052                    if (tr.userId != eventUserId) continue;
2053
2054                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2055                }
2056            }
2057            // Check the recent tasks and filter out all tasks with components that no longer exist.
2058            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2059                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2060                ComponentName cn = p.first.getComponent();
2061                if (cn != null && cn.getPackageName().equals(packageName)) {
2062                    if (componentsKnownToExist.contains(cn)) {
2063                        // If we know that the component still exists in the package, then skip
2064                        continue;
2065                    }
2066                    try {
2067                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2068                        if (info != null) {
2069                            componentsKnownToExist.add(cn);
2070                        } else {
2071                            tasksToRemove.add(p.second);
2072                        }
2073                    } catch (RemoteException e) {
2074                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2075                    }
2076                }
2077            }
2078            // Prune all the tasks with removed components from the list of recent tasks
2079            synchronized (ActivityManagerService.this) {
2080                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2081                    // Remove the task but don't kill the process (since other components in that
2082                    // package may still be running and in the background)
2083                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2084                }
2085            }
2086        }
2087
2088        @Override
2089        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2090            // Force stop the specified packages
2091            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2092            if (packages != null) {
2093                for (String pkg : packages) {
2094                    synchronized (ActivityManagerService.this) {
2095                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2096                                userId, "finished booting")) {
2097                            return true;
2098                        }
2099                    }
2100                }
2101            }
2102            return false;
2103        }
2104    };
2105
2106    public void setSystemProcess() {
2107        try {
2108            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2109            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2110            ServiceManager.addService("meminfo", new MemBinder(this));
2111            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2112            ServiceManager.addService("dbinfo", new DbBinder(this));
2113            if (MONITOR_CPU_USAGE) {
2114                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2115            }
2116            ServiceManager.addService("permission", new PermissionController(this));
2117
2118            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2119                    "android", STOCK_PM_FLAGS);
2120            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2121
2122            synchronized (this) {
2123                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2124                app.persistent = true;
2125                app.pid = MY_PID;
2126                app.maxAdj = ProcessList.SYSTEM_ADJ;
2127                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2128                mProcessNames.put(app.processName, app.uid, app);
2129                synchronized (mPidsSelfLocked) {
2130                    mPidsSelfLocked.put(app.pid, app);
2131                }
2132                updateLruProcessLocked(app, false, null);
2133                updateOomAdjLocked();
2134            }
2135        } catch (PackageManager.NameNotFoundException e) {
2136            throw new RuntimeException(
2137                    "Unable to find android system package", e);
2138        }
2139    }
2140
2141    public void setWindowManager(WindowManagerService wm) {
2142        mWindowManager = wm;
2143        mStackSupervisor.setWindowManager(wm);
2144    }
2145
2146    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2147        mUsageStatsService = usageStatsManager;
2148    }
2149
2150    public void startObservingNativeCrashes() {
2151        final NativeCrashListener ncl = new NativeCrashListener(this);
2152        ncl.start();
2153    }
2154
2155    public IAppOpsService getAppOpsService() {
2156        return mAppOpsService;
2157    }
2158
2159    static class MemBinder extends Binder {
2160        ActivityManagerService mActivityManagerService;
2161        MemBinder(ActivityManagerService activityManagerService) {
2162            mActivityManagerService = activityManagerService;
2163        }
2164
2165        @Override
2166        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2167            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2168                    != PackageManager.PERMISSION_GRANTED) {
2169                pw.println("Permission Denial: can't dump meminfo from from pid="
2170                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2171                        + " without permission " + android.Manifest.permission.DUMP);
2172                return;
2173            }
2174
2175            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2176        }
2177    }
2178
2179    static class GraphicsBinder extends Binder {
2180        ActivityManagerService mActivityManagerService;
2181        GraphicsBinder(ActivityManagerService activityManagerService) {
2182            mActivityManagerService = activityManagerService;
2183        }
2184
2185        @Override
2186        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2187            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2188                    != PackageManager.PERMISSION_GRANTED) {
2189                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2190                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2191                        + " without permission " + android.Manifest.permission.DUMP);
2192                return;
2193            }
2194
2195            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2196        }
2197    }
2198
2199    static class DbBinder extends Binder {
2200        ActivityManagerService mActivityManagerService;
2201        DbBinder(ActivityManagerService activityManagerService) {
2202            mActivityManagerService = activityManagerService;
2203        }
2204
2205        @Override
2206        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2207            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2208                    != PackageManager.PERMISSION_GRANTED) {
2209                pw.println("Permission Denial: can't dump dbinfo from from pid="
2210                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2211                        + " without permission " + android.Manifest.permission.DUMP);
2212                return;
2213            }
2214
2215            mActivityManagerService.dumpDbInfo(fd, pw, args);
2216        }
2217    }
2218
2219    static class CpuBinder extends Binder {
2220        ActivityManagerService mActivityManagerService;
2221        CpuBinder(ActivityManagerService activityManagerService) {
2222            mActivityManagerService = activityManagerService;
2223        }
2224
2225        @Override
2226        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2227            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2228                    != PackageManager.PERMISSION_GRANTED) {
2229                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2230                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2231                        + " without permission " + android.Manifest.permission.DUMP);
2232                return;
2233            }
2234
2235            synchronized (mActivityManagerService.mProcessCpuTracker) {
2236                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2237                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2238                        SystemClock.uptimeMillis()));
2239            }
2240        }
2241    }
2242
2243    public static final class Lifecycle extends SystemService {
2244        private final ActivityManagerService mService;
2245
2246        public Lifecycle(Context context) {
2247            super(context);
2248            mService = new ActivityManagerService(context);
2249        }
2250
2251        @Override
2252        public void onStart() {
2253            mService.start();
2254        }
2255
2256        public ActivityManagerService getService() {
2257            return mService;
2258        }
2259    }
2260
2261    // Note: This method is invoked on the main thread but may need to attach various
2262    // handlers to other threads.  So take care to be explicit about the looper.
2263    public ActivityManagerService(Context systemContext) {
2264        mContext = systemContext;
2265        mFactoryTest = FactoryTest.getMode();
2266        mSystemThread = ActivityThread.currentActivityThread();
2267
2268        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2269
2270        mHandlerThread = new ServiceThread(TAG,
2271                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2272        mHandlerThread.start();
2273        mHandler = new MainHandler(mHandlerThread.getLooper());
2274
2275        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2276                "foreground", BROADCAST_FG_TIMEOUT, false);
2277        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2278                "background", BROADCAST_BG_TIMEOUT, true);
2279        mBroadcastQueues[0] = mFgBroadcastQueue;
2280        mBroadcastQueues[1] = mBgBroadcastQueue;
2281
2282        mServices = new ActiveServices(this);
2283        mProviderMap = new ProviderMap(this);
2284
2285        // TODO: Move creation of battery stats service outside of activity manager service.
2286        File dataDir = Environment.getDataDirectory();
2287        File systemDir = new File(dataDir, "system");
2288        systemDir.mkdirs();
2289        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2290        mBatteryStatsService.getActiveStatistics().readLocked();
2291        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2292        mOnBattery = DEBUG_POWER ? true
2293                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2294        mBatteryStatsService.getActiveStatistics().setCallback(this);
2295
2296        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2297
2298        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2299
2300        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2301
2302        // User 0 is the first and only user that runs at boot.
2303        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2304        mUserLru.add(Integer.valueOf(0));
2305        updateStartedUserArrayLocked();
2306
2307        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2308            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2309
2310        mConfiguration.setToDefaults();
2311        mConfiguration.setLocale(Locale.getDefault());
2312
2313        mConfigurationSeq = mConfiguration.seq = 1;
2314        mProcessCpuTracker.init();
2315
2316        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2317        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2318        mStackSupervisor = new ActivityStackSupervisor(this);
2319        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2320
2321        mProcessCpuThread = new Thread("CpuTracker") {
2322            @Override
2323            public void run() {
2324                while (true) {
2325                    try {
2326                        try {
2327                            synchronized(this) {
2328                                final long now = SystemClock.uptimeMillis();
2329                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2330                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2331                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2332                                //        + ", write delay=" + nextWriteDelay);
2333                                if (nextWriteDelay < nextCpuDelay) {
2334                                    nextCpuDelay = nextWriteDelay;
2335                                }
2336                                if (nextCpuDelay > 0) {
2337                                    mProcessCpuMutexFree.set(true);
2338                                    this.wait(nextCpuDelay);
2339                                }
2340                            }
2341                        } catch (InterruptedException e) {
2342                        }
2343                        updateCpuStatsNow();
2344                    } catch (Exception e) {
2345                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2346                    }
2347                }
2348            }
2349        };
2350
2351        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2352
2353        Watchdog.getInstance().addMonitor(this);
2354        Watchdog.getInstance().addThread(mHandler);
2355    }
2356
2357    public void setSystemServiceManager(SystemServiceManager mgr) {
2358        mSystemServiceManager = mgr;
2359    }
2360
2361    private void start() {
2362        Process.removeAllProcessGroups();
2363        mProcessCpuThread.start();
2364
2365        mBatteryStatsService.publish(mContext);
2366        mAppOpsService.publish(mContext);
2367        Slog.d("AppOps", "AppOpsService published");
2368        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2369    }
2370
2371    public void initPowerManagement() {
2372        mStackSupervisor.initPowerManagement();
2373        mBatteryStatsService.initPowerManagement();
2374    }
2375
2376    @Override
2377    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2378            throws RemoteException {
2379        if (code == SYSPROPS_TRANSACTION) {
2380            // We need to tell all apps about the system property change.
2381            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2382            synchronized(this) {
2383                final int NP = mProcessNames.getMap().size();
2384                for (int ip=0; ip<NP; ip++) {
2385                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2386                    final int NA = apps.size();
2387                    for (int ia=0; ia<NA; ia++) {
2388                        ProcessRecord app = apps.valueAt(ia);
2389                        if (app.thread != null) {
2390                            procs.add(app.thread.asBinder());
2391                        }
2392                    }
2393                }
2394            }
2395
2396            int N = procs.size();
2397            for (int i=0; i<N; i++) {
2398                Parcel data2 = Parcel.obtain();
2399                try {
2400                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2401                } catch (RemoteException e) {
2402                }
2403                data2.recycle();
2404            }
2405        }
2406        try {
2407            return super.onTransact(code, data, reply, flags);
2408        } catch (RuntimeException e) {
2409            // The activity manager only throws security exceptions, so let's
2410            // log all others.
2411            if (!(e instanceof SecurityException)) {
2412                Slog.wtf(TAG, "Activity Manager Crash", e);
2413            }
2414            throw e;
2415        }
2416    }
2417
2418    void updateCpuStats() {
2419        final long now = SystemClock.uptimeMillis();
2420        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2421            return;
2422        }
2423        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2424            synchronized (mProcessCpuThread) {
2425                mProcessCpuThread.notify();
2426            }
2427        }
2428    }
2429
2430    void updateCpuStatsNow() {
2431        synchronized (mProcessCpuTracker) {
2432            mProcessCpuMutexFree.set(false);
2433            final long now = SystemClock.uptimeMillis();
2434            boolean haveNewCpuStats = false;
2435
2436            if (MONITOR_CPU_USAGE &&
2437                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2438                mLastCpuTime.set(now);
2439                haveNewCpuStats = true;
2440                mProcessCpuTracker.update();
2441                //Slog.i(TAG, mProcessCpu.printCurrentState());
2442                //Slog.i(TAG, "Total CPU usage: "
2443                //        + mProcessCpu.getTotalCpuPercent() + "%");
2444
2445                // Slog the cpu usage if the property is set.
2446                if ("true".equals(SystemProperties.get("events.cpu"))) {
2447                    int user = mProcessCpuTracker.getLastUserTime();
2448                    int system = mProcessCpuTracker.getLastSystemTime();
2449                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2450                    int irq = mProcessCpuTracker.getLastIrqTime();
2451                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2452                    int idle = mProcessCpuTracker.getLastIdleTime();
2453
2454                    int total = user + system + iowait + irq + softIrq + idle;
2455                    if (total == 0) total = 1;
2456
2457                    EventLog.writeEvent(EventLogTags.CPU,
2458                            ((user+system+iowait+irq+softIrq) * 100) / total,
2459                            (user * 100) / total,
2460                            (system * 100) / total,
2461                            (iowait * 100) / total,
2462                            (irq * 100) / total,
2463                            (softIrq * 100) / total);
2464                }
2465            }
2466
2467            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2468            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2469            synchronized(bstats) {
2470                synchronized(mPidsSelfLocked) {
2471                    if (haveNewCpuStats) {
2472                        if (mOnBattery) {
2473                            int perc = bstats.startAddingCpuLocked();
2474                            int totalUTime = 0;
2475                            int totalSTime = 0;
2476                            final int N = mProcessCpuTracker.countStats();
2477                            for (int i=0; i<N; i++) {
2478                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2479                                if (!st.working) {
2480                                    continue;
2481                                }
2482                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2483                                int otherUTime = (st.rel_utime*perc)/100;
2484                                int otherSTime = (st.rel_stime*perc)/100;
2485                                totalUTime += otherUTime;
2486                                totalSTime += otherSTime;
2487                                if (pr != null) {
2488                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2489                                    if (ps == null || !ps.isActive()) {
2490                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2491                                                pr.info.uid, pr.processName);
2492                                    }
2493                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2494                                            st.rel_stime-otherSTime);
2495                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2496                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2497                                } else {
2498                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2499                                    if (ps == null || !ps.isActive()) {
2500                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2501                                                bstats.mapUid(st.uid), st.name);
2502                                    }
2503                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2504                                            st.rel_stime-otherSTime);
2505                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2506                                }
2507                            }
2508                            bstats.finishAddingCpuLocked(perc, totalUTime,
2509                                    totalSTime, cpuSpeedTimes);
2510                        }
2511                    }
2512                }
2513
2514                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2515                    mLastWriteTime = now;
2516                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2517                }
2518            }
2519        }
2520    }
2521
2522    @Override
2523    public void batteryNeedsCpuUpdate() {
2524        updateCpuStatsNow();
2525    }
2526
2527    @Override
2528    public void batteryPowerChanged(boolean onBattery) {
2529        // When plugging in, update the CPU stats first before changing
2530        // the plug state.
2531        updateCpuStatsNow();
2532        synchronized (this) {
2533            synchronized(mPidsSelfLocked) {
2534                mOnBattery = DEBUG_POWER ? true : onBattery;
2535            }
2536        }
2537    }
2538
2539    /**
2540     * Initialize the application bind args. These are passed to each
2541     * process when the bindApplication() IPC is sent to the process. They're
2542     * lazily setup to make sure the services are running when they're asked for.
2543     */
2544    private HashMap<String, IBinder> getCommonServicesLocked() {
2545        if (mAppBindArgs == null) {
2546            mAppBindArgs = new HashMap<String, IBinder>();
2547
2548            // Setup the application init args
2549            mAppBindArgs.put("package", ServiceManager.getService("package"));
2550            mAppBindArgs.put("window", ServiceManager.getService("window"));
2551            mAppBindArgs.put(Context.ALARM_SERVICE,
2552                    ServiceManager.getService(Context.ALARM_SERVICE));
2553        }
2554        return mAppBindArgs;
2555    }
2556
2557    final void setFocusedActivityLocked(ActivityRecord r) {
2558        if (mFocusedActivity != r) {
2559            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2560            mFocusedActivity = r;
2561            if (r.task != null && r.task.voiceInteractor != null) {
2562                startRunningVoiceLocked();
2563            } else {
2564                finishRunningVoiceLocked();
2565            }
2566            mStackSupervisor.setFocusedStack(r);
2567            if (r != null) {
2568                mWindowManager.setFocusedApp(r.appToken, true);
2569            }
2570            applyUpdateLockStateLocked(r);
2571        }
2572    }
2573
2574    final void clearFocusedActivity(ActivityRecord r) {
2575        if (mFocusedActivity == r) {
2576            mFocusedActivity = null;
2577        }
2578    }
2579
2580    @Override
2581    public void setFocusedStack(int stackId) {
2582        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2583        synchronized (ActivityManagerService.this) {
2584            ActivityStack stack = mStackSupervisor.getStack(stackId);
2585            if (stack != null) {
2586                ActivityRecord r = stack.topRunningActivityLocked(null);
2587                if (r != null) {
2588                    setFocusedActivityLocked(r);
2589                }
2590            }
2591        }
2592    }
2593
2594    @Override
2595    public void notifyActivityDrawn(IBinder token) {
2596        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2597        synchronized (this) {
2598            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2599            if (r != null) {
2600                r.task.stack.notifyActivityDrawnLocked(r);
2601            }
2602        }
2603    }
2604
2605    final void applyUpdateLockStateLocked(ActivityRecord r) {
2606        // Modifications to the UpdateLock state are done on our handler, outside
2607        // the activity manager's locks.  The new state is determined based on the
2608        // state *now* of the relevant activity record.  The object is passed to
2609        // the handler solely for logging detail, not to be consulted/modified.
2610        final boolean nextState = r != null && r.immersive;
2611        mHandler.sendMessage(
2612                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2613    }
2614
2615    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2616        Message msg = Message.obtain();
2617        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2618        msg.obj = r.task.askedCompatMode ? null : r;
2619        mHandler.sendMessage(msg);
2620    }
2621
2622    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2623            String what, Object obj, ProcessRecord srcApp) {
2624        app.lastActivityTime = now;
2625
2626        if (app.activities.size() > 0) {
2627            // Don't want to touch dependent processes that are hosting activities.
2628            return index;
2629        }
2630
2631        int lrui = mLruProcesses.lastIndexOf(app);
2632        if (lrui < 0) {
2633            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2634                    + what + " " + obj + " from " + srcApp);
2635            return index;
2636        }
2637
2638        if (lrui >= index) {
2639            // Don't want to cause this to move dependent processes *back* in the
2640            // list as if they were less frequently used.
2641            return index;
2642        }
2643
2644        if (lrui >= mLruProcessActivityStart) {
2645            // Don't want to touch dependent processes that are hosting activities.
2646            return index;
2647        }
2648
2649        mLruProcesses.remove(lrui);
2650        if (index > 0) {
2651            index--;
2652        }
2653        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2654                + " in LRU list: " + app);
2655        mLruProcesses.add(index, app);
2656        return index;
2657    }
2658
2659    final void removeLruProcessLocked(ProcessRecord app) {
2660        int lrui = mLruProcesses.lastIndexOf(app);
2661        if (lrui >= 0) {
2662            if (!app.killed) {
2663                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2664                Process.killProcessQuiet(app.pid);
2665                Process.killProcessGroup(app.info.uid, app.pid);
2666            }
2667            if (lrui <= mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui <= mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            mLruProcesses.remove(lrui);
2674        }
2675    }
2676
2677    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2678            ProcessRecord client) {
2679        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2680                || app.treatLikeActivity;
2681        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2682        if (!activityChange && hasActivity) {
2683            // The process has activities, so we are only allowing activity-based adjustments
2684            // to move it.  It should be kept in the front of the list with other
2685            // processes that have activities, and we don't want those to change their
2686            // order except due to activity operations.
2687            return;
2688        }
2689
2690        mLruSeq++;
2691        final long now = SystemClock.uptimeMillis();
2692        app.lastActivityTime = now;
2693
2694        // First a quick reject: if the app is already at the position we will
2695        // put it, then there is nothing to do.
2696        if (hasActivity) {
2697            final int N = mLruProcesses.size();
2698            if (N > 0 && mLruProcesses.get(N-1) == app) {
2699                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2700                return;
2701            }
2702        } else {
2703            if (mLruProcessServiceStart > 0
2704                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2705                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2706                return;
2707            }
2708        }
2709
2710        int lrui = mLruProcesses.lastIndexOf(app);
2711
2712        if (app.persistent && lrui >= 0) {
2713            // We don't care about the position of persistent processes, as long as
2714            // they are in the list.
2715            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2716            return;
2717        }
2718
2719        /* In progress: compute new position first, so we can avoid doing work
2720           if the process is not actually going to move.  Not yet working.
2721        int addIndex;
2722        int nextIndex;
2723        boolean inActivity = false, inService = false;
2724        if (hasActivity) {
2725            // Process has activities, put it at the very tipsy-top.
2726            addIndex = mLruProcesses.size();
2727            nextIndex = mLruProcessServiceStart;
2728            inActivity = true;
2729        } else if (hasService) {
2730            // Process has services, put it at the top of the service list.
2731            addIndex = mLruProcessActivityStart;
2732            nextIndex = mLruProcessServiceStart;
2733            inActivity = true;
2734            inService = true;
2735        } else  {
2736            // Process not otherwise of interest, it goes to the top of the non-service area.
2737            addIndex = mLruProcessServiceStart;
2738            if (client != null) {
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2741                        + app);
2742                if (clientIndex >= 0 && addIndex > clientIndex) {
2743                    addIndex = clientIndex;
2744                }
2745            }
2746            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2747        }
2748
2749        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2750                + mLruProcessActivityStart + "): " + app);
2751        */
2752
2753        if (lrui >= 0) {
2754            if (lrui < mLruProcessActivityStart) {
2755                mLruProcessActivityStart--;
2756            }
2757            if (lrui < mLruProcessServiceStart) {
2758                mLruProcessServiceStart--;
2759            }
2760            /*
2761            if (addIndex > lrui) {
2762                addIndex--;
2763            }
2764            if (nextIndex > lrui) {
2765                nextIndex--;
2766            }
2767            */
2768            mLruProcesses.remove(lrui);
2769        }
2770
2771        /*
2772        mLruProcesses.add(addIndex, app);
2773        if (inActivity) {
2774            mLruProcessActivityStart++;
2775        }
2776        if (inService) {
2777            mLruProcessActivityStart++;
2778        }
2779        */
2780
2781        int nextIndex;
2782        if (hasActivity) {
2783            final int N = mLruProcesses.size();
2784            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2785                // Process doesn't have activities, but has clients with
2786                // activities...  move it up, but one below the top (the top
2787                // should always have a real activity).
2788                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2789                mLruProcesses.add(N-1, app);
2790                // To keep it from spamming the LRU list (by making a bunch of clients),
2791                // we will push down any other entries owned by the app.
2792                final int uid = app.info.uid;
2793                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2794                    ProcessRecord subProc = mLruProcesses.get(i);
2795                    if (subProc.info.uid == uid) {
2796                        // We want to push this one down the list.  If the process after
2797                        // it is for the same uid, however, don't do so, because we don't
2798                        // want them internally to be re-ordered.
2799                        if (mLruProcesses.get(i-1).info.uid != uid) {
2800                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2801                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2802                            ProcessRecord tmp = mLruProcesses.get(i);
2803                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2804                            mLruProcesses.set(i-1, tmp);
2805                            i--;
2806                        }
2807                    } else {
2808                        // A gap, we can stop here.
2809                        break;
2810                    }
2811                }
2812            } else {
2813                // Process has activities, put it at the very tipsy-top.
2814                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2815                mLruProcesses.add(app);
2816            }
2817            nextIndex = mLruProcessServiceStart;
2818        } else if (hasService) {
2819            // Process has services, put it at the top of the service list.
2820            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2821            mLruProcesses.add(mLruProcessActivityStart, app);
2822            nextIndex = mLruProcessServiceStart;
2823            mLruProcessActivityStart++;
2824        } else  {
2825            // Process not otherwise of interest, it goes to the top of the non-service area.
2826            int index = mLruProcessServiceStart;
2827            if (client != null) {
2828                // If there is a client, don't allow the process to be moved up higher
2829                // in the list than that client.
2830                int clientIndex = mLruProcesses.lastIndexOf(client);
2831                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2832                        + " when updating " + app);
2833                if (clientIndex <= lrui) {
2834                    // Don't allow the client index restriction to push it down farther in the
2835                    // list than it already is.
2836                    clientIndex = lrui;
2837                }
2838                if (clientIndex >= 0 && index > clientIndex) {
2839                    index = clientIndex;
2840                }
2841            }
2842            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2843            mLruProcesses.add(index, app);
2844            nextIndex = index-1;
2845            mLruProcessActivityStart++;
2846            mLruProcessServiceStart++;
2847        }
2848
2849        // If the app is currently using a content provider or service,
2850        // bump those processes as well.
2851        for (int j=app.connections.size()-1; j>=0; j--) {
2852            ConnectionRecord cr = app.connections.valueAt(j);
2853            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2854                    && cr.binding.service.app != null
2855                    && cr.binding.service.app.lruSeq != mLruSeq
2856                    && !cr.binding.service.app.persistent) {
2857                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2858                        "service connection", cr, app);
2859            }
2860        }
2861        for (int j=app.conProviders.size()-1; j>=0; j--) {
2862            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2863            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2864                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2865                        "provider reference", cpr, app);
2866            }
2867        }
2868    }
2869
2870    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2871        if (uid == Process.SYSTEM_UID) {
2872            // The system gets to run in any process.  If there are multiple
2873            // processes with the same uid, just pick the first (this
2874            // should never happen).
2875            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2876            if (procs == null) return null;
2877            final int N = procs.size();
2878            for (int i = 0; i < N; i++) {
2879                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2880            }
2881        }
2882        ProcessRecord proc = mProcessNames.get(processName, uid);
2883        if (false && proc != null && !keepIfLarge
2884                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2885                && proc.lastCachedPss >= 4000) {
2886            // Turn this condition on to cause killing to happen regularly, for testing.
2887            if (proc.baseProcessTracker != null) {
2888                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2889            }
2890            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2891        } else if (proc != null && !keepIfLarge
2892                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2893                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2894            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2895            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2896                if (proc.baseProcessTracker != null) {
2897                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2898                }
2899                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2900            }
2901        }
2902        return proc;
2903    }
2904
2905    void ensurePackageDexOpt(String packageName) {
2906        IPackageManager pm = AppGlobals.getPackageManager();
2907        try {
2908            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2909                mDidDexOpt = true;
2910            }
2911        } catch (RemoteException e) {
2912        }
2913    }
2914
2915    boolean isNextTransitionForward() {
2916        int transit = mWindowManager.getPendingAppTransition();
2917        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2918                || transit == AppTransition.TRANSIT_TASK_OPEN
2919                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2920    }
2921
2922    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2923            String processName, String abiOverride, int uid, Runnable crashHandler) {
2924        synchronized(this) {
2925            ApplicationInfo info = new ApplicationInfo();
2926            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2927            // For isolated processes, the former contains the parent's uid and the latter the
2928            // actual uid of the isolated process.
2929            // In the special case introduced by this method (which is, starting an isolated
2930            // process directly from the SystemServer without an actual parent app process) the
2931            // closest thing to a parent's uid is SYSTEM_UID.
2932            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2933            // the |isolated| logic in the ProcessRecord constructor.
2934            info.uid = Process.SYSTEM_UID;
2935            info.processName = processName;
2936            info.className = entryPoint;
2937            info.packageName = "android";
2938            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2939                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2940                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2941                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2942                    crashHandler);
2943            return proc != null ? proc.pid : 0;
2944        }
2945    }
2946
2947    final ProcessRecord startProcessLocked(String processName,
2948            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2949            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2950            boolean isolated, boolean keepIfLarge) {
2951        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2952                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2953                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2954                null /* crashHandler */);
2955    }
2956
2957    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2958            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2959            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2960            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2961        long startTime = SystemClock.elapsedRealtime();
2962        ProcessRecord app;
2963        if (!isolated) {
2964            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2965            checkTime(startTime, "startProcess: after getProcessRecord");
2966        } else {
2967            // If this is an isolated process, it can't re-use an existing process.
2968            app = null;
2969        }
2970        // We don't have to do anything more if:
2971        // (1) There is an existing application record; and
2972        // (2) The caller doesn't think it is dead, OR there is no thread
2973        //     object attached to it so we know it couldn't have crashed; and
2974        // (3) There is a pid assigned to it, so it is either starting or
2975        //     already running.
2976        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2977                + " app=" + app + " knownToBeDead=" + knownToBeDead
2978                + " thread=" + (app != null ? app.thread : null)
2979                + " pid=" + (app != null ? app.pid : -1));
2980        if (app != null && app.pid > 0) {
2981            if (!knownToBeDead || app.thread == null) {
2982                // We already have the app running, or are waiting for it to
2983                // come up (we have a pid but not yet its thread), so keep it.
2984                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2985                // If this is a new package in the process, add the package to the list
2986                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2987                checkTime(startTime, "startProcess: done, added package to proc");
2988                return app;
2989            }
2990
2991            // An application record is attached to a previous process,
2992            // clean it up now.
2993            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2994            checkTime(startTime, "startProcess: bad proc running, killing");
2995            Process.killProcessGroup(app.info.uid, app.pid);
2996            handleAppDiedLocked(app, true, true);
2997            checkTime(startTime, "startProcess: done killing old proc");
2998        }
2999
3000        String hostingNameStr = hostingName != null
3001                ? hostingName.flattenToShortString() : null;
3002
3003        if (!isolated) {
3004            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3005                // If we are in the background, then check to see if this process
3006                // is bad.  If so, we will just silently fail.
3007                if (mBadProcesses.get(info.processName, info.uid) != null) {
3008                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3009                            + "/" + info.processName);
3010                    return null;
3011                }
3012            } else {
3013                // When the user is explicitly starting a process, then clear its
3014                // crash count so that we won't make it bad until they see at
3015                // least one crash dialog again, and make the process good again
3016                // if it had been bad.
3017                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3018                        + "/" + info.processName);
3019                mProcessCrashTimes.remove(info.processName, info.uid);
3020                if (mBadProcesses.get(info.processName, info.uid) != null) {
3021                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3022                            UserHandle.getUserId(info.uid), info.uid,
3023                            info.processName);
3024                    mBadProcesses.remove(info.processName, info.uid);
3025                    if (app != null) {
3026                        app.bad = false;
3027                    }
3028                }
3029            }
3030        }
3031
3032        if (app == null) {
3033            checkTime(startTime, "startProcess: creating new process record");
3034            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3035            app.crashHandler = crashHandler;
3036            if (app == null) {
3037                Slog.w(TAG, "Failed making new process record for "
3038                        + processName + "/" + info.uid + " isolated=" + isolated);
3039                return null;
3040            }
3041            mProcessNames.put(processName, app.uid, app);
3042            if (isolated) {
3043                mIsolatedProcesses.put(app.uid, app);
3044            }
3045            checkTime(startTime, "startProcess: done creating new process record");
3046        } else {
3047            // If this is a new package in the process, add the package to the list
3048            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3049            checkTime(startTime, "startProcess: added package to existing proc");
3050        }
3051
3052        // If the system is not ready yet, then hold off on starting this
3053        // process until it is.
3054        if (!mProcessesReady
3055                && !isAllowedWhileBooting(info)
3056                && !allowWhileBooting) {
3057            if (!mProcessesOnHold.contains(app)) {
3058                mProcessesOnHold.add(app);
3059            }
3060            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3061            checkTime(startTime, "startProcess: returning with proc on hold");
3062            return app;
3063        }
3064
3065        checkTime(startTime, "startProcess: stepping in to startProcess");
3066        startProcessLocked(
3067                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3068        checkTime(startTime, "startProcess: done starting proc!");
3069        return (app.pid != 0) ? app : null;
3070    }
3071
3072    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3073        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3074    }
3075
3076    private final void startProcessLocked(ProcessRecord app,
3077            String hostingType, String hostingNameStr) {
3078        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3079                null /* entryPoint */, null /* entryPointArgs */);
3080    }
3081
3082    private final void startProcessLocked(ProcessRecord app, String hostingType,
3083            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3084        long startTime = SystemClock.elapsedRealtime();
3085        if (app.pid > 0 && app.pid != MY_PID) {
3086            checkTime(startTime, "startProcess: removing from pids map");
3087            synchronized (mPidsSelfLocked) {
3088                mPidsSelfLocked.remove(app.pid);
3089                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3090            }
3091            checkTime(startTime, "startProcess: done removing from pids map");
3092            app.setPid(0);
3093        }
3094
3095        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3096                "startProcessLocked removing on hold: " + app);
3097        mProcessesOnHold.remove(app);
3098
3099        checkTime(startTime, "startProcess: starting to update cpu stats");
3100        updateCpuStats();
3101        checkTime(startTime, "startProcess: done updating cpu stats");
3102
3103        try {
3104            int uid = app.uid;
3105
3106            int[] gids = null;
3107            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3108            if (!app.isolated) {
3109                int[] permGids = null;
3110                try {
3111                    checkTime(startTime, "startProcess: getting gids from package manager");
3112                    final PackageManager pm = mContext.getPackageManager();
3113                    permGids = pm.getPackageGids(app.info.packageName);
3114
3115                    if (Environment.isExternalStorageEmulated()) {
3116                        checkTime(startTime, "startProcess: checking external storage perm");
3117                        if (pm.checkPermission(
3118                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3119                                app.info.packageName) == PERMISSION_GRANTED) {
3120                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3121                        } else {
3122                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3123                        }
3124                    }
3125                } catch (PackageManager.NameNotFoundException e) {
3126                    Slog.w(TAG, "Unable to retrieve gids", e);
3127                }
3128
3129                /*
3130                 * Add shared application and profile GIDs so applications can share some
3131                 * resources like shared libraries and access user-wide resources
3132                 */
3133                if (permGids == null) {
3134                    gids = new int[2];
3135                } else {
3136                    gids = new int[permGids.length + 2];
3137                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3138                }
3139                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3140                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3141            }
3142            checkTime(startTime, "startProcess: building args");
3143            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3144                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3145                        && mTopComponent != null
3146                        && app.processName.equals(mTopComponent.getPackageName())) {
3147                    uid = 0;
3148                }
3149                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3150                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3151                    uid = 0;
3152                }
3153            }
3154            int debugFlags = 0;
3155            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3156                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3157                // Also turn on CheckJNI for debuggable apps. It's quite
3158                // awkward to turn on otherwise.
3159                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3160            }
3161            // Run the app in safe mode if its manifest requests so or the
3162            // system is booted in safe mode.
3163            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3164                mSafeMode == true) {
3165                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3166            }
3167            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3168                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3169            }
3170            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3171                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3172            }
3173            if ("1".equals(SystemProperties.get("debug.assert"))) {
3174                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3175            }
3176
3177            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3178            if (requiredAbi == null) {
3179                requiredAbi = Build.SUPPORTED_ABIS[0];
3180            }
3181
3182            String instructionSet = null;
3183            if (app.info.primaryCpuAbi != null) {
3184                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3185            }
3186
3187            // Start the process.  It will either succeed and return a result containing
3188            // the PID of the new process, or else throw a RuntimeException.
3189            boolean isActivityProcess = (entryPoint == null);
3190            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3191            checkTime(startTime, "startProcess: asking zygote to start proc");
3192            Process.ProcessStartResult startResult = Process.start(entryPoint,
3193                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3194                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3195                    app.info.dataDir, entryPointArgs);
3196            checkTime(startTime, "startProcess: returned from zygote!");
3197
3198            if (app.isolated) {
3199                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3200            }
3201            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3202            checkTime(startTime, "startProcess: done updating battery stats");
3203
3204            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3205                    UserHandle.getUserId(uid), startResult.pid, uid,
3206                    app.processName, hostingType,
3207                    hostingNameStr != null ? hostingNameStr : "");
3208
3209            if (app.persistent) {
3210                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3211            }
3212
3213            checkTime(startTime, "startProcess: building log message");
3214            StringBuilder buf = mStringBuilder;
3215            buf.setLength(0);
3216            buf.append("Start proc ");
3217            buf.append(app.processName);
3218            if (!isActivityProcess) {
3219                buf.append(" [");
3220                buf.append(entryPoint);
3221                buf.append("]");
3222            }
3223            buf.append(" for ");
3224            buf.append(hostingType);
3225            if (hostingNameStr != null) {
3226                buf.append(" ");
3227                buf.append(hostingNameStr);
3228            }
3229            buf.append(": pid=");
3230            buf.append(startResult.pid);
3231            buf.append(" uid=");
3232            buf.append(uid);
3233            buf.append(" gids={");
3234            if (gids != null) {
3235                for (int gi=0; gi<gids.length; gi++) {
3236                    if (gi != 0) buf.append(", ");
3237                    buf.append(gids[gi]);
3238
3239                }
3240            }
3241            buf.append("}");
3242            if (requiredAbi != null) {
3243                buf.append(" abi=");
3244                buf.append(requiredAbi);
3245            }
3246            Slog.i(TAG, buf.toString());
3247            app.setPid(startResult.pid);
3248            app.usingWrapper = startResult.usingWrapper;
3249            app.removed = false;
3250            app.killed = false;
3251            app.killedByAm = false;
3252            checkTime(startTime, "startProcess: starting to update pids map");
3253            synchronized (mPidsSelfLocked) {
3254                this.mPidsSelfLocked.put(startResult.pid, app);
3255                if (isActivityProcess) {
3256                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3257                    msg.obj = app;
3258                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3259                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3260                }
3261            }
3262            checkTime(startTime, "startProcess: done updating pids map");
3263        } catch (RuntimeException e) {
3264            // XXX do better error recovery.
3265            app.setPid(0);
3266            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3267            if (app.isolated) {
3268                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3269            }
3270            Slog.e(TAG, "Failure starting process " + app.processName, e);
3271        }
3272    }
3273
3274    void updateUsageStats(ActivityRecord component, boolean resumed) {
3275        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3276        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3277        if (resumed) {
3278            if (mUsageStatsService != null) {
3279                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3280                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3281            }
3282            synchronized (stats) {
3283                stats.noteActivityResumedLocked(component.app.uid);
3284            }
3285        } else {
3286            if (mUsageStatsService != null) {
3287                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3288                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3289            }
3290            synchronized (stats) {
3291                stats.noteActivityPausedLocked(component.app.uid);
3292            }
3293        }
3294    }
3295
3296    Intent getHomeIntent() {
3297        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3298        intent.setComponent(mTopComponent);
3299        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3300            intent.addCategory(Intent.CATEGORY_HOME);
3301        }
3302        return intent;
3303    }
3304
3305    boolean startHomeActivityLocked(int userId) {
3306        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3307                && mTopAction == null) {
3308            // We are running in factory test mode, but unable to find
3309            // the factory test app, so just sit around displaying the
3310            // error message and don't try to start anything.
3311            return false;
3312        }
3313        Intent intent = getHomeIntent();
3314        ActivityInfo aInfo =
3315            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3316        if (aInfo != null) {
3317            intent.setComponent(new ComponentName(
3318                    aInfo.applicationInfo.packageName, aInfo.name));
3319            // Don't do this if the home app is currently being
3320            // instrumented.
3321            aInfo = new ActivityInfo(aInfo);
3322            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3323            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3324                    aInfo.applicationInfo.uid, true);
3325            if (app == null || app.instrumentationClass == null) {
3326                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3327                mStackSupervisor.startHomeActivity(intent, aInfo);
3328            }
3329        }
3330
3331        return true;
3332    }
3333
3334    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3335        ActivityInfo ai = null;
3336        ComponentName comp = intent.getComponent();
3337        try {
3338            if (comp != null) {
3339                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3340            } else {
3341                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3342                        intent,
3343                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3344                            flags, userId);
3345
3346                if (info != null) {
3347                    ai = info.activityInfo;
3348                }
3349            }
3350        } catch (RemoteException e) {
3351            // ignore
3352        }
3353
3354        return ai;
3355    }
3356
3357    /**
3358     * Starts the "new version setup screen" if appropriate.
3359     */
3360    void startSetupActivityLocked() {
3361        // Only do this once per boot.
3362        if (mCheckedForSetup) {
3363            return;
3364        }
3365
3366        // We will show this screen if the current one is a different
3367        // version than the last one shown, and we are not running in
3368        // low-level factory test mode.
3369        final ContentResolver resolver = mContext.getContentResolver();
3370        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3371                Settings.Global.getInt(resolver,
3372                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3373            mCheckedForSetup = true;
3374
3375            // See if we should be showing the platform update setup UI.
3376            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3377            List<ResolveInfo> ris = mContext.getPackageManager()
3378                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3379
3380            // We don't allow third party apps to replace this.
3381            ResolveInfo ri = null;
3382            for (int i=0; ris != null && i<ris.size(); i++) {
3383                if ((ris.get(i).activityInfo.applicationInfo.flags
3384                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3385                    ri = ris.get(i);
3386                    break;
3387                }
3388            }
3389
3390            if (ri != null) {
3391                String vers = ri.activityInfo.metaData != null
3392                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3393                        : null;
3394                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3395                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3396                            Intent.METADATA_SETUP_VERSION);
3397                }
3398                String lastVers = Settings.Secure.getString(
3399                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3400                if (vers != null && !vers.equals(lastVers)) {
3401                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3402                    intent.setComponent(new ComponentName(
3403                            ri.activityInfo.packageName, ri.activityInfo.name));
3404                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3405                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3406                            null);
3407                }
3408            }
3409        }
3410    }
3411
3412    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3413        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3414    }
3415
3416    void enforceNotIsolatedCaller(String caller) {
3417        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3418            throw new SecurityException("Isolated process not allowed to call " + caller);
3419        }
3420    }
3421
3422    void enforceShellRestriction(String restriction, int userHandle) {
3423        if (Binder.getCallingUid() == Process.SHELL_UID) {
3424            if (userHandle < 0
3425                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3426                throw new SecurityException("Shell does not have permission to access user "
3427                        + userHandle);
3428            }
3429        }
3430    }
3431
3432    @Override
3433    public int getFrontActivityScreenCompatMode() {
3434        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3435        synchronized (this) {
3436            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3437        }
3438    }
3439
3440    @Override
3441    public void setFrontActivityScreenCompatMode(int mode) {
3442        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3443                "setFrontActivityScreenCompatMode");
3444        synchronized (this) {
3445            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3446        }
3447    }
3448
3449    @Override
3450    public int getPackageScreenCompatMode(String packageName) {
3451        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3452        synchronized (this) {
3453            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3454        }
3455    }
3456
3457    @Override
3458    public void setPackageScreenCompatMode(String packageName, int mode) {
3459        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3460                "setPackageScreenCompatMode");
3461        synchronized (this) {
3462            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3463        }
3464    }
3465
3466    @Override
3467    public boolean getPackageAskScreenCompat(String packageName) {
3468        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3469        synchronized (this) {
3470            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3471        }
3472    }
3473
3474    @Override
3475    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3476        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3477                "setPackageAskScreenCompat");
3478        synchronized (this) {
3479            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3480        }
3481    }
3482
3483    private void dispatchProcessesChanged() {
3484        int N;
3485        synchronized (this) {
3486            N = mPendingProcessChanges.size();
3487            if (mActiveProcessChanges.length < N) {
3488                mActiveProcessChanges = new ProcessChangeItem[N];
3489            }
3490            mPendingProcessChanges.toArray(mActiveProcessChanges);
3491            mAvailProcessChanges.addAll(mPendingProcessChanges);
3492            mPendingProcessChanges.clear();
3493            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3494        }
3495
3496        int i = mProcessObservers.beginBroadcast();
3497        while (i > 0) {
3498            i--;
3499            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3500            if (observer != null) {
3501                try {
3502                    for (int j=0; j<N; j++) {
3503                        ProcessChangeItem item = mActiveProcessChanges[j];
3504                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3505                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3506                                    + item.pid + " uid=" + item.uid + ": "
3507                                    + item.foregroundActivities);
3508                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3509                                    item.foregroundActivities);
3510                        }
3511                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3512                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3513                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3514                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3515                        }
3516                    }
3517                } catch (RemoteException e) {
3518                }
3519            }
3520        }
3521        mProcessObservers.finishBroadcast();
3522    }
3523
3524    private void dispatchProcessDied(int pid, int uid) {
3525        int i = mProcessObservers.beginBroadcast();
3526        while (i > 0) {
3527            i--;
3528            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3529            if (observer != null) {
3530                try {
3531                    observer.onProcessDied(pid, uid);
3532                } catch (RemoteException e) {
3533                }
3534            }
3535        }
3536        mProcessObservers.finishBroadcast();
3537    }
3538
3539    @Override
3540    public final int startActivity(IApplicationThread caller, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3542            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3543        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3544            resultWho, requestCode, startFlags, profilerInfo, options,
3545            UserHandle.getCallingUserId());
3546    }
3547
3548    @Override
3549    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3550            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3551            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3552        enforceNotIsolatedCaller("startActivity");
3553        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3554                false, ALLOW_FULL_ONLY, "startActivity", null);
3555        // TODO: Switch to user app stacks here.
3556        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3557                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3558                profilerInfo, null, null, options, userId, null, null);
3559    }
3560
3561    @Override
3562    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3563            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3564            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3565
3566        // This is very dangerous -- it allows you to perform a start activity (including
3567        // permission grants) as any app that may launch one of your own activities.  So
3568        // we will only allow this to be done from activities that are part of the core framework,
3569        // and then only when they are running as the system.
3570        final ActivityRecord sourceRecord;
3571        final int targetUid;
3572        final String targetPackage;
3573        synchronized (this) {
3574            if (resultTo == null) {
3575                throw new SecurityException("Must be called from an activity");
3576            }
3577            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3578            if (sourceRecord == null) {
3579                throw new SecurityException("Called with bad activity token: " + resultTo);
3580            }
3581            if (!sourceRecord.info.packageName.equals("android")) {
3582                throw new SecurityException(
3583                        "Must be called from an activity that is declared in the android package");
3584            }
3585            if (sourceRecord.app == null) {
3586                throw new SecurityException("Called without a process attached to activity");
3587            }
3588            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3589                // This is still okay, as long as this activity is running under the
3590                // uid of the original calling activity.
3591                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3592                    throw new SecurityException(
3593                            "Calling activity in uid " + sourceRecord.app.uid
3594                                    + " must be system uid or original calling uid "
3595                                    + sourceRecord.launchedFromUid);
3596                }
3597            }
3598            targetUid = sourceRecord.launchedFromUid;
3599            targetPackage = sourceRecord.launchedFromPackage;
3600        }
3601
3602        // TODO: Switch to user app stacks here.
3603        try {
3604            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3605                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3606                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3607            return ret;
3608        } catch (SecurityException e) {
3609            // XXX need to figure out how to propagate to original app.
3610            // A SecurityException here is generally actually a fault of the original
3611            // calling activity (such as a fairly granting permissions), so propagate it
3612            // back to them.
3613            /*
3614            StringBuilder msg = new StringBuilder();
3615            msg.append("While launching");
3616            msg.append(intent.toString());
3617            msg.append(": ");
3618            msg.append(e.getMessage());
3619            */
3620            throw e;
3621        }
3622    }
3623
3624    @Override
3625    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3626            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3627            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3628        enforceNotIsolatedCaller("startActivityAndWait");
3629        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3630                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3631        WaitResult res = new WaitResult();
3632        // TODO: Switch to user app stacks here.
3633        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3634                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3635                options, userId, null, null);
3636        return res;
3637    }
3638
3639    @Override
3640    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3641            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3642            int startFlags, Configuration config, Bundle options, int userId) {
3643        enforceNotIsolatedCaller("startActivityWithConfig");
3644        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3645                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3646        // TODO: Switch to user app stacks here.
3647        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3648                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3649                null, null, config, options, userId, null, null);
3650        return ret;
3651    }
3652
3653    @Override
3654    public int startActivityIntentSender(IApplicationThread caller,
3655            IntentSender intent, Intent fillInIntent, String resolvedType,
3656            IBinder resultTo, String resultWho, int requestCode,
3657            int flagsMask, int flagsValues, Bundle options) {
3658        enforceNotIsolatedCaller("startActivityIntentSender");
3659        // Refuse possible leaked file descriptors
3660        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3661            throw new IllegalArgumentException("File descriptors passed in Intent");
3662        }
3663
3664        IIntentSender sender = intent.getTarget();
3665        if (!(sender instanceof PendingIntentRecord)) {
3666            throw new IllegalArgumentException("Bad PendingIntent object");
3667        }
3668
3669        PendingIntentRecord pir = (PendingIntentRecord)sender;
3670
3671        synchronized (this) {
3672            // If this is coming from the currently resumed activity, it is
3673            // effectively saying that app switches are allowed at this point.
3674            final ActivityStack stack = getFocusedStack();
3675            if (stack.mResumedActivity != null &&
3676                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3677                mAppSwitchesAllowedTime = 0;
3678            }
3679        }
3680        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3681                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3682        return ret;
3683    }
3684
3685    @Override
3686    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3687            Intent intent, String resolvedType, IVoiceInteractionSession session,
3688            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3689            Bundle options, int userId) {
3690        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3691                != PackageManager.PERMISSION_GRANTED) {
3692            String msg = "Permission Denial: startVoiceActivity() from pid="
3693                    + Binder.getCallingPid()
3694                    + ", uid=" + Binder.getCallingUid()
3695                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3696            Slog.w(TAG, msg);
3697            throw new SecurityException(msg);
3698        }
3699        if (session == null || interactor == null) {
3700            throw new NullPointerException("null session or interactor");
3701        }
3702        userId = handleIncomingUser(callingPid, callingUid, userId,
3703                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3704        // TODO: Switch to user app stacks here.
3705        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3706                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3707                null, options, userId, null, null);
3708    }
3709
3710    @Override
3711    public boolean startNextMatchingActivity(IBinder callingActivity,
3712            Intent intent, Bundle options) {
3713        // Refuse possible leaked file descriptors
3714        if (intent != null && intent.hasFileDescriptors() == true) {
3715            throw new IllegalArgumentException("File descriptors passed in Intent");
3716        }
3717
3718        synchronized (this) {
3719            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3720            if (r == null) {
3721                ActivityOptions.abort(options);
3722                return false;
3723            }
3724            if (r.app == null || r.app.thread == null) {
3725                // The caller is not running...  d'oh!
3726                ActivityOptions.abort(options);
3727                return false;
3728            }
3729            intent = new Intent(intent);
3730            // The caller is not allowed to change the data.
3731            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3732            // And we are resetting to find the next component...
3733            intent.setComponent(null);
3734
3735            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3736
3737            ActivityInfo aInfo = null;
3738            try {
3739                List<ResolveInfo> resolves =
3740                    AppGlobals.getPackageManager().queryIntentActivities(
3741                            intent, r.resolvedType,
3742                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3743                            UserHandle.getCallingUserId());
3744
3745                // Look for the original activity in the list...
3746                final int N = resolves != null ? resolves.size() : 0;
3747                for (int i=0; i<N; i++) {
3748                    ResolveInfo rInfo = resolves.get(i);
3749                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3750                            && rInfo.activityInfo.name.equals(r.info.name)) {
3751                        // We found the current one...  the next matching is
3752                        // after it.
3753                        i++;
3754                        if (i<N) {
3755                            aInfo = resolves.get(i).activityInfo;
3756                        }
3757                        if (debug) {
3758                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3759                                    + "/" + r.info.name);
3760                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3761                                    + "/" + aInfo.name);
3762                        }
3763                        break;
3764                    }
3765                }
3766            } catch (RemoteException e) {
3767            }
3768
3769            if (aInfo == null) {
3770                // Nobody who is next!
3771                ActivityOptions.abort(options);
3772                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3773                return false;
3774            }
3775
3776            intent.setComponent(new ComponentName(
3777                    aInfo.applicationInfo.packageName, aInfo.name));
3778            intent.setFlags(intent.getFlags()&~(
3779                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3780                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3781                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3782                    Intent.FLAG_ACTIVITY_NEW_TASK));
3783
3784            // Okay now we need to start the new activity, replacing the
3785            // currently running activity.  This is a little tricky because
3786            // we want to start the new one as if the current one is finished,
3787            // but not finish the current one first so that there is no flicker.
3788            // And thus...
3789            final boolean wasFinishing = r.finishing;
3790            r.finishing = true;
3791
3792            // Propagate reply information over to the new activity.
3793            final ActivityRecord resultTo = r.resultTo;
3794            final String resultWho = r.resultWho;
3795            final int requestCode = r.requestCode;
3796            r.resultTo = null;
3797            if (resultTo != null) {
3798                resultTo.removeResultsLocked(r, resultWho, requestCode);
3799            }
3800
3801            final long origId = Binder.clearCallingIdentity();
3802            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3803                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3804                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3805                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3806            Binder.restoreCallingIdentity(origId);
3807
3808            r.finishing = wasFinishing;
3809            if (res != ActivityManager.START_SUCCESS) {
3810                return false;
3811            }
3812            return true;
3813        }
3814    }
3815
3816    @Override
3817    public final int startActivityFromRecents(int taskId, Bundle options) {
3818        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3819            String msg = "Permission Denial: startActivityFromRecents called without " +
3820                    START_TASKS_FROM_RECENTS;
3821            Slog.w(TAG, msg);
3822            throw new SecurityException(msg);
3823        }
3824        return startActivityFromRecentsInner(taskId, options);
3825    }
3826
3827    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3828        final TaskRecord task;
3829        final int callingUid;
3830        final String callingPackage;
3831        final Intent intent;
3832        final int userId;
3833        synchronized (this) {
3834            task = recentTaskForIdLocked(taskId);
3835            if (task == null) {
3836                throw new IllegalArgumentException("Task " + taskId + " not found.");
3837            }
3838            callingUid = task.mCallingUid;
3839            callingPackage = task.mCallingPackage;
3840            intent = task.intent;
3841            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3842            userId = task.userId;
3843        }
3844        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3845                options, userId, null, task);
3846    }
3847
3848    final int startActivityInPackage(int uid, String callingPackage,
3849            Intent intent, String resolvedType, IBinder resultTo,
3850            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3851            IActivityContainer container, TaskRecord inTask) {
3852
3853        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3854                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3855
3856        // TODO: Switch to user app stacks here.
3857        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3858                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3859                null, null, null, options, userId, container, inTask);
3860        return ret;
3861    }
3862
3863    @Override
3864    public final int startActivities(IApplicationThread caller, String callingPackage,
3865            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3866            int userId) {
3867        enforceNotIsolatedCaller("startActivities");
3868        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3869                false, ALLOW_FULL_ONLY, "startActivity", null);
3870        // TODO: Switch to user app stacks here.
3871        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3872                resolvedTypes, resultTo, options, userId);
3873        return ret;
3874    }
3875
3876    final int startActivitiesInPackage(int uid, String callingPackage,
3877            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3878            Bundle options, int userId) {
3879
3880        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3881                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3882        // TODO: Switch to user app stacks here.
3883        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3884                resultTo, options, userId);
3885        return ret;
3886    }
3887
3888    //explicitly remove thd old information in mRecentTasks when removing existing user.
3889    private void removeRecentTasksForUserLocked(int userId) {
3890        if(userId <= 0) {
3891            Slog.i(TAG, "Can't remove recent task on user " + userId);
3892            return;
3893        }
3894
3895        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3896            TaskRecord tr = mRecentTasks.get(i);
3897            if (tr.userId == userId) {
3898                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3899                        + " when finishing user" + userId);
3900                mRecentTasks.remove(i);
3901                tr.removedFromRecents(mTaskPersister);
3902            }
3903        }
3904
3905        // Remove tasks from persistent storage.
3906        mTaskPersister.wakeup(null, true);
3907    }
3908
3909    // Sort by taskId
3910    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3911        @Override
3912        public int compare(TaskRecord lhs, TaskRecord rhs) {
3913            return rhs.taskId - lhs.taskId;
3914        }
3915    };
3916
3917    // Extract the affiliates of the chain containing mRecentTasks[start].
3918    private int processNextAffiliateChain(int start) {
3919        final TaskRecord startTask = mRecentTasks.get(start);
3920        final int affiliateId = startTask.mAffiliatedTaskId;
3921
3922        // Quick identification of isolated tasks. I.e. those not launched behind.
3923        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3924                startTask.mNextAffiliate == null) {
3925            // There is still a slim chance that there are other tasks that point to this task
3926            // and that the chain is so messed up that this task no longer points to them but
3927            // the gain of this optimization outweighs the risk.
3928            startTask.inRecents = true;
3929            return start + 1;
3930        }
3931
3932        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3933        mTmpRecents.clear();
3934        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3935            final TaskRecord task = mRecentTasks.get(i);
3936            if (task.mAffiliatedTaskId == affiliateId) {
3937                mRecentTasks.remove(i);
3938                mTmpRecents.add(task);
3939            }
3940        }
3941
3942        // Sort them all by taskId. That is the order they were create in and that order will
3943        // always be correct.
3944        Collections.sort(mTmpRecents, mTaskRecordComparator);
3945
3946        // Go through and fix up the linked list.
3947        // The first one is the end of the chain and has no next.
3948        final TaskRecord first = mTmpRecents.get(0);
3949        first.inRecents = true;
3950        if (first.mNextAffiliate != null) {
3951            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3952            first.setNextAffiliate(null);
3953            mTaskPersister.wakeup(first, false);
3954        }
3955        // Everything in the middle is doubly linked from next to prev.
3956        final int tmpSize = mTmpRecents.size();
3957        for (int i = 0; i < tmpSize - 1; ++i) {
3958            final TaskRecord next = mTmpRecents.get(i);
3959            final TaskRecord prev = mTmpRecents.get(i + 1);
3960            if (next.mPrevAffiliate != prev) {
3961                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3962                        " setting prev=" + prev);
3963                next.setPrevAffiliate(prev);
3964                mTaskPersister.wakeup(next, false);
3965            }
3966            if (prev.mNextAffiliate != next) {
3967                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3968                        " setting next=" + next);
3969                prev.setNextAffiliate(next);
3970                mTaskPersister.wakeup(prev, false);
3971            }
3972            prev.inRecents = true;
3973        }
3974        // The last one is the beginning of the list and has no prev.
3975        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3976        if (last.mPrevAffiliate != null) {
3977            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3978            last.setPrevAffiliate(null);
3979            mTaskPersister.wakeup(last, false);
3980        }
3981
3982        // Insert the group back into mRecentTasks at start.
3983        mRecentTasks.addAll(start, mTmpRecents);
3984
3985        // Let the caller know where we left off.
3986        return start + tmpSize;
3987    }
3988
3989    /**
3990     * Update the recent tasks lists: make sure tasks should still be here (their
3991     * applications / activities still exist), update their availability, fixup ordering
3992     * of affiliations.
3993     */
3994    void cleanupRecentTasksLocked(int userId) {
3995        if (mRecentTasks == null) {
3996            // Happens when called from the packagemanager broadcast before boot.
3997            return;
3998        }
3999
4000        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4001        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4002        final IPackageManager pm = AppGlobals.getPackageManager();
4003        final ActivityInfo dummyAct = new ActivityInfo();
4004        final ApplicationInfo dummyApp = new ApplicationInfo();
4005
4006        int N = mRecentTasks.size();
4007
4008        int[] users = userId == UserHandle.USER_ALL
4009                ? getUsersLocked() : new int[] { userId };
4010        for (int user : users) {
4011            for (int i = 0; i < N; i++) {
4012                TaskRecord task = mRecentTasks.get(i);
4013                if (task.userId != user) {
4014                    // Only look at tasks for the user ID of interest.
4015                    continue;
4016                }
4017                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4018                    // This situation is broken, and we should just get rid of it now.
4019                    mRecentTasks.remove(i);
4020                    task.removedFromRecents(mTaskPersister);
4021                    i--;
4022                    N--;
4023                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4024                    continue;
4025                }
4026                // Check whether this activity is currently available.
4027                if (task.realActivity != null) {
4028                    ActivityInfo ai = availActCache.get(task.realActivity);
4029                    if (ai == null) {
4030                        try {
4031                            ai = pm.getActivityInfo(task.realActivity,
4032                                    PackageManager.GET_UNINSTALLED_PACKAGES
4033                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4034                        } catch (RemoteException e) {
4035                            // Will never happen.
4036                            continue;
4037                        }
4038                        if (ai == null) {
4039                            ai = dummyAct;
4040                        }
4041                        availActCache.put(task.realActivity, ai);
4042                    }
4043                    if (ai == dummyAct) {
4044                        // This could be either because the activity no longer exists, or the
4045                        // app is temporarily gone.  For the former we want to remove the recents
4046                        // entry; for the latter we want to mark it as unavailable.
4047                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4048                        if (app == null) {
4049                            try {
4050                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4051                                        PackageManager.GET_UNINSTALLED_PACKAGES
4052                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4053                            } catch (RemoteException e) {
4054                                // Will never happen.
4055                                continue;
4056                            }
4057                            if (app == null) {
4058                                app = dummyApp;
4059                            }
4060                            availAppCache.put(task.realActivity.getPackageName(), app);
4061                        }
4062                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4063                            // Doesn't exist any more!  Good-bye.
4064                            mRecentTasks.remove(i);
4065                            task.removedFromRecents(mTaskPersister);
4066                            i--;
4067                            N--;
4068                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4069                            continue;
4070                        } else {
4071                            // Otherwise just not available for now.
4072                            if (task.isAvailable) {
4073                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4074                                        + task);
4075                            }
4076                            task.isAvailable = false;
4077                        }
4078                    } else {
4079                        if (!ai.enabled || !ai.applicationInfo.enabled
4080                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4081                            if (task.isAvailable) {
4082                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4083                                        + task + " (enabled=" + ai.enabled + "/"
4084                                        + ai.applicationInfo.enabled +  " flags="
4085                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4086                            }
4087                            task.isAvailable = false;
4088                        } else {
4089                            if (!task.isAvailable) {
4090                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4091                                        + task);
4092                            }
4093                            task.isAvailable = true;
4094                        }
4095                    }
4096                }
4097            }
4098        }
4099
4100        // Verify the affiliate chain for each task.
4101        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4102        }
4103
4104        mTmpRecents.clear();
4105        // mRecentTasks is now in sorted, affiliated order.
4106    }
4107
4108    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4109        int N = mRecentTasks.size();
4110        TaskRecord top = task;
4111        int topIndex = taskIndex;
4112        while (top.mNextAffiliate != null && topIndex > 0) {
4113            top = top.mNextAffiliate;
4114            topIndex--;
4115        }
4116        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4117                + topIndex + " from intial " + taskIndex);
4118        // Find the end of the chain, doing a sanity check along the way.
4119        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4120        int endIndex = topIndex;
4121        TaskRecord prev = top;
4122        while (endIndex < N) {
4123            TaskRecord cur = mRecentTasks.get(endIndex);
4124            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4125                    + endIndex + " " + cur);
4126            if (cur == top) {
4127                // Verify start of the chain.
4128                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4129                    Slog.wtf(TAG, "Bad chain @" + endIndex
4130                            + ": first task has next affiliate: " + prev);
4131                    sane = false;
4132                    break;
4133                }
4134            } else {
4135                // Verify middle of the chain's next points back to the one before.
4136                if (cur.mNextAffiliate != prev
4137                        || cur.mNextAffiliateTaskId != prev.taskId) {
4138                    Slog.wtf(TAG, "Bad chain @" + endIndex
4139                            + ": middle task " + cur + " @" + endIndex
4140                            + " has bad next affiliate "
4141                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4142                            + ", expected " + prev);
4143                    sane = false;
4144                    break;
4145                }
4146            }
4147            if (cur.mPrevAffiliateTaskId == -1) {
4148                // Chain ends here.
4149                if (cur.mPrevAffiliate != null) {
4150                    Slog.wtf(TAG, "Bad chain @" + endIndex
4151                            + ": last task " + cur + " has previous affiliate "
4152                            + cur.mPrevAffiliate);
4153                    sane = false;
4154                }
4155                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4156                break;
4157            } else {
4158                // Verify middle of the chain's prev points to a valid item.
4159                if (cur.mPrevAffiliate == null) {
4160                    Slog.wtf(TAG, "Bad chain @" + endIndex
4161                            + ": task " + cur + " has previous affiliate "
4162                            + cur.mPrevAffiliate + " but should be id "
4163                            + cur.mPrevAffiliate);
4164                    sane = false;
4165                    break;
4166                }
4167            }
4168            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4169                Slog.wtf(TAG, "Bad chain @" + endIndex
4170                        + ": task " + cur + " has affiliated id "
4171                        + cur.mAffiliatedTaskId + " but should be "
4172                        + task.mAffiliatedTaskId);
4173                sane = false;
4174                break;
4175            }
4176            prev = cur;
4177            endIndex++;
4178            if (endIndex >= N) {
4179                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4180                        + ": last task " + prev);
4181                sane = false;
4182                break;
4183            }
4184        }
4185        if (sane) {
4186            if (endIndex < taskIndex) {
4187                Slog.wtf(TAG, "Bad chain @" + endIndex
4188                        + ": did not extend to task " + task + " @" + taskIndex);
4189                sane = false;
4190            }
4191        }
4192        if (sane) {
4193            // All looks good, we can just move all of the affiliated tasks
4194            // to the top.
4195            for (int i=topIndex; i<=endIndex; i++) {
4196                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4197                        + " from " + i + " to " + (i-topIndex));
4198                TaskRecord cur = mRecentTasks.remove(i);
4199                mRecentTasks.add(i-topIndex, cur);
4200            }
4201            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4202                    + " to " + endIndex);
4203            return true;
4204        }
4205
4206        // Whoops, couldn't do it.
4207        return false;
4208    }
4209
4210    final void addRecentTaskLocked(TaskRecord task) {
4211        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4212                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4213
4214        int N = mRecentTasks.size();
4215        // Quick case: check if the top-most recent task is the same.
4216        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4217            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4218            return;
4219        }
4220        // Another quick case: check if this is part of a set of affiliated
4221        // tasks that are at the top.
4222        if (isAffiliated && N > 0 && task.inRecents
4223                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4224            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4225                    + " at top when adding " + task);
4226            return;
4227        }
4228        // Another quick case: never add voice sessions.
4229        if (task.voiceSession != null) {
4230            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4231            return;
4232        }
4233
4234        boolean needAffiliationFix = false;
4235
4236        // Slightly less quick case: the task is already in recents, so all we need
4237        // to do is move it.
4238        if (task.inRecents) {
4239            int taskIndex = mRecentTasks.indexOf(task);
4240            if (taskIndex >= 0) {
4241                if (!isAffiliated) {
4242                    // Simple case: this is not an affiliated task, so we just move it to the front.
4243                    mRecentTasks.remove(taskIndex);
4244                    mRecentTasks.add(0, task);
4245                    notifyTaskPersisterLocked(task, false);
4246                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4247                            + " from " + taskIndex);
4248                    return;
4249                } else {
4250                    // More complicated: need to keep all affiliated tasks together.
4251                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4252                        // All went well.
4253                        return;
4254                    }
4255
4256                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4257                    // everything and then go through our general path of adding a new task.
4258                    needAffiliationFix = true;
4259                }
4260            } else {
4261                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4262                needAffiliationFix = true;
4263            }
4264        }
4265
4266        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4267        trimRecentsForTask(task, true);
4268
4269        N = mRecentTasks.size();
4270        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4271            final TaskRecord tr = mRecentTasks.remove(N - 1);
4272            tr.removedFromRecents(mTaskPersister);
4273            N--;
4274        }
4275        task.inRecents = true;
4276        if (!isAffiliated || needAffiliationFix) {
4277            // If this is a simple non-affiliated task, or we had some failure trying to
4278            // handle it as part of an affilated task, then just place it at the top.
4279            mRecentTasks.add(0, task);
4280        } else if (isAffiliated) {
4281            // If this is a new affiliated task, then move all of the affiliated tasks
4282            // to the front and insert this new one.
4283            TaskRecord other = task.mNextAffiliate;
4284            if (other == null) {
4285                other = task.mPrevAffiliate;
4286            }
4287            if (other != null) {
4288                int otherIndex = mRecentTasks.indexOf(other);
4289                if (otherIndex >= 0) {
4290                    // Insert new task at appropriate location.
4291                    int taskIndex;
4292                    if (other == task.mNextAffiliate) {
4293                        // We found the index of our next affiliation, which is who is
4294                        // before us in the list, so add after that point.
4295                        taskIndex = otherIndex+1;
4296                    } else {
4297                        // We found the index of our previous affiliation, which is who is
4298                        // after us in the list, so add at their position.
4299                        taskIndex = otherIndex;
4300                    }
4301                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4302                            + taskIndex + ": " + task);
4303                    mRecentTasks.add(taskIndex, task);
4304
4305                    // Now move everything to the front.
4306                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4307                        // All went well.
4308                        return;
4309                    }
4310
4311                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4312                    // everything and then go through our general path of adding a new task.
4313                    needAffiliationFix = true;
4314                } else {
4315                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4316                            + other);
4317                    needAffiliationFix = true;
4318                }
4319            } else {
4320                if (DEBUG_RECENTS) Slog.d(TAG,
4321                        "addRecent: adding affiliated task without next/prev:" + task);
4322                needAffiliationFix = true;
4323            }
4324        }
4325        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4326
4327        if (needAffiliationFix) {
4328            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4329            cleanupRecentTasksLocked(task.userId);
4330        }
4331    }
4332
4333    /**
4334     * If needed, remove oldest existing entries in recents that are for the same kind
4335     * of task as the given one.
4336     */
4337    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4338        int N = mRecentTasks.size();
4339        final Intent intent = task.intent;
4340        final boolean document = intent != null && intent.isDocument();
4341
4342        int maxRecents = task.maxRecents - 1;
4343        for (int i=0; i<N; i++) {
4344            final TaskRecord tr = mRecentTasks.get(i);
4345            if (task != tr) {
4346                if (task.userId != tr.userId) {
4347                    continue;
4348                }
4349                if (i > MAX_RECENT_BITMAPS) {
4350                    tr.freeLastThumbnail();
4351                }
4352                final Intent trIntent = tr.intent;
4353                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4354                    (intent == null || !intent.filterEquals(trIntent))) {
4355                    continue;
4356                }
4357                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4358                if (document && trIsDocument) {
4359                    // These are the same document activity (not necessarily the same doc).
4360                    if (maxRecents > 0) {
4361                        --maxRecents;
4362                        continue;
4363                    }
4364                    // Hit the maximum number of documents for this task. Fall through
4365                    // and remove this document from recents.
4366                } else if (document || trIsDocument) {
4367                    // Only one of these is a document. Not the droid we're looking for.
4368                    continue;
4369                }
4370            }
4371
4372            if (!doTrim) {
4373                // If the caller is not actually asking for a trim, just tell them we reached
4374                // a point where the trim would happen.
4375                return i;
4376            }
4377
4378            // Either task and tr are the same or, their affinities match or their intents match
4379            // and neither of them is a document, or they are documents using the same activity
4380            // and their maxRecents has been reached.
4381            tr.disposeThumbnail();
4382            mRecentTasks.remove(i);
4383            if (task != tr) {
4384                tr.removedFromRecents(mTaskPersister);
4385            }
4386            i--;
4387            N--;
4388            if (task.intent == null) {
4389                // If the new recent task we are adding is not fully
4390                // specified, then replace it with the existing recent task.
4391                task = tr;
4392            }
4393            notifyTaskPersisterLocked(tr, false);
4394        }
4395
4396        return -1;
4397    }
4398
4399    @Override
4400    public void reportActivityFullyDrawn(IBinder token) {
4401        synchronized (this) {
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r == null) {
4404                return;
4405            }
4406            r.reportFullyDrawnLocked();
4407        }
4408    }
4409
4410    @Override
4411    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4412        synchronized (this) {
4413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4414            if (r == null) {
4415                return;
4416            }
4417            final long origId = Binder.clearCallingIdentity();
4418            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4419            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4420                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4421            if (config != null) {
4422                r.frozenBeforeDestroy = true;
4423                if (!updateConfigurationLocked(config, r, false, false)) {
4424                    mStackSupervisor.resumeTopActivitiesLocked();
4425                }
4426            }
4427            Binder.restoreCallingIdentity(origId);
4428        }
4429    }
4430
4431    @Override
4432    public int getRequestedOrientation(IBinder token) {
4433        synchronized (this) {
4434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4435            if (r == null) {
4436                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4437            }
4438            return mWindowManager.getAppOrientation(r.appToken);
4439        }
4440    }
4441
4442    /**
4443     * This is the internal entry point for handling Activity.finish().
4444     *
4445     * @param token The Binder token referencing the Activity we want to finish.
4446     * @param resultCode Result code, if any, from this Activity.
4447     * @param resultData Result data (Intent), if any, from this Activity.
4448     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4449     *            the root Activity in the task.
4450     *
4451     * @return Returns true if the activity successfully finished, or false if it is still running.
4452     */
4453    @Override
4454    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4455            boolean finishTask) {
4456        // Refuse possible leaked file descriptors
4457        if (resultData != null && resultData.hasFileDescriptors() == true) {
4458            throw new IllegalArgumentException("File descriptors passed in Intent");
4459        }
4460
4461        synchronized(this) {
4462            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4463            if (r == null) {
4464                return true;
4465            }
4466            // Keep track of the root activity of the task before we finish it
4467            TaskRecord tr = r.task;
4468            ActivityRecord rootR = tr.getRootActivity();
4469            // Do not allow task to finish in Lock Task mode.
4470            if (tr == mStackSupervisor.mLockTaskModeTask) {
4471                if (rootR == r) {
4472                    mStackSupervisor.showLockTaskToast();
4473                    return false;
4474                }
4475            }
4476            if (mController != null) {
4477                // Find the first activity that is not finishing.
4478                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4479                if (next != null) {
4480                    // ask watcher if this is allowed
4481                    boolean resumeOK = true;
4482                    try {
4483                        resumeOK = mController.activityResuming(next.packageName);
4484                    } catch (RemoteException e) {
4485                        mController = null;
4486                        Watchdog.getInstance().setActivityController(null);
4487                    }
4488
4489                    if (!resumeOK) {
4490                        return false;
4491                    }
4492                }
4493            }
4494            final long origId = Binder.clearCallingIdentity();
4495            try {
4496                boolean res;
4497                if (finishTask && r == rootR) {
4498                    // If requested, remove the task that is associated to this activity only if it
4499                    // was the root activity in the task.  The result code and data is ignored because
4500                    // we don't support returning them across task boundaries.
4501                    res = removeTaskByIdLocked(tr.taskId, 0);
4502                } else {
4503                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4504                            resultData, "app-request", true);
4505                }
4506                return res;
4507            } finally {
4508                Binder.restoreCallingIdentity(origId);
4509            }
4510        }
4511    }
4512
4513    @Override
4514    public final void finishHeavyWeightApp() {
4515        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4516                != PackageManager.PERMISSION_GRANTED) {
4517            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4518                    + Binder.getCallingPid()
4519                    + ", uid=" + Binder.getCallingUid()
4520                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4521            Slog.w(TAG, msg);
4522            throw new SecurityException(msg);
4523        }
4524
4525        synchronized(this) {
4526            if (mHeavyWeightProcess == null) {
4527                return;
4528            }
4529
4530            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4531                    mHeavyWeightProcess.activities);
4532            for (int i=0; i<activities.size(); i++) {
4533                ActivityRecord r = activities.get(i);
4534                if (!r.finishing) {
4535                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4536                            null, "finish-heavy", true);
4537                }
4538            }
4539
4540            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4541                    mHeavyWeightProcess.userId, 0));
4542            mHeavyWeightProcess = null;
4543        }
4544    }
4545
4546    @Override
4547    public void crashApplication(int uid, int initialPid, String packageName,
4548            String message) {
4549        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4550                != PackageManager.PERMISSION_GRANTED) {
4551            String msg = "Permission Denial: crashApplication() from pid="
4552                    + Binder.getCallingPid()
4553                    + ", uid=" + Binder.getCallingUid()
4554                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4555            Slog.w(TAG, msg);
4556            throw new SecurityException(msg);
4557        }
4558
4559        synchronized(this) {
4560            ProcessRecord proc = null;
4561
4562            // Figure out which process to kill.  We don't trust that initialPid
4563            // still has any relation to current pids, so must scan through the
4564            // list.
4565            synchronized (mPidsSelfLocked) {
4566                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4567                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4568                    if (p.uid != uid) {
4569                        continue;
4570                    }
4571                    if (p.pid == initialPid) {
4572                        proc = p;
4573                        break;
4574                    }
4575                    if (p.pkgList.containsKey(packageName)) {
4576                        proc = p;
4577                    }
4578                }
4579            }
4580
4581            if (proc == null) {
4582                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4583                        + " initialPid=" + initialPid
4584                        + " packageName=" + packageName);
4585                return;
4586            }
4587
4588            if (proc.thread != null) {
4589                if (proc.pid == Process.myPid()) {
4590                    Log.w(TAG, "crashApplication: trying to crash self!");
4591                    return;
4592                }
4593                long ident = Binder.clearCallingIdentity();
4594                try {
4595                    proc.thread.scheduleCrash(message);
4596                } catch (RemoteException e) {
4597                }
4598                Binder.restoreCallingIdentity(ident);
4599            }
4600        }
4601    }
4602
4603    @Override
4604    public final void finishSubActivity(IBinder token, String resultWho,
4605            int requestCode) {
4606        synchronized(this) {
4607            final long origId = Binder.clearCallingIdentity();
4608            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4609            if (r != null) {
4610                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4611            }
4612            Binder.restoreCallingIdentity(origId);
4613        }
4614    }
4615
4616    @Override
4617    public boolean finishActivityAffinity(IBinder token) {
4618        synchronized(this) {
4619            final long origId = Binder.clearCallingIdentity();
4620            try {
4621                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4622
4623                ActivityRecord rootR = r.task.getRootActivity();
4624                // Do not allow task to finish in Lock Task mode.
4625                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4626                    if (rootR == r) {
4627                        mStackSupervisor.showLockTaskToast();
4628                        return false;
4629                    }
4630                }
4631                boolean res = false;
4632                if (r != null) {
4633                    res = r.task.stack.finishActivityAffinityLocked(r);
4634                }
4635                return res;
4636            } finally {
4637                Binder.restoreCallingIdentity(origId);
4638            }
4639        }
4640    }
4641
4642    @Override
4643    public void finishVoiceTask(IVoiceInteractionSession session) {
4644        synchronized(this) {
4645            final long origId = Binder.clearCallingIdentity();
4646            try {
4647                mStackSupervisor.finishVoiceTask(session);
4648            } finally {
4649                Binder.restoreCallingIdentity(origId);
4650            }
4651        }
4652
4653    }
4654
4655    @Override
4656    public boolean releaseActivityInstance(IBinder token) {
4657        synchronized(this) {
4658            final long origId = Binder.clearCallingIdentity();
4659            try {
4660                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4661                if (r.task == null || r.task.stack == null) {
4662                    return false;
4663                }
4664                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4665            } finally {
4666                Binder.restoreCallingIdentity(origId);
4667            }
4668        }
4669    }
4670
4671    @Override
4672    public void releaseSomeActivities(IApplicationThread appInt) {
4673        synchronized(this) {
4674            final long origId = Binder.clearCallingIdentity();
4675            try {
4676                ProcessRecord app = getRecordForAppLocked(appInt);
4677                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4678            } finally {
4679                Binder.restoreCallingIdentity(origId);
4680            }
4681        }
4682    }
4683
4684    @Override
4685    public boolean willActivityBeVisible(IBinder token) {
4686        synchronized(this) {
4687            ActivityStack stack = ActivityRecord.getStackLocked(token);
4688            if (stack != null) {
4689                return stack.willActivityBeVisibleLocked(token);
4690            }
4691            return false;
4692        }
4693    }
4694
4695    @Override
4696    public void overridePendingTransition(IBinder token, String packageName,
4697            int enterAnim, int exitAnim) {
4698        synchronized(this) {
4699            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4700            if (self == null) {
4701                return;
4702            }
4703
4704            final long origId = Binder.clearCallingIdentity();
4705
4706            if (self.state == ActivityState.RESUMED
4707                    || self.state == ActivityState.PAUSING) {
4708                mWindowManager.overridePendingAppTransition(packageName,
4709                        enterAnim, exitAnim, null);
4710            }
4711
4712            Binder.restoreCallingIdentity(origId);
4713        }
4714    }
4715
4716    /**
4717     * Main function for removing an existing process from the activity manager
4718     * as a result of that process going away.  Clears out all connections
4719     * to the process.
4720     */
4721    private final void handleAppDiedLocked(ProcessRecord app,
4722            boolean restarting, boolean allowRestart) {
4723        int pid = app.pid;
4724        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4725        if (!kept && !restarting) {
4726            removeLruProcessLocked(app);
4727            if (pid > 0) {
4728                ProcessList.remove(pid);
4729            }
4730        }
4731
4732        if (mProfileProc == app) {
4733            clearProfilerLocked();
4734        }
4735
4736        // Remove this application's activities from active lists.
4737        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4738
4739        app.activities.clear();
4740
4741        if (app.instrumentationClass != null) {
4742            Slog.w(TAG, "Crash of app " + app.processName
4743                  + " running instrumentation " + app.instrumentationClass);
4744            Bundle info = new Bundle();
4745            info.putString("shortMsg", "Process crashed.");
4746            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4747        }
4748
4749        if (!restarting) {
4750            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4751                // If there was nothing to resume, and we are not already
4752                // restarting this process, but there is a visible activity that
4753                // is hosted by the process...  then make sure all visible
4754                // activities are running, taking care of restarting this
4755                // process.
4756                if (hasVisibleActivities) {
4757                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4758                }
4759            }
4760        }
4761    }
4762
4763    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4764        IBinder threadBinder = thread.asBinder();
4765        // Find the application record.
4766        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4767            ProcessRecord rec = mLruProcesses.get(i);
4768            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4769                return i;
4770            }
4771        }
4772        return -1;
4773    }
4774
4775    final ProcessRecord getRecordForAppLocked(
4776            IApplicationThread thread) {
4777        if (thread == null) {
4778            return null;
4779        }
4780
4781        int appIndex = getLRURecordIndexForAppLocked(thread);
4782        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4783    }
4784
4785    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4786        // If there are no longer any background processes running,
4787        // and the app that died was not running instrumentation,
4788        // then tell everyone we are now low on memory.
4789        boolean haveBg = false;
4790        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4791            ProcessRecord rec = mLruProcesses.get(i);
4792            if (rec.thread != null
4793                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4794                haveBg = true;
4795                break;
4796            }
4797        }
4798
4799        if (!haveBg) {
4800            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4801            if (doReport) {
4802                long now = SystemClock.uptimeMillis();
4803                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4804                    doReport = false;
4805                } else {
4806                    mLastMemUsageReportTime = now;
4807                }
4808            }
4809            final ArrayList<ProcessMemInfo> memInfos
4810                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4811            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4812            long now = SystemClock.uptimeMillis();
4813            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4814                ProcessRecord rec = mLruProcesses.get(i);
4815                if (rec == dyingProc || rec.thread == null) {
4816                    continue;
4817                }
4818                if (doReport) {
4819                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4820                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4821                }
4822                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4823                    // The low memory report is overriding any current
4824                    // state for a GC request.  Make sure to do
4825                    // heavy/important/visible/foreground processes first.
4826                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4827                        rec.lastRequestedGc = 0;
4828                    } else {
4829                        rec.lastRequestedGc = rec.lastLowMemory;
4830                    }
4831                    rec.reportLowMemory = true;
4832                    rec.lastLowMemory = now;
4833                    mProcessesToGc.remove(rec);
4834                    addProcessToGcListLocked(rec);
4835                }
4836            }
4837            if (doReport) {
4838                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4839                mHandler.sendMessage(msg);
4840            }
4841            scheduleAppGcsLocked();
4842        }
4843    }
4844
4845    final void appDiedLocked(ProcessRecord app) {
4846       appDiedLocked(app, app.pid, app.thread);
4847    }
4848
4849    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4850        // First check if this ProcessRecord is actually active for the pid.
4851        synchronized (mPidsSelfLocked) {
4852            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4853            if (curProc != app) {
4854                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4855                return;
4856            }
4857        }
4858
4859        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4860        synchronized (stats) {
4861            stats.noteProcessDiedLocked(app.info.uid, pid);
4862        }
4863
4864        Process.killProcessQuiet(pid);
4865        Process.killProcessGroup(app.info.uid, pid);
4866        app.killed = true;
4867
4868        // Clean up already done if the process has been re-started.
4869        if (app.pid == pid && app.thread != null &&
4870                app.thread.asBinder() == thread.asBinder()) {
4871            boolean doLowMem = app.instrumentationClass == null;
4872            boolean doOomAdj = doLowMem;
4873            if (!app.killedByAm) {
4874                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4875                        + ") has died");
4876                mAllowLowerMemLevel = true;
4877            } else {
4878                // Note that we always want to do oom adj to update our state with the
4879                // new number of procs.
4880                mAllowLowerMemLevel = false;
4881                doLowMem = false;
4882            }
4883            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4884            if (DEBUG_CLEANUP) Slog.v(
4885                TAG, "Dying app: " + app + ", pid: " + pid
4886                + ", thread: " + thread.asBinder());
4887            handleAppDiedLocked(app, false, true);
4888
4889            if (doOomAdj) {
4890                updateOomAdjLocked();
4891            }
4892            if (doLowMem) {
4893                doLowMemReportIfNeededLocked(app);
4894            }
4895        } else if (app.pid != pid) {
4896            // A new process has already been started.
4897            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4898                    + ") has died and restarted (pid " + app.pid + ").");
4899            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4900        } else if (DEBUG_PROCESSES) {
4901            Slog.d(TAG, "Received spurious death notification for thread "
4902                    + thread.asBinder());
4903        }
4904    }
4905
4906    /**
4907     * If a stack trace dump file is configured, dump process stack traces.
4908     * @param clearTraces causes the dump file to be erased prior to the new
4909     *    traces being written, if true; when false, the new traces will be
4910     *    appended to any existing file content.
4911     * @param firstPids of dalvik VM processes to dump stack traces for first
4912     * @param lastPids of dalvik VM processes to dump stack traces for last
4913     * @param nativeProcs optional list of native process names to dump stack crawls
4914     * @return file containing stack traces, or null if no dump file is configured
4915     */
4916    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4917            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4918        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4919        if (tracesPath == null || tracesPath.length() == 0) {
4920            return null;
4921        }
4922
4923        File tracesFile = new File(tracesPath);
4924        try {
4925            File tracesDir = tracesFile.getParentFile();
4926            if (!tracesDir.exists()) {
4927                tracesDir.mkdirs();
4928                if (!SELinux.restorecon(tracesDir)) {
4929                    return null;
4930                }
4931            }
4932            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4933
4934            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4935            tracesFile.createNewFile();
4936            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4937        } catch (IOException e) {
4938            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4939            return null;
4940        }
4941
4942        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4943        return tracesFile;
4944    }
4945
4946    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4947            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4948        // Use a FileObserver to detect when traces finish writing.
4949        // The order of traces is considered important to maintain for legibility.
4950        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4951            @Override
4952            public synchronized void onEvent(int event, String path) { notify(); }
4953        };
4954
4955        try {
4956            observer.startWatching();
4957
4958            // First collect all of the stacks of the most important pids.
4959            if (firstPids != null) {
4960                try {
4961                    int num = firstPids.size();
4962                    for (int i = 0; i < num; i++) {
4963                        synchronized (observer) {
4964                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4965                            observer.wait(200);  // Wait for write-close, give up after 200msec
4966                        }
4967                    }
4968                } catch (InterruptedException e) {
4969                    Slog.wtf(TAG, e);
4970                }
4971            }
4972
4973            // Next collect the stacks of the native pids
4974            if (nativeProcs != null) {
4975                int[] pids = Process.getPidsForCommands(nativeProcs);
4976                if (pids != null) {
4977                    for (int pid : pids) {
4978                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4979                    }
4980                }
4981            }
4982
4983            // Lastly, measure CPU usage.
4984            if (processCpuTracker != null) {
4985                processCpuTracker.init();
4986                System.gc();
4987                processCpuTracker.update();
4988                try {
4989                    synchronized (processCpuTracker) {
4990                        processCpuTracker.wait(500); // measure over 1/2 second.
4991                    }
4992                } catch (InterruptedException e) {
4993                }
4994                processCpuTracker.update();
4995
4996                // We'll take the stack crawls of just the top apps using CPU.
4997                final int N = processCpuTracker.countWorkingStats();
4998                int numProcs = 0;
4999                for (int i=0; i<N && numProcs<5; i++) {
5000                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5001                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5002                        numProcs++;
5003                        try {
5004                            synchronized (observer) {
5005                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5006                                observer.wait(200);  // Wait for write-close, give up after 200msec
5007                            }
5008                        } catch (InterruptedException e) {
5009                            Slog.wtf(TAG, e);
5010                        }
5011
5012                    }
5013                }
5014            }
5015        } finally {
5016            observer.stopWatching();
5017        }
5018    }
5019
5020    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5021        if (true || IS_USER_BUILD) {
5022            return;
5023        }
5024        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5025        if (tracesPath == null || tracesPath.length() == 0) {
5026            return;
5027        }
5028
5029        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5030        StrictMode.allowThreadDiskWrites();
5031        try {
5032            final File tracesFile = new File(tracesPath);
5033            final File tracesDir = tracesFile.getParentFile();
5034            final File tracesTmp = new File(tracesDir, "__tmp__");
5035            try {
5036                if (!tracesDir.exists()) {
5037                    tracesDir.mkdirs();
5038                    if (!SELinux.restorecon(tracesDir.getPath())) {
5039                        return;
5040                    }
5041                }
5042                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5043
5044                if (tracesFile.exists()) {
5045                    tracesTmp.delete();
5046                    tracesFile.renameTo(tracesTmp);
5047                }
5048                StringBuilder sb = new StringBuilder();
5049                Time tobj = new Time();
5050                tobj.set(System.currentTimeMillis());
5051                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5052                sb.append(": ");
5053                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5054                sb.append(" since ");
5055                sb.append(msg);
5056                FileOutputStream fos = new FileOutputStream(tracesFile);
5057                fos.write(sb.toString().getBytes());
5058                if (app == null) {
5059                    fos.write("\n*** No application process!".getBytes());
5060                }
5061                fos.close();
5062                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5063            } catch (IOException e) {
5064                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5065                return;
5066            }
5067
5068            if (app != null) {
5069                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5070                firstPids.add(app.pid);
5071                dumpStackTraces(tracesPath, firstPids, null, null, null);
5072            }
5073
5074            File lastTracesFile = null;
5075            File curTracesFile = null;
5076            for (int i=9; i>=0; i--) {
5077                String name = String.format(Locale.US, "slow%02d.txt", i);
5078                curTracesFile = new File(tracesDir, name);
5079                if (curTracesFile.exists()) {
5080                    if (lastTracesFile != null) {
5081                        curTracesFile.renameTo(lastTracesFile);
5082                    } else {
5083                        curTracesFile.delete();
5084                    }
5085                }
5086                lastTracesFile = curTracesFile;
5087            }
5088            tracesFile.renameTo(curTracesFile);
5089            if (tracesTmp.exists()) {
5090                tracesTmp.renameTo(tracesFile);
5091            }
5092        } finally {
5093            StrictMode.setThreadPolicy(oldPolicy);
5094        }
5095    }
5096
5097    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5098            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5099        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5100        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5101
5102        if (mController != null) {
5103            try {
5104                // 0 == continue, -1 = kill process immediately
5105                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5106                if (res < 0 && app.pid != MY_PID) {
5107                    app.kill("anr", true);
5108                }
5109            } catch (RemoteException e) {
5110                mController = null;
5111                Watchdog.getInstance().setActivityController(null);
5112            }
5113        }
5114
5115        long anrTime = SystemClock.uptimeMillis();
5116        if (MONITOR_CPU_USAGE) {
5117            updateCpuStatsNow();
5118        }
5119
5120        synchronized (this) {
5121            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5122            if (mShuttingDown) {
5123                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5124                return;
5125            } else if (app.notResponding) {
5126                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5127                return;
5128            } else if (app.crashing) {
5129                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5130                return;
5131            }
5132
5133            // In case we come through here for the same app before completing
5134            // this one, mark as anring now so we will bail out.
5135            app.notResponding = true;
5136
5137            // Log the ANR to the event log.
5138            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5139                    app.processName, app.info.flags, annotation);
5140
5141            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5142            firstPids.add(app.pid);
5143
5144            int parentPid = app.pid;
5145            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5146            if (parentPid != app.pid) firstPids.add(parentPid);
5147
5148            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5149
5150            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5151                ProcessRecord r = mLruProcesses.get(i);
5152                if (r != null && r.thread != null) {
5153                    int pid = r.pid;
5154                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5155                        if (r.persistent) {
5156                            firstPids.add(pid);
5157                        } else {
5158                            lastPids.put(pid, Boolean.TRUE);
5159                        }
5160                    }
5161                }
5162            }
5163        }
5164
5165        // Log the ANR to the main log.
5166        StringBuilder info = new StringBuilder();
5167        info.setLength(0);
5168        info.append("ANR in ").append(app.processName);
5169        if (activity != null && activity.shortComponentName != null) {
5170            info.append(" (").append(activity.shortComponentName).append(")");
5171        }
5172        info.append("\n");
5173        info.append("PID: ").append(app.pid).append("\n");
5174        if (annotation != null) {
5175            info.append("Reason: ").append(annotation).append("\n");
5176        }
5177        if (parent != null && parent != activity) {
5178            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5179        }
5180
5181        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5182
5183        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5184                NATIVE_STACKS_OF_INTEREST);
5185
5186        String cpuInfo = null;
5187        if (MONITOR_CPU_USAGE) {
5188            updateCpuStatsNow();
5189            synchronized (mProcessCpuTracker) {
5190                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5191            }
5192            info.append(processCpuTracker.printCurrentLoad());
5193            info.append(cpuInfo);
5194        }
5195
5196        info.append(processCpuTracker.printCurrentState(anrTime));
5197
5198        Slog.e(TAG, info.toString());
5199        if (tracesFile == null) {
5200            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5201            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5202        }
5203
5204        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5205                cpuInfo, tracesFile, null);
5206
5207        if (mController != null) {
5208            try {
5209                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5210                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5211                if (res != 0) {
5212                    if (res < 0 && app.pid != MY_PID) {
5213                        app.kill("anr", true);
5214                    } else {
5215                        synchronized (this) {
5216                            mServices.scheduleServiceTimeoutLocked(app);
5217                        }
5218                    }
5219                    return;
5220                }
5221            } catch (RemoteException e) {
5222                mController = null;
5223                Watchdog.getInstance().setActivityController(null);
5224            }
5225        }
5226
5227        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5228        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5229                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5230
5231        synchronized (this) {
5232            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5233                app.kill("bg anr", true);
5234                return;
5235            }
5236
5237            // Set the app's notResponding state, and look up the errorReportReceiver
5238            makeAppNotRespondingLocked(app,
5239                    activity != null ? activity.shortComponentName : null,
5240                    annotation != null ? "ANR " + annotation : "ANR",
5241                    info.toString());
5242
5243            // Bring up the infamous App Not Responding dialog
5244            Message msg = Message.obtain();
5245            HashMap<String, Object> map = new HashMap<String, Object>();
5246            msg.what = SHOW_NOT_RESPONDING_MSG;
5247            msg.obj = map;
5248            msg.arg1 = aboveSystem ? 1 : 0;
5249            map.put("app", app);
5250            if (activity != null) {
5251                map.put("activity", activity);
5252            }
5253
5254            mHandler.sendMessage(msg);
5255        }
5256    }
5257
5258    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5259        if (!mLaunchWarningShown) {
5260            mLaunchWarningShown = true;
5261            mHandler.post(new Runnable() {
5262                @Override
5263                public void run() {
5264                    synchronized (ActivityManagerService.this) {
5265                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5266                        d.show();
5267                        mHandler.postDelayed(new Runnable() {
5268                            @Override
5269                            public void run() {
5270                                synchronized (ActivityManagerService.this) {
5271                                    d.dismiss();
5272                                    mLaunchWarningShown = false;
5273                                }
5274                            }
5275                        }, 4000);
5276                    }
5277                }
5278            });
5279        }
5280    }
5281
5282    @Override
5283    public boolean clearApplicationUserData(final String packageName,
5284            final IPackageDataObserver observer, int userId) {
5285        enforceNotIsolatedCaller("clearApplicationUserData");
5286        int uid = Binder.getCallingUid();
5287        int pid = Binder.getCallingPid();
5288        userId = handleIncomingUser(pid, uid,
5289                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5290        long callingId = Binder.clearCallingIdentity();
5291        try {
5292            IPackageManager pm = AppGlobals.getPackageManager();
5293            int pkgUid = -1;
5294            synchronized(this) {
5295                try {
5296                    pkgUid = pm.getPackageUid(packageName, userId);
5297                } catch (RemoteException e) {
5298                }
5299                if (pkgUid == -1) {
5300                    Slog.w(TAG, "Invalid packageName: " + packageName);
5301                    if (observer != null) {
5302                        try {
5303                            observer.onRemoveCompleted(packageName, false);
5304                        } catch (RemoteException e) {
5305                            Slog.i(TAG, "Observer no longer exists.");
5306                        }
5307                    }
5308                    return false;
5309                }
5310                if (uid == pkgUid || checkComponentPermission(
5311                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5312                        pid, uid, -1, true)
5313                        == PackageManager.PERMISSION_GRANTED) {
5314                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5315                } else {
5316                    throw new SecurityException("PID " + pid + " does not have permission "
5317                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5318                                    + " of package " + packageName);
5319                }
5320
5321                // Remove all tasks match the cleared application package and user
5322                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5323                    final TaskRecord tr = mRecentTasks.get(i);
5324                    final String taskPackageName =
5325                            tr.getBaseIntent().getComponent().getPackageName();
5326                    if (tr.userId != userId) continue;
5327                    if (!taskPackageName.equals(packageName)) continue;
5328                    removeTaskByIdLocked(tr.taskId, 0);
5329                }
5330            }
5331
5332            try {
5333                // Clear application user data
5334                pm.clearApplicationUserData(packageName, observer, userId);
5335
5336                synchronized(this) {
5337                    // Remove all permissions granted from/to this package
5338                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5339                }
5340
5341                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5342                        Uri.fromParts("package", packageName, null));
5343                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5344                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5345                        null, null, 0, null, null, null, false, false, userId);
5346            } catch (RemoteException e) {
5347            }
5348        } finally {
5349            Binder.restoreCallingIdentity(callingId);
5350        }
5351        return true;
5352    }
5353
5354    @Override
5355    public void killBackgroundProcesses(final String packageName, int userId) {
5356        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5357                != PackageManager.PERMISSION_GRANTED &&
5358                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5359                        != PackageManager.PERMISSION_GRANTED) {
5360            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5361                    + Binder.getCallingPid()
5362                    + ", uid=" + Binder.getCallingUid()
5363                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5364            Slog.w(TAG, msg);
5365            throw new SecurityException(msg);
5366        }
5367
5368        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5369                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5370        long callingId = Binder.clearCallingIdentity();
5371        try {
5372            IPackageManager pm = AppGlobals.getPackageManager();
5373            synchronized(this) {
5374                int appId = -1;
5375                try {
5376                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5377                } catch (RemoteException e) {
5378                }
5379                if (appId == -1) {
5380                    Slog.w(TAG, "Invalid packageName: " + packageName);
5381                    return;
5382                }
5383                killPackageProcessesLocked(packageName, appId, userId,
5384                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5385            }
5386        } finally {
5387            Binder.restoreCallingIdentity(callingId);
5388        }
5389    }
5390
5391    @Override
5392    public void killAllBackgroundProcesses() {
5393        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5394                != PackageManager.PERMISSION_GRANTED) {
5395            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5396                    + Binder.getCallingPid()
5397                    + ", uid=" + Binder.getCallingUid()
5398                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5399            Slog.w(TAG, msg);
5400            throw new SecurityException(msg);
5401        }
5402
5403        long callingId = Binder.clearCallingIdentity();
5404        try {
5405            synchronized(this) {
5406                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5407                final int NP = mProcessNames.getMap().size();
5408                for (int ip=0; ip<NP; ip++) {
5409                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5410                    final int NA = apps.size();
5411                    for (int ia=0; ia<NA; ia++) {
5412                        ProcessRecord app = apps.valueAt(ia);
5413                        if (app.persistent) {
5414                            // we don't kill persistent processes
5415                            continue;
5416                        }
5417                        if (app.removed) {
5418                            procs.add(app);
5419                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5420                            app.removed = true;
5421                            procs.add(app);
5422                        }
5423                    }
5424                }
5425
5426                int N = procs.size();
5427                for (int i=0; i<N; i++) {
5428                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5429                }
5430                mAllowLowerMemLevel = true;
5431                updateOomAdjLocked();
5432                doLowMemReportIfNeededLocked(null);
5433            }
5434        } finally {
5435            Binder.restoreCallingIdentity(callingId);
5436        }
5437    }
5438
5439    @Override
5440    public void forceStopPackage(final String packageName, int userId) {
5441        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5442                != PackageManager.PERMISSION_GRANTED) {
5443            String msg = "Permission Denial: forceStopPackage() from pid="
5444                    + Binder.getCallingPid()
5445                    + ", uid=" + Binder.getCallingUid()
5446                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5447            Slog.w(TAG, msg);
5448            throw new SecurityException(msg);
5449        }
5450        final int callingPid = Binder.getCallingPid();
5451        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5452                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5453        long callingId = Binder.clearCallingIdentity();
5454        try {
5455            IPackageManager pm = AppGlobals.getPackageManager();
5456            synchronized(this) {
5457                int[] users = userId == UserHandle.USER_ALL
5458                        ? getUsersLocked() : new int[] { userId };
5459                for (int user : users) {
5460                    int pkgUid = -1;
5461                    try {
5462                        pkgUid = pm.getPackageUid(packageName, user);
5463                    } catch (RemoteException e) {
5464                    }
5465                    if (pkgUid == -1) {
5466                        Slog.w(TAG, "Invalid packageName: " + packageName);
5467                        continue;
5468                    }
5469                    try {
5470                        pm.setPackageStoppedState(packageName, true, user);
5471                    } catch (RemoteException e) {
5472                    } catch (IllegalArgumentException e) {
5473                        Slog.w(TAG, "Failed trying to unstop package "
5474                                + packageName + ": " + e);
5475                    }
5476                    if (isUserRunningLocked(user, false)) {
5477                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5478                    }
5479                }
5480            }
5481        } finally {
5482            Binder.restoreCallingIdentity(callingId);
5483        }
5484    }
5485
5486    @Override
5487    public void addPackageDependency(String packageName) {
5488        synchronized (this) {
5489            int callingPid = Binder.getCallingPid();
5490            if (callingPid == Process.myPid()) {
5491                //  Yeah, um, no.
5492                Slog.w(TAG, "Can't addPackageDependency on system process");
5493                return;
5494            }
5495            ProcessRecord proc;
5496            synchronized (mPidsSelfLocked) {
5497                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5498            }
5499            if (proc != null) {
5500                if (proc.pkgDeps == null) {
5501                    proc.pkgDeps = new ArraySet<String>(1);
5502                }
5503                proc.pkgDeps.add(packageName);
5504            }
5505        }
5506    }
5507
5508    /*
5509     * The pkg name and app id have to be specified.
5510     */
5511    @Override
5512    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5513        if (pkg == null) {
5514            return;
5515        }
5516        // Make sure the uid is valid.
5517        if (appid < 0) {
5518            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5519            return;
5520        }
5521        int callerUid = Binder.getCallingUid();
5522        // Only the system server can kill an application
5523        if (callerUid == Process.SYSTEM_UID) {
5524            // Post an aysnc message to kill the application
5525            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5526            msg.arg1 = appid;
5527            msg.arg2 = 0;
5528            Bundle bundle = new Bundle();
5529            bundle.putString("pkg", pkg);
5530            bundle.putString("reason", reason);
5531            msg.obj = bundle;
5532            mHandler.sendMessage(msg);
5533        } else {
5534            throw new SecurityException(callerUid + " cannot kill pkg: " +
5535                    pkg);
5536        }
5537    }
5538
5539    @Override
5540    public void closeSystemDialogs(String reason) {
5541        enforceNotIsolatedCaller("closeSystemDialogs");
5542
5543        final int pid = Binder.getCallingPid();
5544        final int uid = Binder.getCallingUid();
5545        final long origId = Binder.clearCallingIdentity();
5546        try {
5547            synchronized (this) {
5548                // Only allow this from foreground processes, so that background
5549                // applications can't abuse it to prevent system UI from being shown.
5550                if (uid >= Process.FIRST_APPLICATION_UID) {
5551                    ProcessRecord proc;
5552                    synchronized (mPidsSelfLocked) {
5553                        proc = mPidsSelfLocked.get(pid);
5554                    }
5555                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5556                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5557                                + " from background process " + proc);
5558                        return;
5559                    }
5560                }
5561                closeSystemDialogsLocked(reason);
5562            }
5563        } finally {
5564            Binder.restoreCallingIdentity(origId);
5565        }
5566    }
5567
5568    void closeSystemDialogsLocked(String reason) {
5569        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5570        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5571                | Intent.FLAG_RECEIVER_FOREGROUND);
5572        if (reason != null) {
5573            intent.putExtra("reason", reason);
5574        }
5575        mWindowManager.closeSystemDialogs(reason);
5576
5577        mStackSupervisor.closeSystemDialogsLocked();
5578
5579        broadcastIntentLocked(null, null, intent, null,
5580                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5581                Process.SYSTEM_UID, UserHandle.USER_ALL);
5582    }
5583
5584    @Override
5585    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5586        enforceNotIsolatedCaller("getProcessMemoryInfo");
5587        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5588        for (int i=pids.length-1; i>=0; i--) {
5589            ProcessRecord proc;
5590            int oomAdj;
5591            synchronized (this) {
5592                synchronized (mPidsSelfLocked) {
5593                    proc = mPidsSelfLocked.get(pids[i]);
5594                    oomAdj = proc != null ? proc.setAdj : 0;
5595                }
5596            }
5597            infos[i] = new Debug.MemoryInfo();
5598            Debug.getMemoryInfo(pids[i], infos[i]);
5599            if (proc != null) {
5600                synchronized (this) {
5601                    if (proc.thread != null && proc.setAdj == oomAdj) {
5602                        // Record this for posterity if the process has been stable.
5603                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5604                                infos[i].getTotalUss(), false, proc.pkgList);
5605                    }
5606                }
5607            }
5608        }
5609        return infos;
5610    }
5611
5612    @Override
5613    public long[] getProcessPss(int[] pids) {
5614        enforceNotIsolatedCaller("getProcessPss");
5615        long[] pss = new long[pids.length];
5616        for (int i=pids.length-1; i>=0; i--) {
5617            ProcessRecord proc;
5618            int oomAdj;
5619            synchronized (this) {
5620                synchronized (mPidsSelfLocked) {
5621                    proc = mPidsSelfLocked.get(pids[i]);
5622                    oomAdj = proc != null ? proc.setAdj : 0;
5623                }
5624            }
5625            long[] tmpUss = new long[1];
5626            pss[i] = Debug.getPss(pids[i], tmpUss);
5627            if (proc != null) {
5628                synchronized (this) {
5629                    if (proc.thread != null && proc.setAdj == oomAdj) {
5630                        // Record this for posterity if the process has been stable.
5631                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5632                    }
5633                }
5634            }
5635        }
5636        return pss;
5637    }
5638
5639    @Override
5640    public void killApplicationProcess(String processName, int uid) {
5641        if (processName == null) {
5642            return;
5643        }
5644
5645        int callerUid = Binder.getCallingUid();
5646        // Only the system server can kill an application
5647        if (callerUid == Process.SYSTEM_UID) {
5648            synchronized (this) {
5649                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5650                if (app != null && app.thread != null) {
5651                    try {
5652                        app.thread.scheduleSuicide();
5653                    } catch (RemoteException e) {
5654                        // If the other end already died, then our work here is done.
5655                    }
5656                } else {
5657                    Slog.w(TAG, "Process/uid not found attempting kill of "
5658                            + processName + " / " + uid);
5659                }
5660            }
5661        } else {
5662            throw new SecurityException(callerUid + " cannot kill app process: " +
5663                    processName);
5664        }
5665    }
5666
5667    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5668        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5669                false, true, false, false, UserHandle.getUserId(uid), reason);
5670        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5671                Uri.fromParts("package", packageName, null));
5672        if (!mProcessesReady) {
5673            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5674                    | Intent.FLAG_RECEIVER_FOREGROUND);
5675        }
5676        intent.putExtra(Intent.EXTRA_UID, uid);
5677        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5678        broadcastIntentLocked(null, null, intent,
5679                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5680                false, false,
5681                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5682    }
5683
5684    private void forceStopUserLocked(int userId, String reason) {
5685        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5686        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5687        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5688                | Intent.FLAG_RECEIVER_FOREGROUND);
5689        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5690        broadcastIntentLocked(null, null, intent,
5691                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5692                false, false,
5693                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5694    }
5695
5696    private final boolean killPackageProcessesLocked(String packageName, int appId,
5697            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5698            boolean doit, boolean evenPersistent, String reason) {
5699        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5700
5701        // Remove all processes this package may have touched: all with the
5702        // same UID (except for the system or root user), and all whose name
5703        // matches the package name.
5704        final int NP = mProcessNames.getMap().size();
5705        for (int ip=0; ip<NP; ip++) {
5706            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5707            final int NA = apps.size();
5708            for (int ia=0; ia<NA; ia++) {
5709                ProcessRecord app = apps.valueAt(ia);
5710                if (app.persistent && !evenPersistent) {
5711                    // we don't kill persistent processes
5712                    continue;
5713                }
5714                if (app.removed) {
5715                    if (doit) {
5716                        procs.add(app);
5717                    }
5718                    continue;
5719                }
5720
5721                // Skip process if it doesn't meet our oom adj requirement.
5722                if (app.setAdj < minOomAdj) {
5723                    continue;
5724                }
5725
5726                // If no package is specified, we call all processes under the
5727                // give user id.
5728                if (packageName == null) {
5729                    if (app.userId != userId) {
5730                        continue;
5731                    }
5732                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5733                        continue;
5734                    }
5735                // Package has been specified, we want to hit all processes
5736                // that match it.  We need to qualify this by the processes
5737                // that are running under the specified app and user ID.
5738                } else {
5739                    final boolean isDep = app.pkgDeps != null
5740                            && app.pkgDeps.contains(packageName);
5741                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5742                        continue;
5743                    }
5744                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5745                        continue;
5746                    }
5747                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5748                        continue;
5749                    }
5750                }
5751
5752                // Process has passed all conditions, kill it!
5753                if (!doit) {
5754                    return true;
5755                }
5756                app.removed = true;
5757                procs.add(app);
5758            }
5759        }
5760
5761        int N = procs.size();
5762        for (int i=0; i<N; i++) {
5763            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5764        }
5765        updateOomAdjLocked();
5766        return N > 0;
5767    }
5768
5769    private final boolean forceStopPackageLocked(String name, int appId,
5770            boolean callerWillRestart, boolean purgeCache, boolean doit,
5771            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5772        int i;
5773        int N;
5774
5775        if (userId == UserHandle.USER_ALL && name == null) {
5776            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5777        }
5778
5779        if (appId < 0 && name != null) {
5780            try {
5781                appId = UserHandle.getAppId(
5782                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5783            } catch (RemoteException e) {
5784            }
5785        }
5786
5787        if (doit) {
5788            if (name != null) {
5789                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5790                        + " user=" + userId + ": " + reason);
5791            } else {
5792                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5793            }
5794
5795            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5796            for (int ip=pmap.size()-1; ip>=0; ip--) {
5797                SparseArray<Long> ba = pmap.valueAt(ip);
5798                for (i=ba.size()-1; i>=0; i--) {
5799                    boolean remove = false;
5800                    final int entUid = ba.keyAt(i);
5801                    if (name != null) {
5802                        if (userId == UserHandle.USER_ALL) {
5803                            if (UserHandle.getAppId(entUid) == appId) {
5804                                remove = true;
5805                            }
5806                        } else {
5807                            if (entUid == UserHandle.getUid(userId, appId)) {
5808                                remove = true;
5809                            }
5810                        }
5811                    } else if (UserHandle.getUserId(entUid) == userId) {
5812                        remove = true;
5813                    }
5814                    if (remove) {
5815                        ba.removeAt(i);
5816                    }
5817                }
5818                if (ba.size() == 0) {
5819                    pmap.removeAt(ip);
5820                }
5821            }
5822        }
5823
5824        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5825                -100, callerWillRestart, true, doit, evenPersistent,
5826                name == null ? ("stop user " + userId) : ("stop " + name));
5827
5828        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5829            if (!doit) {
5830                return true;
5831            }
5832            didSomething = true;
5833        }
5834
5835        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5836            if (!doit) {
5837                return true;
5838            }
5839            didSomething = true;
5840        }
5841
5842        if (name == null) {
5843            // Remove all sticky broadcasts from this user.
5844            mStickyBroadcasts.remove(userId);
5845        }
5846
5847        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5848        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5849                userId, providers)) {
5850            if (!doit) {
5851                return true;
5852            }
5853            didSomething = true;
5854        }
5855        N = providers.size();
5856        for (i=0; i<N; i++) {
5857            removeDyingProviderLocked(null, providers.get(i), true);
5858        }
5859
5860        // Remove transient permissions granted from/to this package/user
5861        removeUriPermissionsForPackageLocked(name, userId, false);
5862
5863        if (name == null || uninstalling) {
5864            // Remove pending intents.  For now we only do this when force
5865            // stopping users, because we have some problems when doing this
5866            // for packages -- app widgets are not currently cleaned up for
5867            // such packages, so they can be left with bad pending intents.
5868            if (mIntentSenderRecords.size() > 0) {
5869                Iterator<WeakReference<PendingIntentRecord>> it
5870                        = mIntentSenderRecords.values().iterator();
5871                while (it.hasNext()) {
5872                    WeakReference<PendingIntentRecord> wpir = it.next();
5873                    if (wpir == null) {
5874                        it.remove();
5875                        continue;
5876                    }
5877                    PendingIntentRecord pir = wpir.get();
5878                    if (pir == null) {
5879                        it.remove();
5880                        continue;
5881                    }
5882                    if (name == null) {
5883                        // Stopping user, remove all objects for the user.
5884                        if (pir.key.userId != userId) {
5885                            // Not the same user, skip it.
5886                            continue;
5887                        }
5888                    } else {
5889                        if (UserHandle.getAppId(pir.uid) != appId) {
5890                            // Different app id, skip it.
5891                            continue;
5892                        }
5893                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5894                            // Different user, skip it.
5895                            continue;
5896                        }
5897                        if (!pir.key.packageName.equals(name)) {
5898                            // Different package, skip it.
5899                            continue;
5900                        }
5901                    }
5902                    if (!doit) {
5903                        return true;
5904                    }
5905                    didSomething = true;
5906                    it.remove();
5907                    pir.canceled = true;
5908                    if (pir.key.activity != null) {
5909                        pir.key.activity.pendingResults.remove(pir.ref);
5910                    }
5911                }
5912            }
5913        }
5914
5915        if (doit) {
5916            if (purgeCache && name != null) {
5917                AttributeCache ac = AttributeCache.instance();
5918                if (ac != null) {
5919                    ac.removePackage(name);
5920                }
5921            }
5922            if (mBooted) {
5923                mStackSupervisor.resumeTopActivitiesLocked();
5924                mStackSupervisor.scheduleIdleLocked();
5925            }
5926        }
5927
5928        return didSomething;
5929    }
5930
5931    private final boolean removeProcessLocked(ProcessRecord app,
5932            boolean callerWillRestart, boolean allowRestart, String reason) {
5933        final String name = app.processName;
5934        final int uid = app.uid;
5935        if (DEBUG_PROCESSES) Slog.d(
5936            TAG, "Force removing proc " + app.toShortString() + " (" + name
5937            + "/" + uid + ")");
5938
5939        mProcessNames.remove(name, uid);
5940        mIsolatedProcesses.remove(app.uid);
5941        if (mHeavyWeightProcess == app) {
5942            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5943                    mHeavyWeightProcess.userId, 0));
5944            mHeavyWeightProcess = null;
5945        }
5946        boolean needRestart = false;
5947        if (app.pid > 0 && app.pid != MY_PID) {
5948            int pid = app.pid;
5949            synchronized (mPidsSelfLocked) {
5950                mPidsSelfLocked.remove(pid);
5951                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5952            }
5953            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5954            if (app.isolated) {
5955                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5956            }
5957            app.kill(reason, true);
5958            handleAppDiedLocked(app, true, allowRestart);
5959            removeLruProcessLocked(app);
5960
5961            if (app.persistent && !app.isolated) {
5962                if (!callerWillRestart) {
5963                    addAppLocked(app.info, false, null /* ABI override */);
5964                } else {
5965                    needRestart = true;
5966                }
5967            }
5968        } else {
5969            mRemovedProcesses.add(app);
5970        }
5971
5972        return needRestart;
5973    }
5974
5975    private final void processStartTimedOutLocked(ProcessRecord app) {
5976        final int pid = app.pid;
5977        boolean gone = false;
5978        synchronized (mPidsSelfLocked) {
5979            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5980            if (knownApp != null && knownApp.thread == null) {
5981                mPidsSelfLocked.remove(pid);
5982                gone = true;
5983            }
5984        }
5985
5986        if (gone) {
5987            Slog.w(TAG, "Process " + app + " failed to attach");
5988            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5989                    pid, app.uid, app.processName);
5990            mProcessNames.remove(app.processName, app.uid);
5991            mIsolatedProcesses.remove(app.uid);
5992            if (mHeavyWeightProcess == app) {
5993                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5994                        mHeavyWeightProcess.userId, 0));
5995                mHeavyWeightProcess = null;
5996            }
5997            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5998            if (app.isolated) {
5999                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6000            }
6001            // Take care of any launching providers waiting for this process.
6002            checkAppInLaunchingProvidersLocked(app, true);
6003            // Take care of any services that are waiting for the process.
6004            mServices.processStartTimedOutLocked(app);
6005            app.kill("start timeout", true);
6006            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6007                Slog.w(TAG, "Unattached app died before backup, skipping");
6008                try {
6009                    IBackupManager bm = IBackupManager.Stub.asInterface(
6010                            ServiceManager.getService(Context.BACKUP_SERVICE));
6011                    bm.agentDisconnected(app.info.packageName);
6012                } catch (RemoteException e) {
6013                    // Can't happen; the backup manager is local
6014                }
6015            }
6016            if (isPendingBroadcastProcessLocked(pid)) {
6017                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6018                skipPendingBroadcastLocked(pid);
6019            }
6020        } else {
6021            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6022        }
6023    }
6024
6025    private final boolean attachApplicationLocked(IApplicationThread thread,
6026            int pid) {
6027
6028        // Find the application record that is being attached...  either via
6029        // the pid if we are running in multiple processes, or just pull the
6030        // next app record if we are emulating process with anonymous threads.
6031        ProcessRecord app;
6032        if (pid != MY_PID && pid >= 0) {
6033            synchronized (mPidsSelfLocked) {
6034                app = mPidsSelfLocked.get(pid);
6035            }
6036        } else {
6037            app = null;
6038        }
6039
6040        if (app == null) {
6041            Slog.w(TAG, "No pending application record for pid " + pid
6042                    + " (IApplicationThread " + thread + "); dropping process");
6043            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6044            if (pid > 0 && pid != MY_PID) {
6045                Process.killProcessQuiet(pid);
6046                //TODO: Process.killProcessGroup(app.info.uid, pid);
6047            } else {
6048                try {
6049                    thread.scheduleExit();
6050                } catch (Exception e) {
6051                    // Ignore exceptions.
6052                }
6053            }
6054            return false;
6055        }
6056
6057        // If this application record is still attached to a previous
6058        // process, clean it up now.
6059        if (app.thread != null) {
6060            handleAppDiedLocked(app, true, true);
6061        }
6062
6063        // Tell the process all about itself.
6064
6065        if (localLOGV) Slog.v(
6066                TAG, "Binding process pid " + pid + " to record " + app);
6067
6068        final String processName = app.processName;
6069        try {
6070            AppDeathRecipient adr = new AppDeathRecipient(
6071                    app, pid, thread);
6072            thread.asBinder().linkToDeath(adr, 0);
6073            app.deathRecipient = adr;
6074        } catch (RemoteException e) {
6075            app.resetPackageList(mProcessStats);
6076            startProcessLocked(app, "link fail", processName);
6077            return false;
6078        }
6079
6080        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6081
6082        app.makeActive(thread, mProcessStats);
6083        app.curAdj = app.setAdj = -100;
6084        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6085        app.forcingToForeground = null;
6086        updateProcessForegroundLocked(app, false, false);
6087        app.hasShownUi = false;
6088        app.debugging = false;
6089        app.cached = false;
6090
6091        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6092
6093        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6094        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6095
6096        if (!normalMode) {
6097            Slog.i(TAG, "Launching preboot mode app: " + app);
6098        }
6099
6100        if (localLOGV) Slog.v(
6101            TAG, "New app record " + app
6102            + " thread=" + thread.asBinder() + " pid=" + pid);
6103        try {
6104            int testMode = IApplicationThread.DEBUG_OFF;
6105            if (mDebugApp != null && mDebugApp.equals(processName)) {
6106                testMode = mWaitForDebugger
6107                    ? IApplicationThread.DEBUG_WAIT
6108                    : IApplicationThread.DEBUG_ON;
6109                app.debugging = true;
6110                if (mDebugTransient) {
6111                    mDebugApp = mOrigDebugApp;
6112                    mWaitForDebugger = mOrigWaitForDebugger;
6113                }
6114            }
6115            String profileFile = app.instrumentationProfileFile;
6116            ParcelFileDescriptor profileFd = null;
6117            int samplingInterval = 0;
6118            boolean profileAutoStop = false;
6119            if (mProfileApp != null && mProfileApp.equals(processName)) {
6120                mProfileProc = app;
6121                profileFile = mProfileFile;
6122                profileFd = mProfileFd;
6123                samplingInterval = mSamplingInterval;
6124                profileAutoStop = mAutoStopProfiler;
6125            }
6126            boolean enableOpenGlTrace = false;
6127            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6128                enableOpenGlTrace = true;
6129                mOpenGlTraceApp = null;
6130            }
6131
6132            // If the app is being launched for restore or full backup, set it up specially
6133            boolean isRestrictedBackupMode = false;
6134            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6135                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6136                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6137                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6138            }
6139
6140            ensurePackageDexOpt(app.instrumentationInfo != null
6141                    ? app.instrumentationInfo.packageName
6142                    : app.info.packageName);
6143            if (app.instrumentationClass != null) {
6144                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6145            }
6146            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6147                    + processName + " with config " + mConfiguration);
6148            ApplicationInfo appInfo = app.instrumentationInfo != null
6149                    ? app.instrumentationInfo : app.info;
6150            app.compat = compatibilityInfoForPackageLocked(appInfo);
6151            if (profileFd != null) {
6152                profileFd = profileFd.dup();
6153            }
6154            ProfilerInfo profilerInfo = profileFile == null ? null
6155                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6156            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6157                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6158                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6159                    isRestrictedBackupMode || !normalMode, app.persistent,
6160                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6161                    mCoreSettingsObserver.getCoreSettingsLocked());
6162            updateLruProcessLocked(app, false, null);
6163            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6164        } catch (Exception e) {
6165            // todo: Yikes!  What should we do?  For now we will try to
6166            // start another process, but that could easily get us in
6167            // an infinite loop of restarting processes...
6168            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6169
6170            app.resetPackageList(mProcessStats);
6171            app.unlinkDeathRecipient();
6172            startProcessLocked(app, "bind fail", processName);
6173            return false;
6174        }
6175
6176        // Remove this record from the list of starting applications.
6177        mPersistentStartingProcesses.remove(app);
6178        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6179                "Attach application locked removing on hold: " + app);
6180        mProcessesOnHold.remove(app);
6181
6182        boolean badApp = false;
6183        boolean didSomething = false;
6184
6185        // See if the top visible activity is waiting to run in this process...
6186        if (normalMode) {
6187            try {
6188                if (mStackSupervisor.attachApplicationLocked(app)) {
6189                    didSomething = true;
6190                }
6191            } catch (Exception e) {
6192                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6193                badApp = true;
6194            }
6195        }
6196
6197        // Find any services that should be running in this process...
6198        if (!badApp) {
6199            try {
6200                didSomething |= mServices.attachApplicationLocked(app, processName);
6201            } catch (Exception e) {
6202                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6203                badApp = true;
6204            }
6205        }
6206
6207        // Check if a next-broadcast receiver is in this process...
6208        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6209            try {
6210                didSomething |= sendPendingBroadcastsLocked(app);
6211            } catch (Exception e) {
6212                // If the app died trying to launch the receiver we declare it 'bad'
6213                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6214                badApp = true;
6215            }
6216        }
6217
6218        // Check whether the next backup agent is in this process...
6219        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6220            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6221            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6222            try {
6223                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6224                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6225                        mBackupTarget.backupMode);
6226            } catch (Exception e) {
6227                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6228                badApp = true;
6229            }
6230        }
6231
6232        if (badApp) {
6233            app.kill("error during init", true);
6234            handleAppDiedLocked(app, false, true);
6235            return false;
6236        }
6237
6238        if (!didSomething) {
6239            updateOomAdjLocked();
6240        }
6241
6242        return true;
6243    }
6244
6245    @Override
6246    public final void attachApplication(IApplicationThread thread) {
6247        synchronized (this) {
6248            int callingPid = Binder.getCallingPid();
6249            final long origId = Binder.clearCallingIdentity();
6250            attachApplicationLocked(thread, callingPid);
6251            Binder.restoreCallingIdentity(origId);
6252        }
6253    }
6254
6255    @Override
6256    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6257        final long origId = Binder.clearCallingIdentity();
6258        synchronized (this) {
6259            ActivityStack stack = ActivityRecord.getStackLocked(token);
6260            if (stack != null) {
6261                ActivityRecord r =
6262                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6263                if (stopProfiling) {
6264                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6265                        try {
6266                            mProfileFd.close();
6267                        } catch (IOException e) {
6268                        }
6269                        clearProfilerLocked();
6270                    }
6271                }
6272            }
6273        }
6274        Binder.restoreCallingIdentity(origId);
6275    }
6276
6277    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6278        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6279                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6280    }
6281
6282    void enableScreenAfterBoot() {
6283        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6284                SystemClock.uptimeMillis());
6285        mWindowManager.enableScreenAfterBoot();
6286
6287        synchronized (this) {
6288            updateEventDispatchingLocked();
6289        }
6290    }
6291
6292    @Override
6293    public void showBootMessage(final CharSequence msg, final boolean always) {
6294        enforceNotIsolatedCaller("showBootMessage");
6295        mWindowManager.showBootMessage(msg, always);
6296    }
6297
6298    @Override
6299    public void keyguardWaitingForActivityDrawn() {
6300        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6301        final long token = Binder.clearCallingIdentity();
6302        try {
6303            synchronized (this) {
6304                if (DEBUG_LOCKSCREEN) logLockScreen("");
6305                mWindowManager.keyguardWaitingForActivityDrawn();
6306                if (mLockScreenShown) {
6307                    mLockScreenShown = false;
6308                    comeOutOfSleepIfNeededLocked();
6309                }
6310            }
6311        } finally {
6312            Binder.restoreCallingIdentity(token);
6313        }
6314    }
6315
6316    final void finishBooting() {
6317        synchronized (this) {
6318            if (!mBootAnimationComplete) {
6319                mCallFinishBooting = true;
6320                return;
6321            }
6322            mCallFinishBooting = false;
6323        }
6324
6325        // Register receivers to handle package update events
6326        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6327
6328        // Let system services know.
6329        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6330
6331        synchronized (this) {
6332            // Ensure that any processes we had put on hold are now started
6333            // up.
6334            final int NP = mProcessesOnHold.size();
6335            if (NP > 0) {
6336                ArrayList<ProcessRecord> procs =
6337                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6338                for (int ip=0; ip<NP; ip++) {
6339                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6340                            + procs.get(ip));
6341                    startProcessLocked(procs.get(ip), "on-hold", null);
6342                }
6343            }
6344
6345            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6346                // Start looking for apps that are abusing wake locks.
6347                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6348                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6349                // Tell anyone interested that we are done booting!
6350                SystemProperties.set("sys.boot_completed", "1");
6351
6352                // And trigger dev.bootcomplete if we are not showing encryption progress
6353                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6354                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6355                    SystemProperties.set("dev.bootcomplete", "1");
6356                }
6357                for (int i=0; i<mStartedUsers.size(); i++) {
6358                    UserStartedState uss = mStartedUsers.valueAt(i);
6359                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6360                        uss.mState = UserStartedState.STATE_RUNNING;
6361                        final int userId = mStartedUsers.keyAt(i);
6362                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6363                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6364                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6365                        broadcastIntentLocked(null, null, intent, null,
6366                                new IIntentReceiver.Stub() {
6367                                    @Override
6368                                    public void performReceive(Intent intent, int resultCode,
6369                                            String data, Bundle extras, boolean ordered,
6370                                            boolean sticky, int sendingUser) {
6371                                        synchronized (ActivityManagerService.this) {
6372                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6373                                                    true, false);
6374                                        }
6375                                    }
6376                                },
6377                                0, null, null,
6378                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6379                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6380                                userId);
6381                    }
6382                }
6383                scheduleStartProfilesLocked();
6384            }
6385        }
6386    }
6387
6388    @Override
6389    public void bootAnimationComplete() {
6390        final boolean callFinishBooting;
6391        synchronized (this) {
6392            callFinishBooting = mCallFinishBooting;
6393            mBootAnimationComplete = true;
6394        }
6395        if (callFinishBooting) {
6396            finishBooting();
6397        }
6398    }
6399
6400    final void ensureBootCompleted() {
6401        boolean booting;
6402        boolean enableScreen;
6403        synchronized (this) {
6404            booting = mBooting;
6405            mBooting = false;
6406            enableScreen = !mBooted;
6407            mBooted = true;
6408        }
6409
6410        if (booting) {
6411            finishBooting();
6412        }
6413
6414        if (enableScreen) {
6415            enableScreenAfterBoot();
6416        }
6417    }
6418
6419    @Override
6420    public final void activityResumed(IBinder token) {
6421        final long origId = Binder.clearCallingIdentity();
6422        synchronized(this) {
6423            ActivityStack stack = ActivityRecord.getStackLocked(token);
6424            if (stack != null) {
6425                ActivityRecord.activityResumedLocked(token);
6426            }
6427        }
6428        Binder.restoreCallingIdentity(origId);
6429    }
6430
6431    @Override
6432    public final void activityPaused(IBinder token) {
6433        final long origId = Binder.clearCallingIdentity();
6434        synchronized(this) {
6435            ActivityStack stack = ActivityRecord.getStackLocked(token);
6436            if (stack != null) {
6437                stack.activityPausedLocked(token, false);
6438            }
6439        }
6440        Binder.restoreCallingIdentity(origId);
6441    }
6442
6443    @Override
6444    public final void activityStopped(IBinder token, Bundle icicle,
6445            PersistableBundle persistentState, CharSequence description) {
6446        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6447
6448        // Refuse possible leaked file descriptors
6449        if (icicle != null && icicle.hasFileDescriptors()) {
6450            throw new IllegalArgumentException("File descriptors passed in Bundle");
6451        }
6452
6453        final long origId = Binder.clearCallingIdentity();
6454
6455        synchronized (this) {
6456            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6457            if (r != null) {
6458                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6459            }
6460        }
6461
6462        trimApplications();
6463
6464        Binder.restoreCallingIdentity(origId);
6465    }
6466
6467    @Override
6468    public final void activityDestroyed(IBinder token) {
6469        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6470        synchronized (this) {
6471            ActivityStack stack = ActivityRecord.getStackLocked(token);
6472            if (stack != null) {
6473                stack.activityDestroyedLocked(token);
6474            }
6475        }
6476    }
6477
6478    @Override
6479    public final void backgroundResourcesReleased(IBinder token) {
6480        final long origId = Binder.clearCallingIdentity();
6481        try {
6482            synchronized (this) {
6483                ActivityStack stack = ActivityRecord.getStackLocked(token);
6484                if (stack != null) {
6485                    stack.backgroundResourcesReleased(token);
6486                }
6487            }
6488        } finally {
6489            Binder.restoreCallingIdentity(origId);
6490        }
6491    }
6492
6493    @Override
6494    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6495        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6496    }
6497
6498    @Override
6499    public final void notifyEnterAnimationComplete(IBinder token) {
6500        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6501    }
6502
6503    @Override
6504    public String getCallingPackage(IBinder token) {
6505        synchronized (this) {
6506            ActivityRecord r = getCallingRecordLocked(token);
6507            return r != null ? r.info.packageName : null;
6508        }
6509    }
6510
6511    @Override
6512    public ComponentName getCallingActivity(IBinder token) {
6513        synchronized (this) {
6514            ActivityRecord r = getCallingRecordLocked(token);
6515            return r != null ? r.intent.getComponent() : null;
6516        }
6517    }
6518
6519    private ActivityRecord getCallingRecordLocked(IBinder token) {
6520        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6521        if (r == null) {
6522            return null;
6523        }
6524        return r.resultTo;
6525    }
6526
6527    @Override
6528    public ComponentName getActivityClassForToken(IBinder token) {
6529        synchronized(this) {
6530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6531            if (r == null) {
6532                return null;
6533            }
6534            return r.intent.getComponent();
6535        }
6536    }
6537
6538    @Override
6539    public String getPackageForToken(IBinder token) {
6540        synchronized(this) {
6541            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6542            if (r == null) {
6543                return null;
6544            }
6545            return r.packageName;
6546        }
6547    }
6548
6549    @Override
6550    public IIntentSender getIntentSender(int type,
6551            String packageName, IBinder token, String resultWho,
6552            int requestCode, Intent[] intents, String[] resolvedTypes,
6553            int flags, Bundle options, int userId) {
6554        enforceNotIsolatedCaller("getIntentSender");
6555        // Refuse possible leaked file descriptors
6556        if (intents != null) {
6557            if (intents.length < 1) {
6558                throw new IllegalArgumentException("Intents array length must be >= 1");
6559            }
6560            for (int i=0; i<intents.length; i++) {
6561                Intent intent = intents[i];
6562                if (intent != null) {
6563                    if (intent.hasFileDescriptors()) {
6564                        throw new IllegalArgumentException("File descriptors passed in Intent");
6565                    }
6566                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6567                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6568                        throw new IllegalArgumentException(
6569                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6570                    }
6571                    intents[i] = new Intent(intent);
6572                }
6573            }
6574            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6575                throw new IllegalArgumentException(
6576                        "Intent array length does not match resolvedTypes length");
6577            }
6578        }
6579        if (options != null) {
6580            if (options.hasFileDescriptors()) {
6581                throw new IllegalArgumentException("File descriptors passed in options");
6582            }
6583        }
6584
6585        synchronized(this) {
6586            int callingUid = Binder.getCallingUid();
6587            int origUserId = userId;
6588            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6589                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6590                    ALLOW_NON_FULL, "getIntentSender", null);
6591            if (origUserId == UserHandle.USER_CURRENT) {
6592                // We don't want to evaluate this until the pending intent is
6593                // actually executed.  However, we do want to always do the
6594                // security checking for it above.
6595                userId = UserHandle.USER_CURRENT;
6596            }
6597            try {
6598                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6599                    int uid = AppGlobals.getPackageManager()
6600                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6601                    if (!UserHandle.isSameApp(callingUid, uid)) {
6602                        String msg = "Permission Denial: getIntentSender() from pid="
6603                            + Binder.getCallingPid()
6604                            + ", uid=" + Binder.getCallingUid()
6605                            + ", (need uid=" + uid + ")"
6606                            + " is not allowed to send as package " + packageName;
6607                        Slog.w(TAG, msg);
6608                        throw new SecurityException(msg);
6609                    }
6610                }
6611
6612                return getIntentSenderLocked(type, packageName, callingUid, userId,
6613                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6614
6615            } catch (RemoteException e) {
6616                throw new SecurityException(e);
6617            }
6618        }
6619    }
6620
6621    IIntentSender getIntentSenderLocked(int type, String packageName,
6622            int callingUid, int userId, IBinder token, String resultWho,
6623            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6624            Bundle options) {
6625        if (DEBUG_MU)
6626            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6627        ActivityRecord activity = null;
6628        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6629            activity = ActivityRecord.isInStackLocked(token);
6630            if (activity == null) {
6631                return null;
6632            }
6633            if (activity.finishing) {
6634                return null;
6635            }
6636        }
6637
6638        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6639        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6640        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6641        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6642                |PendingIntent.FLAG_UPDATE_CURRENT);
6643
6644        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6645                type, packageName, activity, resultWho,
6646                requestCode, intents, resolvedTypes, flags, options, userId);
6647        WeakReference<PendingIntentRecord> ref;
6648        ref = mIntentSenderRecords.get(key);
6649        PendingIntentRecord rec = ref != null ? ref.get() : null;
6650        if (rec != null) {
6651            if (!cancelCurrent) {
6652                if (updateCurrent) {
6653                    if (rec.key.requestIntent != null) {
6654                        rec.key.requestIntent.replaceExtras(intents != null ?
6655                                intents[intents.length - 1] : null);
6656                    }
6657                    if (intents != null) {
6658                        intents[intents.length-1] = rec.key.requestIntent;
6659                        rec.key.allIntents = intents;
6660                        rec.key.allResolvedTypes = resolvedTypes;
6661                    } else {
6662                        rec.key.allIntents = null;
6663                        rec.key.allResolvedTypes = null;
6664                    }
6665                }
6666                return rec;
6667            }
6668            rec.canceled = true;
6669            mIntentSenderRecords.remove(key);
6670        }
6671        if (noCreate) {
6672            return rec;
6673        }
6674        rec = new PendingIntentRecord(this, key, callingUid);
6675        mIntentSenderRecords.put(key, rec.ref);
6676        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6677            if (activity.pendingResults == null) {
6678                activity.pendingResults
6679                        = new HashSet<WeakReference<PendingIntentRecord>>();
6680            }
6681            activity.pendingResults.add(rec.ref);
6682        }
6683        return rec;
6684    }
6685
6686    @Override
6687    public void cancelIntentSender(IIntentSender sender) {
6688        if (!(sender instanceof PendingIntentRecord)) {
6689            return;
6690        }
6691        synchronized(this) {
6692            PendingIntentRecord rec = (PendingIntentRecord)sender;
6693            try {
6694                int uid = AppGlobals.getPackageManager()
6695                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6696                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6697                    String msg = "Permission Denial: cancelIntentSender() from pid="
6698                        + Binder.getCallingPid()
6699                        + ", uid=" + Binder.getCallingUid()
6700                        + " is not allowed to cancel packges "
6701                        + rec.key.packageName;
6702                    Slog.w(TAG, msg);
6703                    throw new SecurityException(msg);
6704                }
6705            } catch (RemoteException e) {
6706                throw new SecurityException(e);
6707            }
6708            cancelIntentSenderLocked(rec, true);
6709        }
6710    }
6711
6712    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6713        rec.canceled = true;
6714        mIntentSenderRecords.remove(rec.key);
6715        if (cleanActivity && rec.key.activity != null) {
6716            rec.key.activity.pendingResults.remove(rec.ref);
6717        }
6718    }
6719
6720    @Override
6721    public String getPackageForIntentSender(IIntentSender pendingResult) {
6722        if (!(pendingResult instanceof PendingIntentRecord)) {
6723            return null;
6724        }
6725        try {
6726            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6727            return res.key.packageName;
6728        } catch (ClassCastException e) {
6729        }
6730        return null;
6731    }
6732
6733    @Override
6734    public int getUidForIntentSender(IIntentSender sender) {
6735        if (sender instanceof PendingIntentRecord) {
6736            try {
6737                PendingIntentRecord res = (PendingIntentRecord)sender;
6738                return res.uid;
6739            } catch (ClassCastException e) {
6740            }
6741        }
6742        return -1;
6743    }
6744
6745    @Override
6746    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6747        if (!(pendingResult instanceof PendingIntentRecord)) {
6748            return false;
6749        }
6750        try {
6751            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6752            if (res.key.allIntents == null) {
6753                return false;
6754            }
6755            for (int i=0; i<res.key.allIntents.length; i++) {
6756                Intent intent = res.key.allIntents[i];
6757                if (intent.getPackage() != null && intent.getComponent() != null) {
6758                    return false;
6759                }
6760            }
6761            return true;
6762        } catch (ClassCastException e) {
6763        }
6764        return false;
6765    }
6766
6767    @Override
6768    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6769        if (!(pendingResult instanceof PendingIntentRecord)) {
6770            return false;
6771        }
6772        try {
6773            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6774            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6775                return true;
6776            }
6777            return false;
6778        } catch (ClassCastException e) {
6779        }
6780        return false;
6781    }
6782
6783    @Override
6784    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6785        if (!(pendingResult instanceof PendingIntentRecord)) {
6786            return null;
6787        }
6788        try {
6789            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6790            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6791        } catch (ClassCastException e) {
6792        }
6793        return null;
6794    }
6795
6796    @Override
6797    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6798        if (!(pendingResult instanceof PendingIntentRecord)) {
6799            return null;
6800        }
6801        try {
6802            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803            Intent intent = res.key.requestIntent;
6804            if (intent != null) {
6805                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6806                        || res.lastTagPrefix.equals(prefix))) {
6807                    return res.lastTag;
6808                }
6809                res.lastTagPrefix = prefix;
6810                StringBuilder sb = new StringBuilder(128);
6811                if (prefix != null) {
6812                    sb.append(prefix);
6813                }
6814                if (intent.getAction() != null) {
6815                    sb.append(intent.getAction());
6816                } else if (intent.getComponent() != null) {
6817                    intent.getComponent().appendShortString(sb);
6818                } else {
6819                    sb.append("?");
6820                }
6821                return res.lastTag = sb.toString();
6822            }
6823        } catch (ClassCastException e) {
6824        }
6825        return null;
6826    }
6827
6828    @Override
6829    public void setProcessLimit(int max) {
6830        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6831                "setProcessLimit()");
6832        synchronized (this) {
6833            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6834            mProcessLimitOverride = max;
6835        }
6836        trimApplications();
6837    }
6838
6839    @Override
6840    public int getProcessLimit() {
6841        synchronized (this) {
6842            return mProcessLimitOverride;
6843        }
6844    }
6845
6846    void foregroundTokenDied(ForegroundToken token) {
6847        synchronized (ActivityManagerService.this) {
6848            synchronized (mPidsSelfLocked) {
6849                ForegroundToken cur
6850                    = mForegroundProcesses.get(token.pid);
6851                if (cur != token) {
6852                    return;
6853                }
6854                mForegroundProcesses.remove(token.pid);
6855                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6856                if (pr == null) {
6857                    return;
6858                }
6859                pr.forcingToForeground = null;
6860                updateProcessForegroundLocked(pr, false, false);
6861            }
6862            updateOomAdjLocked();
6863        }
6864    }
6865
6866    @Override
6867    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6868        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6869                "setProcessForeground()");
6870        synchronized(this) {
6871            boolean changed = false;
6872
6873            synchronized (mPidsSelfLocked) {
6874                ProcessRecord pr = mPidsSelfLocked.get(pid);
6875                if (pr == null && isForeground) {
6876                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6877                    return;
6878                }
6879                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6880                if (oldToken != null) {
6881                    oldToken.token.unlinkToDeath(oldToken, 0);
6882                    mForegroundProcesses.remove(pid);
6883                    if (pr != null) {
6884                        pr.forcingToForeground = null;
6885                    }
6886                    changed = true;
6887                }
6888                if (isForeground && token != null) {
6889                    ForegroundToken newToken = new ForegroundToken() {
6890                        @Override
6891                        public void binderDied() {
6892                            foregroundTokenDied(this);
6893                        }
6894                    };
6895                    newToken.pid = pid;
6896                    newToken.token = token;
6897                    try {
6898                        token.linkToDeath(newToken, 0);
6899                        mForegroundProcesses.put(pid, newToken);
6900                        pr.forcingToForeground = token;
6901                        changed = true;
6902                    } catch (RemoteException e) {
6903                        // If the process died while doing this, we will later
6904                        // do the cleanup with the process death link.
6905                    }
6906                }
6907            }
6908
6909            if (changed) {
6910                updateOomAdjLocked();
6911            }
6912        }
6913    }
6914
6915    // =========================================================
6916    // PERMISSIONS
6917    // =========================================================
6918
6919    static class PermissionController extends IPermissionController.Stub {
6920        ActivityManagerService mActivityManagerService;
6921        PermissionController(ActivityManagerService activityManagerService) {
6922            mActivityManagerService = activityManagerService;
6923        }
6924
6925        @Override
6926        public boolean checkPermission(String permission, int pid, int uid) {
6927            return mActivityManagerService.checkPermission(permission, pid,
6928                    uid) == PackageManager.PERMISSION_GRANTED;
6929        }
6930    }
6931
6932    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6933        @Override
6934        public int checkComponentPermission(String permission, int pid, int uid,
6935                int owningUid, boolean exported) {
6936            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6937                    owningUid, exported);
6938        }
6939
6940        @Override
6941        public Object getAMSLock() {
6942            return ActivityManagerService.this;
6943        }
6944    }
6945
6946    /**
6947     * This can be called with or without the global lock held.
6948     */
6949    int checkComponentPermission(String permission, int pid, int uid,
6950            int owningUid, boolean exported) {
6951        // We might be performing an operation on behalf of an indirect binder
6952        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6953        // client identity accordingly before proceeding.
6954        Identity tlsIdentity = sCallerIdentity.get();
6955        if (tlsIdentity != null) {
6956            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6957                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6958            uid = tlsIdentity.uid;
6959            pid = tlsIdentity.pid;
6960        }
6961
6962        if (pid == MY_PID) {
6963            return PackageManager.PERMISSION_GRANTED;
6964        }
6965
6966        return ActivityManager.checkComponentPermission(permission, uid,
6967                owningUid, exported);
6968    }
6969
6970    /**
6971     * As the only public entry point for permissions checking, this method
6972     * can enforce the semantic that requesting a check on a null global
6973     * permission is automatically denied.  (Internally a null permission
6974     * string is used when calling {@link #checkComponentPermission} in cases
6975     * when only uid-based security is needed.)
6976     *
6977     * This can be called with or without the global lock held.
6978     */
6979    @Override
6980    public int checkPermission(String permission, int pid, int uid) {
6981        if (permission == null) {
6982            return PackageManager.PERMISSION_DENIED;
6983        }
6984        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6985    }
6986
6987    /**
6988     * Binder IPC calls go through the public entry point.
6989     * This can be called with or without the global lock held.
6990     */
6991    int checkCallingPermission(String permission) {
6992        return checkPermission(permission,
6993                Binder.getCallingPid(),
6994                UserHandle.getAppId(Binder.getCallingUid()));
6995    }
6996
6997    /**
6998     * This can be called with or without the global lock held.
6999     */
7000    void enforceCallingPermission(String permission, String func) {
7001        if (checkCallingPermission(permission)
7002                == PackageManager.PERMISSION_GRANTED) {
7003            return;
7004        }
7005
7006        String msg = "Permission Denial: " + func + " from pid="
7007                + Binder.getCallingPid()
7008                + ", uid=" + Binder.getCallingUid()
7009                + " requires " + permission;
7010        Slog.w(TAG, msg);
7011        throw new SecurityException(msg);
7012    }
7013
7014    /**
7015     * Determine if UID is holding permissions required to access {@link Uri} in
7016     * the given {@link ProviderInfo}. Final permission checking is always done
7017     * in {@link ContentProvider}.
7018     */
7019    private final boolean checkHoldingPermissionsLocked(
7020            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7021        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7022                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7023        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7024            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7025                    != PERMISSION_GRANTED) {
7026                return false;
7027            }
7028        }
7029        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7030    }
7031
7032    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7033            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7034        if (pi.applicationInfo.uid == uid) {
7035            return true;
7036        } else if (!pi.exported) {
7037            return false;
7038        }
7039
7040        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7041        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7042        try {
7043            // check if target holds top-level <provider> permissions
7044            if (!readMet && pi.readPermission != null && considerUidPermissions
7045                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7046                readMet = true;
7047            }
7048            if (!writeMet && pi.writePermission != null && considerUidPermissions
7049                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7050                writeMet = true;
7051            }
7052
7053            // track if unprotected read/write is allowed; any denied
7054            // <path-permission> below removes this ability
7055            boolean allowDefaultRead = pi.readPermission == null;
7056            boolean allowDefaultWrite = pi.writePermission == null;
7057
7058            // check if target holds any <path-permission> that match uri
7059            final PathPermission[] pps = pi.pathPermissions;
7060            if (pps != null) {
7061                final String path = grantUri.uri.getPath();
7062                int i = pps.length;
7063                while (i > 0 && (!readMet || !writeMet)) {
7064                    i--;
7065                    PathPermission pp = pps[i];
7066                    if (pp.match(path)) {
7067                        if (!readMet) {
7068                            final String pprperm = pp.getReadPermission();
7069                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7070                                    + pprperm + " for " + pp.getPath()
7071                                    + ": match=" + pp.match(path)
7072                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7073                            if (pprperm != null) {
7074                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7075                                        == PERMISSION_GRANTED) {
7076                                    readMet = true;
7077                                } else {
7078                                    allowDefaultRead = false;
7079                                }
7080                            }
7081                        }
7082                        if (!writeMet) {
7083                            final String ppwperm = pp.getWritePermission();
7084                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7085                                    + ppwperm + " for " + pp.getPath()
7086                                    + ": match=" + pp.match(path)
7087                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7088                            if (ppwperm != null) {
7089                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7090                                        == PERMISSION_GRANTED) {
7091                                    writeMet = true;
7092                                } else {
7093                                    allowDefaultWrite = false;
7094                                }
7095                            }
7096                        }
7097                    }
7098                }
7099            }
7100
7101            // grant unprotected <provider> read/write, if not blocked by
7102            // <path-permission> above
7103            if (allowDefaultRead) readMet = true;
7104            if (allowDefaultWrite) writeMet = true;
7105
7106        } catch (RemoteException e) {
7107            return false;
7108        }
7109
7110        return readMet && writeMet;
7111    }
7112
7113    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7114        ProviderInfo pi = null;
7115        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7116        if (cpr != null) {
7117            pi = cpr.info;
7118        } else {
7119            try {
7120                pi = AppGlobals.getPackageManager().resolveContentProvider(
7121                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7122            } catch (RemoteException ex) {
7123            }
7124        }
7125        return pi;
7126    }
7127
7128    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7129        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7130        if (targetUris != null) {
7131            return targetUris.get(grantUri);
7132        }
7133        return null;
7134    }
7135
7136    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7137            String targetPkg, int targetUid, GrantUri grantUri) {
7138        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7139        if (targetUris == null) {
7140            targetUris = Maps.newArrayMap();
7141            mGrantedUriPermissions.put(targetUid, targetUris);
7142        }
7143
7144        UriPermission perm = targetUris.get(grantUri);
7145        if (perm == null) {
7146            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7147            targetUris.put(grantUri, perm);
7148        }
7149
7150        return perm;
7151    }
7152
7153    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7154            final int modeFlags) {
7155        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7156        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7157                : UriPermission.STRENGTH_OWNED;
7158
7159        // Root gets to do everything.
7160        if (uid == 0) {
7161            return true;
7162        }
7163
7164        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7165        if (perms == null) return false;
7166
7167        // First look for exact match
7168        final UriPermission exactPerm = perms.get(grantUri);
7169        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7170            return true;
7171        }
7172
7173        // No exact match, look for prefixes
7174        final int N = perms.size();
7175        for (int i = 0; i < N; i++) {
7176            final UriPermission perm = perms.valueAt(i);
7177            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7178                    && perm.getStrength(modeFlags) >= minStrength) {
7179                return true;
7180            }
7181        }
7182
7183        return false;
7184    }
7185
7186    /**
7187     * @param uri This uri must NOT contain an embedded userId.
7188     * @param userId The userId in which the uri is to be resolved.
7189     */
7190    @Override
7191    public int checkUriPermission(Uri uri, int pid, int uid,
7192            final int modeFlags, int userId) {
7193        enforceNotIsolatedCaller("checkUriPermission");
7194
7195        // Another redirected-binder-call permissions check as in
7196        // {@link checkComponentPermission}.
7197        Identity tlsIdentity = sCallerIdentity.get();
7198        if (tlsIdentity != null) {
7199            uid = tlsIdentity.uid;
7200            pid = tlsIdentity.pid;
7201        }
7202
7203        // Our own process gets to do everything.
7204        if (pid == MY_PID) {
7205            return PackageManager.PERMISSION_GRANTED;
7206        }
7207        synchronized (this) {
7208            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7209                    ? PackageManager.PERMISSION_GRANTED
7210                    : PackageManager.PERMISSION_DENIED;
7211        }
7212    }
7213
7214    /**
7215     * Check if the targetPkg can be granted permission to access uri by
7216     * the callingUid using the given modeFlags.  Throws a security exception
7217     * if callingUid is not allowed to do this.  Returns the uid of the target
7218     * if the URI permission grant should be performed; returns -1 if it is not
7219     * needed (for example targetPkg already has permission to access the URI).
7220     * If you already know the uid of the target, you can supply it in
7221     * lastTargetUid else set that to -1.
7222     */
7223    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7224            final int modeFlags, int lastTargetUid) {
7225        if (!Intent.isAccessUriMode(modeFlags)) {
7226            return -1;
7227        }
7228
7229        if (targetPkg != null) {
7230            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7231                    "Checking grant " + targetPkg + " permission to " + grantUri);
7232        }
7233
7234        final IPackageManager pm = AppGlobals.getPackageManager();
7235
7236        // If this is not a content: uri, we can't do anything with it.
7237        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7238            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7239                    "Can't grant URI permission for non-content URI: " + grantUri);
7240            return -1;
7241        }
7242
7243        final String authority = grantUri.uri.getAuthority();
7244        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7245        if (pi == null) {
7246            Slog.w(TAG, "No content provider found for permission check: " +
7247                    grantUri.uri.toSafeString());
7248            return -1;
7249        }
7250
7251        int targetUid = lastTargetUid;
7252        if (targetUid < 0 && targetPkg != null) {
7253            try {
7254                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7255                if (targetUid < 0) {
7256                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7257                            "Can't grant URI permission no uid for: " + targetPkg);
7258                    return -1;
7259                }
7260            } catch (RemoteException ex) {
7261                return -1;
7262            }
7263        }
7264
7265        if (targetUid >= 0) {
7266            // First...  does the target actually need this permission?
7267            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7268                // No need to grant the target this permission.
7269                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7270                        "Target " + targetPkg + " already has full permission to " + grantUri);
7271                return -1;
7272            }
7273        } else {
7274            // First...  there is no target package, so can anyone access it?
7275            boolean allowed = pi.exported;
7276            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7277                if (pi.readPermission != null) {
7278                    allowed = false;
7279                }
7280            }
7281            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7282                if (pi.writePermission != null) {
7283                    allowed = false;
7284                }
7285            }
7286            if (allowed) {
7287                return -1;
7288            }
7289        }
7290
7291        /* There is a special cross user grant if:
7292         * - The target is on another user.
7293         * - Apps on the current user can access the uri without any uid permissions.
7294         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7295         * grant uri permissions.
7296         */
7297        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7298                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7299                modeFlags, false /*without considering the uid permissions*/);
7300
7301        // Second...  is the provider allowing granting of URI permissions?
7302        if (!specialCrossUserGrant) {
7303            if (!pi.grantUriPermissions) {
7304                throw new SecurityException("Provider " + pi.packageName
7305                        + "/" + pi.name
7306                        + " does not allow granting of Uri permissions (uri "
7307                        + grantUri + ")");
7308            }
7309            if (pi.uriPermissionPatterns != null) {
7310                final int N = pi.uriPermissionPatterns.length;
7311                boolean allowed = false;
7312                for (int i=0; i<N; i++) {
7313                    if (pi.uriPermissionPatterns[i] != null
7314                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7315                        allowed = true;
7316                        break;
7317                    }
7318                }
7319                if (!allowed) {
7320                    throw new SecurityException("Provider " + pi.packageName
7321                            + "/" + pi.name
7322                            + " does not allow granting of permission to path of Uri "
7323                            + grantUri);
7324                }
7325            }
7326        }
7327
7328        // Third...  does the caller itself have permission to access
7329        // this uri?
7330        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7331            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7332                // Require they hold a strong enough Uri permission
7333                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7334                    throw new SecurityException("Uid " + callingUid
7335                            + " does not have permission to uri " + grantUri);
7336                }
7337            }
7338        }
7339        return targetUid;
7340    }
7341
7342    /**
7343     * @param uri This uri must NOT contain an embedded userId.
7344     * @param userId The userId in which the uri is to be resolved.
7345     */
7346    @Override
7347    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7348            final int modeFlags, int userId) {
7349        enforceNotIsolatedCaller("checkGrantUriPermission");
7350        synchronized(this) {
7351            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7352                    new GrantUri(userId, uri, false), modeFlags, -1);
7353        }
7354    }
7355
7356    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7357            final int modeFlags, UriPermissionOwner owner) {
7358        if (!Intent.isAccessUriMode(modeFlags)) {
7359            return;
7360        }
7361
7362        // So here we are: the caller has the assumed permission
7363        // to the uri, and the target doesn't.  Let's now give this to
7364        // the target.
7365
7366        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7367                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7368
7369        final String authority = grantUri.uri.getAuthority();
7370        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7371        if (pi == null) {
7372            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7373            return;
7374        }
7375
7376        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7377            grantUri.prefix = true;
7378        }
7379        final UriPermission perm = findOrCreateUriPermissionLocked(
7380                pi.packageName, targetPkg, targetUid, grantUri);
7381        perm.grantModes(modeFlags, owner);
7382    }
7383
7384    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7385            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7386        if (targetPkg == null) {
7387            throw new NullPointerException("targetPkg");
7388        }
7389        int targetUid;
7390        final IPackageManager pm = AppGlobals.getPackageManager();
7391        try {
7392            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7393        } catch (RemoteException ex) {
7394            return;
7395        }
7396
7397        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7398                targetUid);
7399        if (targetUid < 0) {
7400            return;
7401        }
7402
7403        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7404                owner);
7405    }
7406
7407    static class NeededUriGrants extends ArrayList<GrantUri> {
7408        final String targetPkg;
7409        final int targetUid;
7410        final int flags;
7411
7412        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7413            this.targetPkg = targetPkg;
7414            this.targetUid = targetUid;
7415            this.flags = flags;
7416        }
7417    }
7418
7419    /**
7420     * Like checkGrantUriPermissionLocked, but takes an Intent.
7421     */
7422    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7423            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7424        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7425                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7426                + " clip=" + (intent != null ? intent.getClipData() : null)
7427                + " from " + intent + "; flags=0x"
7428                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7429
7430        if (targetPkg == null) {
7431            throw new NullPointerException("targetPkg");
7432        }
7433
7434        if (intent == null) {
7435            return null;
7436        }
7437        Uri data = intent.getData();
7438        ClipData clip = intent.getClipData();
7439        if (data == null && clip == null) {
7440            return null;
7441        }
7442        // Default userId for uris in the intent (if they don't specify it themselves)
7443        int contentUserHint = intent.getContentUserHint();
7444        if (contentUserHint == UserHandle.USER_CURRENT) {
7445            contentUserHint = UserHandle.getUserId(callingUid);
7446        }
7447        final IPackageManager pm = AppGlobals.getPackageManager();
7448        int targetUid;
7449        if (needed != null) {
7450            targetUid = needed.targetUid;
7451        } else {
7452            try {
7453                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7454            } catch (RemoteException ex) {
7455                return null;
7456            }
7457            if (targetUid < 0) {
7458                if (DEBUG_URI_PERMISSION) {
7459                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7460                            + " on user " + targetUserId);
7461                }
7462                return null;
7463            }
7464        }
7465        if (data != null) {
7466            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7467            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7468                    targetUid);
7469            if (targetUid > 0) {
7470                if (needed == null) {
7471                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7472                }
7473                needed.add(grantUri);
7474            }
7475        }
7476        if (clip != null) {
7477            for (int i=0; i<clip.getItemCount(); i++) {
7478                Uri uri = clip.getItemAt(i).getUri();
7479                if (uri != null) {
7480                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7481                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7482                            targetUid);
7483                    if (targetUid > 0) {
7484                        if (needed == null) {
7485                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7486                        }
7487                        needed.add(grantUri);
7488                    }
7489                } else {
7490                    Intent clipIntent = clip.getItemAt(i).getIntent();
7491                    if (clipIntent != null) {
7492                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7493                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7494                        if (newNeeded != null) {
7495                            needed = newNeeded;
7496                        }
7497                    }
7498                }
7499            }
7500        }
7501
7502        return needed;
7503    }
7504
7505    /**
7506     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7507     */
7508    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7509            UriPermissionOwner owner) {
7510        if (needed != null) {
7511            for (int i=0; i<needed.size(); i++) {
7512                GrantUri grantUri = needed.get(i);
7513                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7514                        grantUri, needed.flags, owner);
7515            }
7516        }
7517    }
7518
7519    void grantUriPermissionFromIntentLocked(int callingUid,
7520            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7521        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7522                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7523        if (needed == null) {
7524            return;
7525        }
7526
7527        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7528    }
7529
7530    /**
7531     * @param uri This uri must NOT contain an embedded userId.
7532     * @param userId The userId in which the uri is to be resolved.
7533     */
7534    @Override
7535    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7536            final int modeFlags, int userId) {
7537        enforceNotIsolatedCaller("grantUriPermission");
7538        GrantUri grantUri = new GrantUri(userId, uri, false);
7539        synchronized(this) {
7540            final ProcessRecord r = getRecordForAppLocked(caller);
7541            if (r == null) {
7542                throw new SecurityException("Unable to find app for caller "
7543                        + caller
7544                        + " when granting permission to uri " + grantUri);
7545            }
7546            if (targetPkg == null) {
7547                throw new IllegalArgumentException("null target");
7548            }
7549            if (grantUri == null) {
7550                throw new IllegalArgumentException("null uri");
7551            }
7552
7553            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7554                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7555                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7556                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7557
7558            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7559                    UserHandle.getUserId(r.uid));
7560        }
7561    }
7562
7563    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7564        if (perm.modeFlags == 0) {
7565            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7566                    perm.targetUid);
7567            if (perms != null) {
7568                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7569                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7570
7571                perms.remove(perm.uri);
7572                if (perms.isEmpty()) {
7573                    mGrantedUriPermissions.remove(perm.targetUid);
7574                }
7575            }
7576        }
7577    }
7578
7579    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7580        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7581
7582        final IPackageManager pm = AppGlobals.getPackageManager();
7583        final String authority = grantUri.uri.getAuthority();
7584        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7585        if (pi == null) {
7586            Slog.w(TAG, "No content provider found for permission revoke: "
7587                    + grantUri.toSafeString());
7588            return;
7589        }
7590
7591        // Does the caller have this permission on the URI?
7592        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7593            // If they don't have direct access to the URI, then revoke any
7594            // ownerless URI permissions that have been granted to them.
7595            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7596            if (perms != null) {
7597                boolean persistChanged = false;
7598                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7599                    final UriPermission perm = it.next();
7600                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7601                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7602                        if (DEBUG_URI_PERMISSION)
7603                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7604                                    " permission to " + perm.uri);
7605                        persistChanged |= perm.revokeModes(
7606                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7607                        if (perm.modeFlags == 0) {
7608                            it.remove();
7609                        }
7610                    }
7611                }
7612                if (perms.isEmpty()) {
7613                    mGrantedUriPermissions.remove(callingUid);
7614                }
7615                if (persistChanged) {
7616                    schedulePersistUriGrants();
7617                }
7618            }
7619            return;
7620        }
7621
7622        boolean persistChanged = false;
7623
7624        // Go through all of the permissions and remove any that match.
7625        int N = mGrantedUriPermissions.size();
7626        for (int i = 0; i < N; i++) {
7627            final int targetUid = mGrantedUriPermissions.keyAt(i);
7628            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7629
7630            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7631                final UriPermission perm = it.next();
7632                if (perm.uri.sourceUserId == grantUri.sourceUserId
7633                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7634                    if (DEBUG_URI_PERMISSION)
7635                        Slog.v(TAG,
7636                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7637                    persistChanged |= perm.revokeModes(
7638                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7639                    if (perm.modeFlags == 0) {
7640                        it.remove();
7641                    }
7642                }
7643            }
7644
7645            if (perms.isEmpty()) {
7646                mGrantedUriPermissions.remove(targetUid);
7647                N--;
7648                i--;
7649            }
7650        }
7651
7652        if (persistChanged) {
7653            schedulePersistUriGrants();
7654        }
7655    }
7656
7657    /**
7658     * @param uri This uri must NOT contain an embedded userId.
7659     * @param userId The userId in which the uri is to be resolved.
7660     */
7661    @Override
7662    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7663            int userId) {
7664        enforceNotIsolatedCaller("revokeUriPermission");
7665        synchronized(this) {
7666            final ProcessRecord r = getRecordForAppLocked(caller);
7667            if (r == null) {
7668                throw new SecurityException("Unable to find app for caller "
7669                        + caller
7670                        + " when revoking permission to uri " + uri);
7671            }
7672            if (uri == null) {
7673                Slog.w(TAG, "revokeUriPermission: null uri");
7674                return;
7675            }
7676
7677            if (!Intent.isAccessUriMode(modeFlags)) {
7678                return;
7679            }
7680
7681            final IPackageManager pm = AppGlobals.getPackageManager();
7682            final String authority = uri.getAuthority();
7683            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7684            if (pi == null) {
7685                Slog.w(TAG, "No content provider found for permission revoke: "
7686                        + uri.toSafeString());
7687                return;
7688            }
7689
7690            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7691        }
7692    }
7693
7694    /**
7695     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7696     * given package.
7697     *
7698     * @param packageName Package name to match, or {@code null} to apply to all
7699     *            packages.
7700     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7701     *            to all users.
7702     * @param persistable If persistable grants should be removed.
7703     */
7704    private void removeUriPermissionsForPackageLocked(
7705            String packageName, int userHandle, boolean persistable) {
7706        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7707            throw new IllegalArgumentException("Must narrow by either package or user");
7708        }
7709
7710        boolean persistChanged = false;
7711
7712        int N = mGrantedUriPermissions.size();
7713        for (int i = 0; i < N; i++) {
7714            final int targetUid = mGrantedUriPermissions.keyAt(i);
7715            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7716
7717            // Only inspect grants matching user
7718            if (userHandle == UserHandle.USER_ALL
7719                    || userHandle == UserHandle.getUserId(targetUid)) {
7720                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7721                    final UriPermission perm = it.next();
7722
7723                    // Only inspect grants matching package
7724                    if (packageName == null || perm.sourcePkg.equals(packageName)
7725                            || perm.targetPkg.equals(packageName)) {
7726                        persistChanged |= perm.revokeModes(persistable
7727                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7728
7729                        // Only remove when no modes remain; any persisted grants
7730                        // will keep this alive.
7731                        if (perm.modeFlags == 0) {
7732                            it.remove();
7733                        }
7734                    }
7735                }
7736
7737                if (perms.isEmpty()) {
7738                    mGrantedUriPermissions.remove(targetUid);
7739                    N--;
7740                    i--;
7741                }
7742            }
7743        }
7744
7745        if (persistChanged) {
7746            schedulePersistUriGrants();
7747        }
7748    }
7749
7750    @Override
7751    public IBinder newUriPermissionOwner(String name) {
7752        enforceNotIsolatedCaller("newUriPermissionOwner");
7753        synchronized(this) {
7754            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7755            return owner.getExternalTokenLocked();
7756        }
7757    }
7758
7759    /**
7760     * @param uri This uri must NOT contain an embedded userId.
7761     * @param sourceUserId The userId in which the uri is to be resolved.
7762     * @param targetUserId The userId of the app that receives the grant.
7763     */
7764    @Override
7765    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7766            final int modeFlags, int sourceUserId, int targetUserId) {
7767        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7768                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7769        synchronized(this) {
7770            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7771            if (owner == null) {
7772                throw new IllegalArgumentException("Unknown owner: " + token);
7773            }
7774            if (fromUid != Binder.getCallingUid()) {
7775                if (Binder.getCallingUid() != Process.myUid()) {
7776                    // Only system code can grant URI permissions on behalf
7777                    // of other users.
7778                    throw new SecurityException("nice try");
7779                }
7780            }
7781            if (targetPkg == null) {
7782                throw new IllegalArgumentException("null target");
7783            }
7784            if (uri == null) {
7785                throw new IllegalArgumentException("null uri");
7786            }
7787
7788            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7789                    modeFlags, owner, targetUserId);
7790        }
7791    }
7792
7793    /**
7794     * @param uri This uri must NOT contain an embedded userId.
7795     * @param userId The userId in which the uri is to be resolved.
7796     */
7797    @Override
7798    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7799        synchronized(this) {
7800            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7801            if (owner == null) {
7802                throw new IllegalArgumentException("Unknown owner: " + token);
7803            }
7804
7805            if (uri == null) {
7806                owner.removeUriPermissionsLocked(mode);
7807            } else {
7808                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7809            }
7810        }
7811    }
7812
7813    private void schedulePersistUriGrants() {
7814        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7815            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7816                    10 * DateUtils.SECOND_IN_MILLIS);
7817        }
7818    }
7819
7820    private void writeGrantedUriPermissions() {
7821        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7822
7823        // Snapshot permissions so we can persist without lock
7824        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7825        synchronized (this) {
7826            final int size = mGrantedUriPermissions.size();
7827            for (int i = 0; i < size; i++) {
7828                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7829                for (UriPermission perm : perms.values()) {
7830                    if (perm.persistedModeFlags != 0) {
7831                        persist.add(perm.snapshot());
7832                    }
7833                }
7834            }
7835        }
7836
7837        FileOutputStream fos = null;
7838        try {
7839            fos = mGrantFile.startWrite();
7840
7841            XmlSerializer out = new FastXmlSerializer();
7842            out.setOutput(fos, "utf-8");
7843            out.startDocument(null, true);
7844            out.startTag(null, TAG_URI_GRANTS);
7845            for (UriPermission.Snapshot perm : persist) {
7846                out.startTag(null, TAG_URI_GRANT);
7847                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7848                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7849                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7850                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7851                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7852                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7853                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7854                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7855                out.endTag(null, TAG_URI_GRANT);
7856            }
7857            out.endTag(null, TAG_URI_GRANTS);
7858            out.endDocument();
7859
7860            mGrantFile.finishWrite(fos);
7861        } catch (IOException e) {
7862            if (fos != null) {
7863                mGrantFile.failWrite(fos);
7864            }
7865        }
7866    }
7867
7868    private void readGrantedUriPermissionsLocked() {
7869        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7870
7871        final long now = System.currentTimeMillis();
7872
7873        FileInputStream fis = null;
7874        try {
7875            fis = mGrantFile.openRead();
7876            final XmlPullParser in = Xml.newPullParser();
7877            in.setInput(fis, null);
7878
7879            int type;
7880            while ((type = in.next()) != END_DOCUMENT) {
7881                final String tag = in.getName();
7882                if (type == START_TAG) {
7883                    if (TAG_URI_GRANT.equals(tag)) {
7884                        final int sourceUserId;
7885                        final int targetUserId;
7886                        final int userHandle = readIntAttribute(in,
7887                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7888                        if (userHandle != UserHandle.USER_NULL) {
7889                            // For backwards compatibility.
7890                            sourceUserId = userHandle;
7891                            targetUserId = userHandle;
7892                        } else {
7893                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7894                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7895                        }
7896                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7897                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7898                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7899                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7900                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7901                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7902
7903                        // Sanity check that provider still belongs to source package
7904                        final ProviderInfo pi = getProviderInfoLocked(
7905                                uri.getAuthority(), sourceUserId);
7906                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7907                            int targetUid = -1;
7908                            try {
7909                                targetUid = AppGlobals.getPackageManager()
7910                                        .getPackageUid(targetPkg, targetUserId);
7911                            } catch (RemoteException e) {
7912                            }
7913                            if (targetUid != -1) {
7914                                final UriPermission perm = findOrCreateUriPermissionLocked(
7915                                        sourcePkg, targetPkg, targetUid,
7916                                        new GrantUri(sourceUserId, uri, prefix));
7917                                perm.initPersistedModes(modeFlags, createdTime);
7918                            }
7919                        } else {
7920                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7921                                    + " but instead found " + pi);
7922                        }
7923                    }
7924                }
7925            }
7926        } catch (FileNotFoundException e) {
7927            // Missing grants is okay
7928        } catch (IOException e) {
7929            Slog.wtf(TAG, "Failed reading Uri grants", e);
7930        } catch (XmlPullParserException e) {
7931            Slog.wtf(TAG, "Failed reading Uri grants", e);
7932        } finally {
7933            IoUtils.closeQuietly(fis);
7934        }
7935    }
7936
7937    /**
7938     * @param uri This uri must NOT contain an embedded userId.
7939     * @param userId The userId in which the uri is to be resolved.
7940     */
7941    @Override
7942    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7943        enforceNotIsolatedCaller("takePersistableUriPermission");
7944
7945        Preconditions.checkFlagsArgument(modeFlags,
7946                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7947
7948        synchronized (this) {
7949            final int callingUid = Binder.getCallingUid();
7950            boolean persistChanged = false;
7951            GrantUri grantUri = new GrantUri(userId, uri, false);
7952
7953            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7954                    new GrantUri(userId, uri, false));
7955            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7956                    new GrantUri(userId, uri, true));
7957
7958            final boolean exactValid = (exactPerm != null)
7959                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7960            final boolean prefixValid = (prefixPerm != null)
7961                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7962
7963            if (!(exactValid || prefixValid)) {
7964                throw new SecurityException("No persistable permission grants found for UID "
7965                        + callingUid + " and Uri " + grantUri.toSafeString());
7966            }
7967
7968            if (exactValid) {
7969                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7970            }
7971            if (prefixValid) {
7972                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7973            }
7974
7975            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7976
7977            if (persistChanged) {
7978                schedulePersistUriGrants();
7979            }
7980        }
7981    }
7982
7983    /**
7984     * @param uri This uri must NOT contain an embedded userId.
7985     * @param userId The userId in which the uri is to be resolved.
7986     */
7987    @Override
7988    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7989        enforceNotIsolatedCaller("releasePersistableUriPermission");
7990
7991        Preconditions.checkFlagsArgument(modeFlags,
7992                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7993
7994        synchronized (this) {
7995            final int callingUid = Binder.getCallingUid();
7996            boolean persistChanged = false;
7997
7998            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7999                    new GrantUri(userId, uri, false));
8000            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8001                    new GrantUri(userId, uri, true));
8002            if (exactPerm == null && prefixPerm == null) {
8003                throw new SecurityException("No permission grants found for UID " + callingUid
8004                        + " and Uri " + uri.toSafeString());
8005            }
8006
8007            if (exactPerm != null) {
8008                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8009                removeUriPermissionIfNeededLocked(exactPerm);
8010            }
8011            if (prefixPerm != null) {
8012                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8013                removeUriPermissionIfNeededLocked(prefixPerm);
8014            }
8015
8016            if (persistChanged) {
8017                schedulePersistUriGrants();
8018            }
8019        }
8020    }
8021
8022    /**
8023     * Prune any older {@link UriPermission} for the given UID until outstanding
8024     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8025     *
8026     * @return if any mutations occured that require persisting.
8027     */
8028    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8029        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8030        if (perms == null) return false;
8031        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8032
8033        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8034        for (UriPermission perm : perms.values()) {
8035            if (perm.persistedModeFlags != 0) {
8036                persisted.add(perm);
8037            }
8038        }
8039
8040        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8041        if (trimCount <= 0) return false;
8042
8043        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8044        for (int i = 0; i < trimCount; i++) {
8045            final UriPermission perm = persisted.get(i);
8046
8047            if (DEBUG_URI_PERMISSION) {
8048                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8049            }
8050
8051            perm.releasePersistableModes(~0);
8052            removeUriPermissionIfNeededLocked(perm);
8053        }
8054
8055        return true;
8056    }
8057
8058    @Override
8059    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8060            String packageName, boolean incoming) {
8061        enforceNotIsolatedCaller("getPersistedUriPermissions");
8062        Preconditions.checkNotNull(packageName, "packageName");
8063
8064        final int callingUid = Binder.getCallingUid();
8065        final IPackageManager pm = AppGlobals.getPackageManager();
8066        try {
8067            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8068            if (packageUid != callingUid) {
8069                throw new SecurityException(
8070                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8071            }
8072        } catch (RemoteException e) {
8073            throw new SecurityException("Failed to verify package name ownership");
8074        }
8075
8076        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8077        synchronized (this) {
8078            if (incoming) {
8079                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8080                        callingUid);
8081                if (perms == null) {
8082                    Slog.w(TAG, "No permission grants found for " + packageName);
8083                } else {
8084                    for (UriPermission perm : perms.values()) {
8085                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8086                            result.add(perm.buildPersistedPublicApiObject());
8087                        }
8088                    }
8089                }
8090            } else {
8091                final int size = mGrantedUriPermissions.size();
8092                for (int i = 0; i < size; i++) {
8093                    final ArrayMap<GrantUri, UriPermission> perms =
8094                            mGrantedUriPermissions.valueAt(i);
8095                    for (UriPermission perm : perms.values()) {
8096                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8097                            result.add(perm.buildPersistedPublicApiObject());
8098                        }
8099                    }
8100                }
8101            }
8102        }
8103        return new ParceledListSlice<android.content.UriPermission>(result);
8104    }
8105
8106    @Override
8107    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8108        synchronized (this) {
8109            ProcessRecord app =
8110                who != null ? getRecordForAppLocked(who) : null;
8111            if (app == null) return;
8112
8113            Message msg = Message.obtain();
8114            msg.what = WAIT_FOR_DEBUGGER_MSG;
8115            msg.obj = app;
8116            msg.arg1 = waiting ? 1 : 0;
8117            mHandler.sendMessage(msg);
8118        }
8119    }
8120
8121    @Override
8122    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8123        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8124        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8125        outInfo.availMem = Process.getFreeMemory();
8126        outInfo.totalMem = Process.getTotalMemory();
8127        outInfo.threshold = homeAppMem;
8128        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8129        outInfo.hiddenAppThreshold = cachedAppMem;
8130        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8131                ProcessList.SERVICE_ADJ);
8132        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8133                ProcessList.VISIBLE_APP_ADJ);
8134        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8135                ProcessList.FOREGROUND_APP_ADJ);
8136    }
8137
8138    // =========================================================
8139    // TASK MANAGEMENT
8140    // =========================================================
8141
8142    @Override
8143    public List<IAppTask> getAppTasks(String callingPackage) {
8144        int callingUid = Binder.getCallingUid();
8145        long ident = Binder.clearCallingIdentity();
8146
8147        synchronized(this) {
8148            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8149            try {
8150                if (localLOGV) Slog.v(TAG, "getAppTasks");
8151
8152                final int N = mRecentTasks.size();
8153                for (int i = 0; i < N; i++) {
8154                    TaskRecord tr = mRecentTasks.get(i);
8155                    // Skip tasks that do not match the caller.  We don't need to verify
8156                    // callingPackage, because we are also limiting to callingUid and know
8157                    // that will limit to the correct security sandbox.
8158                    if (tr.effectiveUid != callingUid) {
8159                        continue;
8160                    }
8161                    Intent intent = tr.getBaseIntent();
8162                    if (intent == null ||
8163                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8164                        continue;
8165                    }
8166                    ActivityManager.RecentTaskInfo taskInfo =
8167                            createRecentTaskInfoFromTaskRecord(tr);
8168                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8169                    list.add(taskImpl);
8170                }
8171            } finally {
8172                Binder.restoreCallingIdentity(ident);
8173            }
8174            return list;
8175        }
8176    }
8177
8178    @Override
8179    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8180        final int callingUid = Binder.getCallingUid();
8181        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8182
8183        synchronized(this) {
8184            if (localLOGV) Slog.v(
8185                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8186
8187            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8188                    callingUid);
8189
8190            // TODO: Improve with MRU list from all ActivityStacks.
8191            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8192        }
8193
8194        return list;
8195    }
8196
8197    TaskRecord getMostRecentTask() {
8198        return mRecentTasks.get(0);
8199    }
8200
8201    /**
8202     * Creates a new RecentTaskInfo from a TaskRecord.
8203     */
8204    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8205        // Update the task description to reflect any changes in the task stack
8206        tr.updateTaskDescription();
8207
8208        // Compose the recent task info
8209        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8210        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8211        rti.persistentId = tr.taskId;
8212        rti.baseIntent = new Intent(tr.getBaseIntent());
8213        rti.origActivity = tr.origActivity;
8214        rti.description = tr.lastDescription;
8215        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8216        rti.userId = tr.userId;
8217        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8218        rti.firstActiveTime = tr.firstActiveTime;
8219        rti.lastActiveTime = tr.lastActiveTime;
8220        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8221        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8222        return rti;
8223    }
8224
8225    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8226        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8227                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8228        if (!allowed) {
8229            if (checkPermission(android.Manifest.permission.GET_TASKS,
8230                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8231                // Temporary compatibility: some existing apps on the system image may
8232                // still be requesting the old permission and not switched to the new
8233                // one; if so, we'll still allow them full access.  This means we need
8234                // to see if they are holding the old permission and are a system app.
8235                try {
8236                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8237                        allowed = true;
8238                        Slog.w(TAG, caller + ": caller " + callingUid
8239                                + " is using old GET_TASKS but privileged; allowing");
8240                    }
8241                } catch (RemoteException e) {
8242                }
8243            }
8244        }
8245        if (!allowed) {
8246            Slog.w(TAG, caller + ": caller " + callingUid
8247                    + " does not hold GET_TASKS; limiting output");
8248        }
8249        return allowed;
8250    }
8251
8252    @Override
8253    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8254        final int callingUid = Binder.getCallingUid();
8255        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8256                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8257
8258        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8259        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8260        synchronized (this) {
8261            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8262                    callingUid);
8263            final boolean detailed = checkCallingPermission(
8264                    android.Manifest.permission.GET_DETAILED_TASKS)
8265                    == PackageManager.PERMISSION_GRANTED;
8266
8267            final int N = mRecentTasks.size();
8268            ArrayList<ActivityManager.RecentTaskInfo> res
8269                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8270                            maxNum < N ? maxNum : N);
8271
8272            final Set<Integer> includedUsers;
8273            if (includeProfiles) {
8274                includedUsers = getProfileIdsLocked(userId);
8275            } else {
8276                includedUsers = new HashSet<Integer>();
8277            }
8278            includedUsers.add(Integer.valueOf(userId));
8279
8280            for (int i=0; i<N && maxNum > 0; i++) {
8281                TaskRecord tr = mRecentTasks.get(i);
8282                // Only add calling user or related users recent tasks
8283                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8284                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8285                    continue;
8286                }
8287
8288                // Return the entry if desired by the caller.  We always return
8289                // the first entry, because callers always expect this to be the
8290                // foreground app.  We may filter others if the caller has
8291                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8292                // we should exclude the entry.
8293
8294                if (i == 0
8295                        || withExcluded
8296                        || (tr.intent == null)
8297                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8298                                == 0)) {
8299                    if (!allowed) {
8300                        // If the caller doesn't have the GET_TASKS permission, then only
8301                        // allow them to see a small subset of tasks -- their own and home.
8302                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8303                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8304                            continue;
8305                        }
8306                    }
8307                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8308                        if (tr.stack != null && tr.stack.isHomeStack()) {
8309                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8310                            continue;
8311                        }
8312                    }
8313                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8314                        // Don't include auto remove tasks that are finished or finishing.
8315                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8316                                + tr);
8317                        continue;
8318                    }
8319                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8320                            && !tr.isAvailable) {
8321                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8322                        continue;
8323                    }
8324
8325                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8326                    if (!detailed) {
8327                        rti.baseIntent.replaceExtras((Bundle)null);
8328                    }
8329
8330                    res.add(rti);
8331                    maxNum--;
8332                }
8333            }
8334            return res;
8335        }
8336    }
8337
8338    private TaskRecord recentTaskForIdLocked(int id) {
8339        final int N = mRecentTasks.size();
8340            for (int i=0; i<N; i++) {
8341                TaskRecord tr = mRecentTasks.get(i);
8342                if (tr.taskId == id) {
8343                    return tr;
8344                }
8345            }
8346            return null;
8347    }
8348
8349    @Override
8350    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8351        synchronized (this) {
8352            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8353                    "getTaskThumbnail()");
8354            TaskRecord tr = recentTaskForIdLocked(id);
8355            if (tr != null) {
8356                return tr.getTaskThumbnailLocked();
8357            }
8358        }
8359        return null;
8360    }
8361
8362    @Override
8363    public int addAppTask(IBinder activityToken, Intent intent,
8364            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8365        final int callingUid = Binder.getCallingUid();
8366        final long callingIdent = Binder.clearCallingIdentity();
8367
8368        try {
8369            synchronized (this) {
8370                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8371                if (r == null) {
8372                    throw new IllegalArgumentException("Activity does not exist; token="
8373                            + activityToken);
8374                }
8375                ComponentName comp = intent.getComponent();
8376                if (comp == null) {
8377                    throw new IllegalArgumentException("Intent " + intent
8378                            + " must specify explicit component");
8379                }
8380                if (thumbnail.getWidth() != mThumbnailWidth
8381                        || thumbnail.getHeight() != mThumbnailHeight) {
8382                    throw new IllegalArgumentException("Bad thumbnail size: got "
8383                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8384                            + mThumbnailWidth + "x" + mThumbnailHeight);
8385                }
8386                if (intent.getSelector() != null) {
8387                    intent.setSelector(null);
8388                }
8389                if (intent.getSourceBounds() != null) {
8390                    intent.setSourceBounds(null);
8391                }
8392                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8393                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8394                        // The caller has added this as an auto-remove task...  that makes no
8395                        // sense, so turn off auto-remove.
8396                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8397                    }
8398                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8399                    // Must be a new task.
8400                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8401                }
8402                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8403                    mLastAddedTaskActivity = null;
8404                }
8405                ActivityInfo ainfo = mLastAddedTaskActivity;
8406                if (ainfo == null) {
8407                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8408                            comp, 0, UserHandle.getUserId(callingUid));
8409                    if (ainfo.applicationInfo.uid != callingUid) {
8410                        throw new SecurityException(
8411                                "Can't add task for another application: target uid="
8412                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8413                    }
8414                }
8415
8416                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8417                        intent, description);
8418
8419                int trimIdx = trimRecentsForTask(task, false);
8420                if (trimIdx >= 0) {
8421                    // If this would have caused a trim, then we'll abort because that
8422                    // means it would be added at the end of the list but then just removed.
8423                    return -1;
8424                }
8425
8426                final int N = mRecentTasks.size();
8427                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8428                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8429                    tr.removedFromRecents(mTaskPersister);
8430                }
8431
8432                task.inRecents = true;
8433                mRecentTasks.add(task);
8434                r.task.stack.addTask(task, false, false);
8435
8436                task.setLastThumbnail(thumbnail);
8437                task.freeLastThumbnail();
8438
8439                return task.taskId;
8440            }
8441        } finally {
8442            Binder.restoreCallingIdentity(callingIdent);
8443        }
8444    }
8445
8446    @Override
8447    public Point getAppTaskThumbnailSize() {
8448        synchronized (this) {
8449            return new Point(mThumbnailWidth,  mThumbnailHeight);
8450        }
8451    }
8452
8453    @Override
8454    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8455        synchronized (this) {
8456            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8457            if (r != null) {
8458                r.setTaskDescription(td);
8459                r.task.updateTaskDescription();
8460            }
8461        }
8462    }
8463
8464    @Override
8465    public Bitmap getTaskDescriptionIcon(String filename) {
8466        if (!FileUtils.isValidExtFilename(filename)
8467                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8468            throw new IllegalArgumentException("Bad filename: " + filename);
8469        }
8470        return mTaskPersister.getTaskDescriptionIcon(filename);
8471    }
8472
8473    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8474        mRecentTasks.remove(tr);
8475        tr.removedFromRecents(mTaskPersister);
8476        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8477        Intent baseIntent = new Intent(
8478                tr.intent != null ? tr.intent : tr.affinityIntent);
8479        ComponentName component = baseIntent.getComponent();
8480        if (component == null) {
8481            Slog.w(TAG, "Now component for base intent of task: " + tr);
8482            return;
8483        }
8484
8485        // Find any running services associated with this app.
8486        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8487
8488        if (killProcesses) {
8489            // Find any running processes associated with this app.
8490            final String pkg = component.getPackageName();
8491            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8492            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8493            for (int i=0; i<pmap.size(); i++) {
8494                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8495                for (int j=0; j<uids.size(); j++) {
8496                    ProcessRecord proc = uids.valueAt(j);
8497                    if (proc.userId != tr.userId) {
8498                        continue;
8499                    }
8500                    if (!proc.pkgList.containsKey(pkg)) {
8501                        continue;
8502                    }
8503                    procs.add(proc);
8504                }
8505            }
8506
8507            // Kill the running processes.
8508            for (int i=0; i<procs.size(); i++) {
8509                ProcessRecord pr = procs.get(i);
8510                if (pr == mHomeProcess) {
8511                    // Don't kill the home process along with tasks from the same package.
8512                    continue;
8513                }
8514                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8515                    pr.kill("remove task", true);
8516                } else {
8517                    pr.waitingToKill = "remove task";
8518                }
8519            }
8520        }
8521    }
8522
8523    /**
8524     * Removes the task with the specified task id.
8525     *
8526     * @param taskId Identifier of the task to be removed.
8527     * @param flags Additional operational flags.  May be 0 or
8528     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8529     * @return Returns true if the given task was found and removed.
8530     */
8531    private boolean removeTaskByIdLocked(int taskId, int flags) {
8532        TaskRecord tr = recentTaskForIdLocked(taskId);
8533        if (tr != null) {
8534            tr.removeTaskActivitiesLocked();
8535            cleanUpRemovedTaskLocked(tr, flags);
8536            if (tr.isPersistable) {
8537                notifyTaskPersisterLocked(null, true);
8538            }
8539            return true;
8540        }
8541        return false;
8542    }
8543
8544    @Override
8545    public boolean removeTask(int taskId, int flags) {
8546        synchronized (this) {
8547            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8548                    "removeTask()");
8549            long ident = Binder.clearCallingIdentity();
8550            try {
8551                return removeTaskByIdLocked(taskId, flags);
8552            } finally {
8553                Binder.restoreCallingIdentity(ident);
8554            }
8555        }
8556    }
8557
8558    /**
8559     * TODO: Add mController hook
8560     */
8561    @Override
8562    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8563        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8564                "moveTaskToFront()");
8565
8566        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8567        synchronized(this) {
8568            moveTaskToFrontLocked(taskId, flags, options);
8569        }
8570    }
8571
8572    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8573        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8574                Binder.getCallingUid(), -1, -1, "Task to front")) {
8575            ActivityOptions.abort(options);
8576            return;
8577        }
8578        final long origId = Binder.clearCallingIdentity();
8579        try {
8580            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8581            if (task == null) {
8582                return;
8583            }
8584            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8585                mStackSupervisor.showLockTaskToast();
8586                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8587                return;
8588            }
8589            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8590            if (prev != null && prev.isRecentsActivity()) {
8591                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8592            }
8593            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8594        } finally {
8595            Binder.restoreCallingIdentity(origId);
8596        }
8597        ActivityOptions.abort(options);
8598    }
8599
8600    @Override
8601    public void moveTaskToBack(int taskId) {
8602        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8603                "moveTaskToBack()");
8604
8605        synchronized(this) {
8606            TaskRecord tr = recentTaskForIdLocked(taskId);
8607            if (tr != null) {
8608                if (tr == mStackSupervisor.mLockTaskModeTask) {
8609                    mStackSupervisor.showLockTaskToast();
8610                    return;
8611                }
8612                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8613                ActivityStack stack = tr.stack;
8614                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8615                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8616                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8617                        return;
8618                    }
8619                }
8620                final long origId = Binder.clearCallingIdentity();
8621                try {
8622                    stack.moveTaskToBackLocked(taskId, null);
8623                } finally {
8624                    Binder.restoreCallingIdentity(origId);
8625                }
8626            }
8627        }
8628    }
8629
8630    /**
8631     * Moves an activity, and all of the other activities within the same task, to the bottom
8632     * of the history stack.  The activity's order within the task is unchanged.
8633     *
8634     * @param token A reference to the activity we wish to move
8635     * @param nonRoot If false then this only works if the activity is the root
8636     *                of a task; if true it will work for any activity in a task.
8637     * @return Returns true if the move completed, false if not.
8638     */
8639    @Override
8640    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8641        enforceNotIsolatedCaller("moveActivityTaskToBack");
8642        synchronized(this) {
8643            final long origId = Binder.clearCallingIdentity();
8644            try {
8645                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8646                if (taskId >= 0) {
8647                    if ((mStackSupervisor.mLockTaskModeTask != null)
8648                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8649                        mStackSupervisor.showLockTaskToast();
8650                        return false;
8651                    }
8652                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8653                }
8654            } finally {
8655                Binder.restoreCallingIdentity(origId);
8656            }
8657        }
8658        return false;
8659    }
8660
8661    @Override
8662    public void moveTaskBackwards(int task) {
8663        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8664                "moveTaskBackwards()");
8665
8666        synchronized(this) {
8667            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8668                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8669                return;
8670            }
8671            final long origId = Binder.clearCallingIdentity();
8672            moveTaskBackwardsLocked(task);
8673            Binder.restoreCallingIdentity(origId);
8674        }
8675    }
8676
8677    private final void moveTaskBackwardsLocked(int task) {
8678        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8679    }
8680
8681    @Override
8682    public IBinder getHomeActivityToken() throws RemoteException {
8683        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8684                "getHomeActivityToken()");
8685        synchronized (this) {
8686            return mStackSupervisor.getHomeActivityToken();
8687        }
8688    }
8689
8690    @Override
8691    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8692            IActivityContainerCallback callback) throws RemoteException {
8693        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8694                "createActivityContainer()");
8695        synchronized (this) {
8696            if (parentActivityToken == null) {
8697                throw new IllegalArgumentException("parent token must not be null");
8698            }
8699            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8700            if (r == null) {
8701                return null;
8702            }
8703            if (callback == null) {
8704                throw new IllegalArgumentException("callback must not be null");
8705            }
8706            return mStackSupervisor.createActivityContainer(r, callback);
8707        }
8708    }
8709
8710    @Override
8711    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8712        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8713                "deleteActivityContainer()");
8714        synchronized (this) {
8715            mStackSupervisor.deleteActivityContainer(container);
8716        }
8717    }
8718
8719    @Override
8720    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8721            throws RemoteException {
8722        synchronized (this) {
8723            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8724            if (stack != null) {
8725                return stack.mActivityContainer;
8726            }
8727            return null;
8728        }
8729    }
8730
8731    @Override
8732    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8733        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8734                "moveTaskToStack()");
8735        if (stackId == HOME_STACK_ID) {
8736            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8737                    new RuntimeException("here").fillInStackTrace());
8738        }
8739        synchronized (this) {
8740            long ident = Binder.clearCallingIdentity();
8741            try {
8742                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8743                        + stackId + " toTop=" + toTop);
8744                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8745            } finally {
8746                Binder.restoreCallingIdentity(ident);
8747            }
8748        }
8749    }
8750
8751    @Override
8752    public void resizeStack(int stackBoxId, Rect bounds) {
8753        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8754                "resizeStackBox()");
8755        long ident = Binder.clearCallingIdentity();
8756        try {
8757            mWindowManager.resizeStack(stackBoxId, bounds);
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761    }
8762
8763    @Override
8764    public List<StackInfo> getAllStackInfos() {
8765        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8766                "getAllStackInfos()");
8767        long ident = Binder.clearCallingIdentity();
8768        try {
8769            synchronized (this) {
8770                return mStackSupervisor.getAllStackInfosLocked();
8771            }
8772        } finally {
8773            Binder.restoreCallingIdentity(ident);
8774        }
8775    }
8776
8777    @Override
8778    public StackInfo getStackInfo(int stackId) {
8779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8780                "getStackInfo()");
8781        long ident = Binder.clearCallingIdentity();
8782        try {
8783            synchronized (this) {
8784                return mStackSupervisor.getStackInfoLocked(stackId);
8785            }
8786        } finally {
8787            Binder.restoreCallingIdentity(ident);
8788        }
8789    }
8790
8791    @Override
8792    public boolean isInHomeStack(int taskId) {
8793        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8794                "getStackInfo()");
8795        long ident = Binder.clearCallingIdentity();
8796        try {
8797            synchronized (this) {
8798                TaskRecord tr = recentTaskForIdLocked(taskId);
8799                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8800            }
8801        } finally {
8802            Binder.restoreCallingIdentity(ident);
8803        }
8804    }
8805
8806    @Override
8807    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8808        synchronized(this) {
8809            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8810        }
8811    }
8812
8813    private boolean isLockTaskAuthorized(String pkg) {
8814        final DevicePolicyManager dpm = (DevicePolicyManager)
8815                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8816        try {
8817            int uid = mContext.getPackageManager().getPackageUid(pkg,
8818                    Binder.getCallingUserHandle().getIdentifier());
8819            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8820        } catch (NameNotFoundException e) {
8821            return false;
8822        }
8823    }
8824
8825    void startLockTaskMode(TaskRecord task) {
8826        final String pkg;
8827        synchronized (this) {
8828            pkg = task.intent.getComponent().getPackageName();
8829        }
8830        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8831        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8832            final TaskRecord taskRecord = task;
8833            mHandler.post(new Runnable() {
8834                @Override
8835                public void run() {
8836                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8837                }
8838            });
8839            return;
8840        }
8841        long ident = Binder.clearCallingIdentity();
8842        try {
8843            synchronized (this) {
8844                // Since we lost lock on task, make sure it is still there.
8845                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8846                if (task != null) {
8847                    if (!isSystemInitiated
8848                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8849                        throw new IllegalArgumentException("Invalid task, not in foreground");
8850                    }
8851                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8852                }
8853            }
8854        } finally {
8855            Binder.restoreCallingIdentity(ident);
8856        }
8857    }
8858
8859    @Override
8860    public void startLockTaskMode(int taskId) {
8861        final TaskRecord task;
8862        long ident = Binder.clearCallingIdentity();
8863        try {
8864            synchronized (this) {
8865                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8866            }
8867        } finally {
8868            Binder.restoreCallingIdentity(ident);
8869        }
8870        if (task != null) {
8871            startLockTaskMode(task);
8872        }
8873    }
8874
8875    @Override
8876    public void startLockTaskMode(IBinder token) {
8877        final TaskRecord task;
8878        long ident = Binder.clearCallingIdentity();
8879        try {
8880            synchronized (this) {
8881                final ActivityRecord r = ActivityRecord.forToken(token);
8882                if (r == null) {
8883                    return;
8884                }
8885                task = r.task;
8886            }
8887        } finally {
8888            Binder.restoreCallingIdentity(ident);
8889        }
8890        if (task != null) {
8891            startLockTaskMode(task);
8892        }
8893    }
8894
8895    @Override
8896    public void startLockTaskModeOnCurrent() throws RemoteException {
8897        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8898                "startLockTaskModeOnCurrent");
8899        ActivityRecord r = null;
8900        synchronized (this) {
8901            r = mStackSupervisor.topRunningActivityLocked();
8902        }
8903        startLockTaskMode(r.task);
8904    }
8905
8906    @Override
8907    public void stopLockTaskMode() {
8908        // Verify that the user matches the package of the intent for the TaskRecord
8909        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8910        // and stopLockTaskMode.
8911        final int callingUid = Binder.getCallingUid();
8912        if (callingUid != Process.SYSTEM_UID) {
8913            try {
8914                String pkg =
8915                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8916                int uid = mContext.getPackageManager().getPackageUid(pkg,
8917                        Binder.getCallingUserHandle().getIdentifier());
8918                if (uid != callingUid) {
8919                    throw new SecurityException("Invalid uid, expected " + uid);
8920                }
8921            } catch (NameNotFoundException e) {
8922                Log.d(TAG, "stopLockTaskMode " + e);
8923                return;
8924            }
8925        }
8926        long ident = Binder.clearCallingIdentity();
8927        try {
8928            Log.d(TAG, "stopLockTaskMode");
8929            // Stop lock task
8930            synchronized (this) {
8931                mStackSupervisor.setLockTaskModeLocked(null, false);
8932            }
8933        } finally {
8934            Binder.restoreCallingIdentity(ident);
8935        }
8936    }
8937
8938    @Override
8939    public void stopLockTaskModeOnCurrent() throws RemoteException {
8940        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8941                "stopLockTaskModeOnCurrent");
8942        long ident = Binder.clearCallingIdentity();
8943        try {
8944            stopLockTaskMode();
8945        } finally {
8946            Binder.restoreCallingIdentity(ident);
8947        }
8948    }
8949
8950    @Override
8951    public boolean isInLockTaskMode() {
8952        synchronized (this) {
8953            return mStackSupervisor.isInLockTaskMode();
8954        }
8955    }
8956
8957    // =========================================================
8958    // CONTENT PROVIDERS
8959    // =========================================================
8960
8961    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8962        List<ProviderInfo> providers = null;
8963        try {
8964            providers = AppGlobals.getPackageManager().
8965                queryContentProviders(app.processName, app.uid,
8966                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8967        } catch (RemoteException ex) {
8968        }
8969        if (DEBUG_MU)
8970            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8971        int userId = app.userId;
8972        if (providers != null) {
8973            int N = providers.size();
8974            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8975            for (int i=0; i<N; i++) {
8976                ProviderInfo cpi =
8977                    (ProviderInfo)providers.get(i);
8978                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8979                        cpi.name, cpi.flags);
8980                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8981                    // This is a singleton provider, but a user besides the
8982                    // default user is asking to initialize a process it runs
8983                    // in...  well, no, it doesn't actually run in this process,
8984                    // it runs in the process of the default user.  Get rid of it.
8985                    providers.remove(i);
8986                    N--;
8987                    i--;
8988                    continue;
8989                }
8990
8991                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8992                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8993                if (cpr == null) {
8994                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8995                    mProviderMap.putProviderByClass(comp, cpr);
8996                }
8997                if (DEBUG_MU)
8998                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8999                app.pubProviders.put(cpi.name, cpr);
9000                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9001                    // Don't add this if it is a platform component that is marked
9002                    // to run in multiple processes, because this is actually
9003                    // part of the framework so doesn't make sense to track as a
9004                    // separate apk in the process.
9005                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9006                            mProcessStats);
9007                }
9008                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9009            }
9010        }
9011        return providers;
9012    }
9013
9014    /**
9015     * Check if {@link ProcessRecord} has a possible chance at accessing the
9016     * given {@link ProviderInfo}. Final permission checking is always done
9017     * in {@link ContentProvider}.
9018     */
9019    private final String checkContentProviderPermissionLocked(
9020            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9021        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9022        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9023        boolean checkedGrants = false;
9024        if (checkUser) {
9025            // Looking for cross-user grants before enforcing the typical cross-users permissions
9026            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9027            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9028                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9029                    return null;
9030                }
9031                checkedGrants = true;
9032            }
9033            userId = handleIncomingUser(callingPid, callingUid, userId,
9034                    false, ALLOW_NON_FULL,
9035                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9036            if (userId != tmpTargetUserId) {
9037                // When we actually went to determine the final targer user ID, this ended
9038                // up different than our initial check for the authority.  This is because
9039                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9040                // SELF.  So we need to re-check the grants again.
9041                checkedGrants = false;
9042            }
9043        }
9044        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9045                cpi.applicationInfo.uid, cpi.exported)
9046                == PackageManager.PERMISSION_GRANTED) {
9047            return null;
9048        }
9049        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9050                cpi.applicationInfo.uid, cpi.exported)
9051                == PackageManager.PERMISSION_GRANTED) {
9052            return null;
9053        }
9054
9055        PathPermission[] pps = cpi.pathPermissions;
9056        if (pps != null) {
9057            int i = pps.length;
9058            while (i > 0) {
9059                i--;
9060                PathPermission pp = pps[i];
9061                String pprperm = pp.getReadPermission();
9062                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9063                        cpi.applicationInfo.uid, cpi.exported)
9064                        == PackageManager.PERMISSION_GRANTED) {
9065                    return null;
9066                }
9067                String ppwperm = pp.getWritePermission();
9068                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9069                        cpi.applicationInfo.uid, cpi.exported)
9070                        == PackageManager.PERMISSION_GRANTED) {
9071                    return null;
9072                }
9073            }
9074        }
9075        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9076            return null;
9077        }
9078
9079        String msg;
9080        if (!cpi.exported) {
9081            msg = "Permission Denial: opening provider " + cpi.name
9082                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9083                    + ", uid=" + callingUid + ") that is not exported from uid "
9084                    + cpi.applicationInfo.uid;
9085        } else {
9086            msg = "Permission Denial: opening provider " + cpi.name
9087                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9088                    + ", uid=" + callingUid + ") requires "
9089                    + cpi.readPermission + " or " + cpi.writePermission;
9090        }
9091        Slog.w(TAG, msg);
9092        return msg;
9093    }
9094
9095    /**
9096     * Returns if the ContentProvider has granted a uri to callingUid
9097     */
9098    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9099        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9100        if (perms != null) {
9101            for (int i=perms.size()-1; i>=0; i--) {
9102                GrantUri grantUri = perms.keyAt(i);
9103                if (grantUri.sourceUserId == userId || !checkUser) {
9104                    if (matchesProvider(grantUri.uri, cpi)) {
9105                        return true;
9106                    }
9107                }
9108            }
9109        }
9110        return false;
9111    }
9112
9113    /**
9114     * Returns true if the uri authority is one of the authorities specified in the provider.
9115     */
9116    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9117        String uriAuth = uri.getAuthority();
9118        String cpiAuth = cpi.authority;
9119        if (cpiAuth.indexOf(';') == -1) {
9120            return cpiAuth.equals(uriAuth);
9121        }
9122        String[] cpiAuths = cpiAuth.split(";");
9123        int length = cpiAuths.length;
9124        for (int i = 0; i < length; i++) {
9125            if (cpiAuths[i].equals(uriAuth)) return true;
9126        }
9127        return false;
9128    }
9129
9130    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9131            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9132        if (r != null) {
9133            for (int i=0; i<r.conProviders.size(); i++) {
9134                ContentProviderConnection conn = r.conProviders.get(i);
9135                if (conn.provider == cpr) {
9136                    if (DEBUG_PROVIDER) Slog.v(TAG,
9137                            "Adding provider requested by "
9138                            + r.processName + " from process "
9139                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9140                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9141                    if (stable) {
9142                        conn.stableCount++;
9143                        conn.numStableIncs++;
9144                    } else {
9145                        conn.unstableCount++;
9146                        conn.numUnstableIncs++;
9147                    }
9148                    return conn;
9149                }
9150            }
9151            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9152            if (stable) {
9153                conn.stableCount = 1;
9154                conn.numStableIncs = 1;
9155            } else {
9156                conn.unstableCount = 1;
9157                conn.numUnstableIncs = 1;
9158            }
9159            cpr.connections.add(conn);
9160            r.conProviders.add(conn);
9161            return conn;
9162        }
9163        cpr.addExternalProcessHandleLocked(externalProcessToken);
9164        return null;
9165    }
9166
9167    boolean decProviderCountLocked(ContentProviderConnection conn,
9168            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9169        if (conn != null) {
9170            cpr = conn.provider;
9171            if (DEBUG_PROVIDER) Slog.v(TAG,
9172                    "Removing provider requested by "
9173                    + conn.client.processName + " from process "
9174                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9175                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9176            if (stable) {
9177                conn.stableCount--;
9178            } else {
9179                conn.unstableCount--;
9180            }
9181            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9182                cpr.connections.remove(conn);
9183                conn.client.conProviders.remove(conn);
9184                return true;
9185            }
9186            return false;
9187        }
9188        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9189        return false;
9190    }
9191
9192    private void checkTime(long startTime, String where) {
9193        long now = SystemClock.elapsedRealtime();
9194        if ((now-startTime) > 1000) {
9195            // If we are taking more than a second, log about it.
9196            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9197        }
9198    }
9199
9200    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9201            String name, IBinder token, boolean stable, int userId) {
9202        ContentProviderRecord cpr;
9203        ContentProviderConnection conn = null;
9204        ProviderInfo cpi = null;
9205
9206        synchronized(this) {
9207            long startTime = SystemClock.elapsedRealtime();
9208
9209            ProcessRecord r = null;
9210            if (caller != null) {
9211                r = getRecordForAppLocked(caller);
9212                if (r == null) {
9213                    throw new SecurityException(
9214                            "Unable to find app for caller " + caller
9215                          + " (pid=" + Binder.getCallingPid()
9216                          + ") when getting content provider " + name);
9217                }
9218            }
9219
9220            boolean checkCrossUser = true;
9221
9222            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9223
9224            // First check if this content provider has been published...
9225            cpr = mProviderMap.getProviderByName(name, userId);
9226            // If that didn't work, check if it exists for user 0 and then
9227            // verify that it's a singleton provider before using it.
9228            if (cpr == null && userId != UserHandle.USER_OWNER) {
9229                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9230                if (cpr != null) {
9231                    cpi = cpr.info;
9232                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9233                            cpi.name, cpi.flags)
9234                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9235                        userId = UserHandle.USER_OWNER;
9236                        checkCrossUser = false;
9237                    } else {
9238                        cpr = null;
9239                        cpi = null;
9240                    }
9241                }
9242            }
9243
9244            boolean providerRunning = cpr != null;
9245            if (providerRunning) {
9246                cpi = cpr.info;
9247                String msg;
9248                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9249                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9250                        != null) {
9251                    throw new SecurityException(msg);
9252                }
9253                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9254
9255                if (r != null && cpr.canRunHere(r)) {
9256                    // This provider has been published or is in the process
9257                    // of being published...  but it is also allowed to run
9258                    // in the caller's process, so don't make a connection
9259                    // and just let the caller instantiate its own instance.
9260                    ContentProviderHolder holder = cpr.newHolder(null);
9261                    // don't give caller the provider object, it needs
9262                    // to make its own.
9263                    holder.provider = null;
9264                    return holder;
9265                }
9266
9267                final long origId = Binder.clearCallingIdentity();
9268
9269                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9270
9271                // In this case the provider instance already exists, so we can
9272                // return it right away.
9273                conn = incProviderCountLocked(r, cpr, token, stable);
9274                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9275                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9276                        // If this is a perceptible app accessing the provider,
9277                        // make sure to count it as being accessed and thus
9278                        // back up on the LRU list.  This is good because
9279                        // content providers are often expensive to start.
9280                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9281                        updateLruProcessLocked(cpr.proc, false, null);
9282                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9283                    }
9284                }
9285
9286                if (cpr.proc != null) {
9287                    if (false) {
9288                        if (cpr.name.flattenToShortString().equals(
9289                                "com.android.providers.calendar/.CalendarProvider2")) {
9290                            Slog.v(TAG, "****************** KILLING "
9291                                + cpr.name.flattenToShortString());
9292                            Process.killProcess(cpr.proc.pid);
9293                        }
9294                    }
9295                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9296                    boolean success = updateOomAdjLocked(cpr.proc);
9297                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9298                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9299                    // NOTE: there is still a race here where a signal could be
9300                    // pending on the process even though we managed to update its
9301                    // adj level.  Not sure what to do about this, but at least
9302                    // the race is now smaller.
9303                    if (!success) {
9304                        // Uh oh...  it looks like the provider's process
9305                        // has been killed on us.  We need to wait for a new
9306                        // process to be started, and make sure its death
9307                        // doesn't kill our process.
9308                        Slog.i(TAG,
9309                                "Existing provider " + cpr.name.flattenToShortString()
9310                                + " is crashing; detaching " + r);
9311                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9312                        checkTime(startTime, "getContentProviderImpl: before appDied");
9313                        appDiedLocked(cpr.proc);
9314                        checkTime(startTime, "getContentProviderImpl: after appDied");
9315                        if (!lastRef) {
9316                            // This wasn't the last ref our process had on
9317                            // the provider...  we have now been killed, bail.
9318                            return null;
9319                        }
9320                        providerRunning = false;
9321                        conn = null;
9322                    }
9323                }
9324
9325                Binder.restoreCallingIdentity(origId);
9326            }
9327
9328            boolean singleton;
9329            if (!providerRunning) {
9330                try {
9331                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9332                    cpi = AppGlobals.getPackageManager().
9333                        resolveContentProvider(name,
9334                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9335                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9336                } catch (RemoteException ex) {
9337                }
9338                if (cpi == null) {
9339                    return null;
9340                }
9341                // If the provider is a singleton AND
9342                // (it's a call within the same user || the provider is a
9343                // privileged app)
9344                // Then allow connecting to the singleton provider
9345                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9346                        cpi.name, cpi.flags)
9347                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9348                if (singleton) {
9349                    userId = UserHandle.USER_OWNER;
9350                }
9351                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9352                checkTime(startTime, "getContentProviderImpl: got app info for user");
9353
9354                String msg;
9355                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9356                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9357                        != null) {
9358                    throw new SecurityException(msg);
9359                }
9360                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9361
9362                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9363                        && !cpi.processName.equals("system")) {
9364                    // If this content provider does not run in the system
9365                    // process, and the system is not yet ready to run other
9366                    // processes, then fail fast instead of hanging.
9367                    throw new IllegalArgumentException(
9368                            "Attempt to launch content provider before system ready");
9369                }
9370
9371                // Make sure that the user who owns this provider is started.  If not,
9372                // we don't want to allow it to run.
9373                if (mStartedUsers.get(userId) == null) {
9374                    Slog.w(TAG, "Unable to launch app "
9375                            + cpi.applicationInfo.packageName + "/"
9376                            + cpi.applicationInfo.uid + " for provider "
9377                            + name + ": user " + userId + " is stopped");
9378                    return null;
9379                }
9380
9381                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9382                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9383                cpr = mProviderMap.getProviderByClass(comp, userId);
9384                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9385                final boolean firstClass = cpr == null;
9386                if (firstClass) {
9387                    final long ident = Binder.clearCallingIdentity();
9388                    try {
9389                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9390                        ApplicationInfo ai =
9391                            AppGlobals.getPackageManager().
9392                                getApplicationInfo(
9393                                        cpi.applicationInfo.packageName,
9394                                        STOCK_PM_FLAGS, userId);
9395                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9396                        if (ai == null) {
9397                            Slog.w(TAG, "No package info for content provider "
9398                                    + cpi.name);
9399                            return null;
9400                        }
9401                        ai = getAppInfoForUser(ai, userId);
9402                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9403                    } catch (RemoteException ex) {
9404                        // pm is in same process, this will never happen.
9405                    } finally {
9406                        Binder.restoreCallingIdentity(ident);
9407                    }
9408                }
9409
9410                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9411
9412                if (r != null && cpr.canRunHere(r)) {
9413                    // If this is a multiprocess provider, then just return its
9414                    // info and allow the caller to instantiate it.  Only do
9415                    // this if the provider is the same user as the caller's
9416                    // process, or can run as root (so can be in any process).
9417                    return cpr.newHolder(null);
9418                }
9419
9420                if (DEBUG_PROVIDER) {
9421                    RuntimeException e = new RuntimeException("here");
9422                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9423                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9424                }
9425
9426                // This is single process, and our app is now connecting to it.
9427                // See if we are already in the process of launching this
9428                // provider.
9429                final int N = mLaunchingProviders.size();
9430                int i;
9431                for (i=0; i<N; i++) {
9432                    if (mLaunchingProviders.get(i) == cpr) {
9433                        break;
9434                    }
9435                }
9436
9437                // If the provider is not already being launched, then get it
9438                // started.
9439                if (i >= N) {
9440                    final long origId = Binder.clearCallingIdentity();
9441
9442                    try {
9443                        // Content provider is now in use, its package can't be stopped.
9444                        try {
9445                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9446                            AppGlobals.getPackageManager().setPackageStoppedState(
9447                                    cpr.appInfo.packageName, false, userId);
9448                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9449                        } catch (RemoteException e) {
9450                        } catch (IllegalArgumentException e) {
9451                            Slog.w(TAG, "Failed trying to unstop package "
9452                                    + cpr.appInfo.packageName + ": " + e);
9453                        }
9454
9455                        // Use existing process if already started
9456                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9457                        ProcessRecord proc = getProcessRecordLocked(
9458                                cpi.processName, cpr.appInfo.uid, false);
9459                        if (proc != null && proc.thread != null) {
9460                            if (DEBUG_PROVIDER) {
9461                                Slog.d(TAG, "Installing in existing process " + proc);
9462                            }
9463                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9464                            proc.pubProviders.put(cpi.name, cpr);
9465                            try {
9466                                proc.thread.scheduleInstallProvider(cpi);
9467                            } catch (RemoteException e) {
9468                            }
9469                        } else {
9470                            checkTime(startTime, "getContentProviderImpl: before start process");
9471                            proc = startProcessLocked(cpi.processName,
9472                                    cpr.appInfo, false, 0, "content provider",
9473                                    new ComponentName(cpi.applicationInfo.packageName,
9474                                            cpi.name), false, false, false);
9475                            checkTime(startTime, "getContentProviderImpl: after start process");
9476                            if (proc == null) {
9477                                Slog.w(TAG, "Unable to launch app "
9478                                        + cpi.applicationInfo.packageName + "/"
9479                                        + cpi.applicationInfo.uid + " for provider "
9480                                        + name + ": process is bad");
9481                                return null;
9482                            }
9483                        }
9484                        cpr.launchingApp = proc;
9485                        mLaunchingProviders.add(cpr);
9486                    } finally {
9487                        Binder.restoreCallingIdentity(origId);
9488                    }
9489                }
9490
9491                checkTime(startTime, "getContentProviderImpl: updating data structures");
9492
9493                // Make sure the provider is published (the same provider class
9494                // may be published under multiple names).
9495                if (firstClass) {
9496                    mProviderMap.putProviderByClass(comp, cpr);
9497                }
9498
9499                mProviderMap.putProviderByName(name, cpr);
9500                conn = incProviderCountLocked(r, cpr, token, stable);
9501                if (conn != null) {
9502                    conn.waiting = true;
9503                }
9504            }
9505            checkTime(startTime, "getContentProviderImpl: done!");
9506        }
9507
9508        // Wait for the provider to be published...
9509        synchronized (cpr) {
9510            while (cpr.provider == null) {
9511                if (cpr.launchingApp == null) {
9512                    Slog.w(TAG, "Unable to launch app "
9513                            + cpi.applicationInfo.packageName + "/"
9514                            + cpi.applicationInfo.uid + " for provider "
9515                            + name + ": launching app became null");
9516                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9517                            UserHandle.getUserId(cpi.applicationInfo.uid),
9518                            cpi.applicationInfo.packageName,
9519                            cpi.applicationInfo.uid, name);
9520                    return null;
9521                }
9522                try {
9523                    if (DEBUG_MU) {
9524                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9525                                + cpr.launchingApp);
9526                    }
9527                    if (conn != null) {
9528                        conn.waiting = true;
9529                    }
9530                    cpr.wait();
9531                } catch (InterruptedException ex) {
9532                } finally {
9533                    if (conn != null) {
9534                        conn.waiting = false;
9535                    }
9536                }
9537            }
9538        }
9539        return cpr != null ? cpr.newHolder(conn) : null;
9540    }
9541
9542    @Override
9543    public final ContentProviderHolder getContentProvider(
9544            IApplicationThread caller, String name, int userId, boolean stable) {
9545        enforceNotIsolatedCaller("getContentProvider");
9546        if (caller == null) {
9547            String msg = "null IApplicationThread when getting content provider "
9548                    + name;
9549            Slog.w(TAG, msg);
9550            throw new SecurityException(msg);
9551        }
9552        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9553        // with cross-user grant.
9554        return getContentProviderImpl(caller, name, null, stable, userId);
9555    }
9556
9557    public ContentProviderHolder getContentProviderExternal(
9558            String name, int userId, IBinder token) {
9559        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9560            "Do not have permission in call getContentProviderExternal()");
9561        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9562                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9563        return getContentProviderExternalUnchecked(name, token, userId);
9564    }
9565
9566    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9567            IBinder token, int userId) {
9568        return getContentProviderImpl(null, name, token, true, userId);
9569    }
9570
9571    /**
9572     * Drop a content provider from a ProcessRecord's bookkeeping
9573     */
9574    public void removeContentProvider(IBinder connection, boolean stable) {
9575        enforceNotIsolatedCaller("removeContentProvider");
9576        long ident = Binder.clearCallingIdentity();
9577        try {
9578            synchronized (this) {
9579                ContentProviderConnection conn;
9580                try {
9581                    conn = (ContentProviderConnection)connection;
9582                } catch (ClassCastException e) {
9583                    String msg ="removeContentProvider: " + connection
9584                            + " not a ContentProviderConnection";
9585                    Slog.w(TAG, msg);
9586                    throw new IllegalArgumentException(msg);
9587                }
9588                if (conn == null) {
9589                    throw new NullPointerException("connection is null");
9590                }
9591                if (decProviderCountLocked(conn, null, null, stable)) {
9592                    updateOomAdjLocked();
9593                }
9594            }
9595        } finally {
9596            Binder.restoreCallingIdentity(ident);
9597        }
9598    }
9599
9600    public void removeContentProviderExternal(String name, IBinder token) {
9601        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9602            "Do not have permission in call removeContentProviderExternal()");
9603        int userId = UserHandle.getCallingUserId();
9604        long ident = Binder.clearCallingIdentity();
9605        try {
9606            removeContentProviderExternalUnchecked(name, token, userId);
9607        } finally {
9608            Binder.restoreCallingIdentity(ident);
9609        }
9610    }
9611
9612    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9613        synchronized (this) {
9614            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9615            if(cpr == null) {
9616                //remove from mProvidersByClass
9617                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9618                return;
9619            }
9620
9621            //update content provider record entry info
9622            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9623            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9624            if (localCpr.hasExternalProcessHandles()) {
9625                if (localCpr.removeExternalProcessHandleLocked(token)) {
9626                    updateOomAdjLocked();
9627                } else {
9628                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9629                            + " with no external reference for token: "
9630                            + token + ".");
9631                }
9632            } else {
9633                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9634                        + " with no external references.");
9635            }
9636        }
9637    }
9638
9639    public final void publishContentProviders(IApplicationThread caller,
9640            List<ContentProviderHolder> providers) {
9641        if (providers == null) {
9642            return;
9643        }
9644
9645        enforceNotIsolatedCaller("publishContentProviders");
9646        synchronized (this) {
9647            final ProcessRecord r = getRecordForAppLocked(caller);
9648            if (DEBUG_MU)
9649                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9650            if (r == null) {
9651                throw new SecurityException(
9652                        "Unable to find app for caller " + caller
9653                      + " (pid=" + Binder.getCallingPid()
9654                      + ") when publishing content providers");
9655            }
9656
9657            final long origId = Binder.clearCallingIdentity();
9658
9659            final int N = providers.size();
9660            for (int i=0; i<N; i++) {
9661                ContentProviderHolder src = providers.get(i);
9662                if (src == null || src.info == null || src.provider == null) {
9663                    continue;
9664                }
9665                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9666                if (DEBUG_MU)
9667                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9668                if (dst != null) {
9669                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9670                    mProviderMap.putProviderByClass(comp, dst);
9671                    String names[] = dst.info.authority.split(";");
9672                    for (int j = 0; j < names.length; j++) {
9673                        mProviderMap.putProviderByName(names[j], dst);
9674                    }
9675
9676                    int NL = mLaunchingProviders.size();
9677                    int j;
9678                    for (j=0; j<NL; j++) {
9679                        if (mLaunchingProviders.get(j) == dst) {
9680                            mLaunchingProviders.remove(j);
9681                            j--;
9682                            NL--;
9683                        }
9684                    }
9685                    synchronized (dst) {
9686                        dst.provider = src.provider;
9687                        dst.proc = r;
9688                        dst.notifyAll();
9689                    }
9690                    updateOomAdjLocked(r);
9691                }
9692            }
9693
9694            Binder.restoreCallingIdentity(origId);
9695        }
9696    }
9697
9698    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9699        ContentProviderConnection conn;
9700        try {
9701            conn = (ContentProviderConnection)connection;
9702        } catch (ClassCastException e) {
9703            String msg ="refContentProvider: " + connection
9704                    + " not a ContentProviderConnection";
9705            Slog.w(TAG, msg);
9706            throw new IllegalArgumentException(msg);
9707        }
9708        if (conn == null) {
9709            throw new NullPointerException("connection is null");
9710        }
9711
9712        synchronized (this) {
9713            if (stable > 0) {
9714                conn.numStableIncs += stable;
9715            }
9716            stable = conn.stableCount + stable;
9717            if (stable < 0) {
9718                throw new IllegalStateException("stableCount < 0: " + stable);
9719            }
9720
9721            if (unstable > 0) {
9722                conn.numUnstableIncs += unstable;
9723            }
9724            unstable = conn.unstableCount + unstable;
9725            if (unstable < 0) {
9726                throw new IllegalStateException("unstableCount < 0: " + unstable);
9727            }
9728
9729            if ((stable+unstable) <= 0) {
9730                throw new IllegalStateException("ref counts can't go to zero here: stable="
9731                        + stable + " unstable=" + unstable);
9732            }
9733            conn.stableCount = stable;
9734            conn.unstableCount = unstable;
9735            return !conn.dead;
9736        }
9737    }
9738
9739    public void unstableProviderDied(IBinder connection) {
9740        ContentProviderConnection conn;
9741        try {
9742            conn = (ContentProviderConnection)connection;
9743        } catch (ClassCastException e) {
9744            String msg ="refContentProvider: " + connection
9745                    + " not a ContentProviderConnection";
9746            Slog.w(TAG, msg);
9747            throw new IllegalArgumentException(msg);
9748        }
9749        if (conn == null) {
9750            throw new NullPointerException("connection is null");
9751        }
9752
9753        // Safely retrieve the content provider associated with the connection.
9754        IContentProvider provider;
9755        synchronized (this) {
9756            provider = conn.provider.provider;
9757        }
9758
9759        if (provider == null) {
9760            // Um, yeah, we're way ahead of you.
9761            return;
9762        }
9763
9764        // Make sure the caller is being honest with us.
9765        if (provider.asBinder().pingBinder()) {
9766            // Er, no, still looks good to us.
9767            synchronized (this) {
9768                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9769                        + " says " + conn + " died, but we don't agree");
9770                return;
9771            }
9772        }
9773
9774        // Well look at that!  It's dead!
9775        synchronized (this) {
9776            if (conn.provider.provider != provider) {
9777                // But something changed...  good enough.
9778                return;
9779            }
9780
9781            ProcessRecord proc = conn.provider.proc;
9782            if (proc == null || proc.thread == null) {
9783                // Seems like the process is already cleaned up.
9784                return;
9785            }
9786
9787            // As far as we're concerned, this is just like receiving a
9788            // death notification...  just a bit prematurely.
9789            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9790                    + ") early provider death");
9791            final long ident = Binder.clearCallingIdentity();
9792            try {
9793                appDiedLocked(proc);
9794            } finally {
9795                Binder.restoreCallingIdentity(ident);
9796            }
9797        }
9798    }
9799
9800    @Override
9801    public void appNotRespondingViaProvider(IBinder connection) {
9802        enforceCallingPermission(
9803                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9804
9805        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9806        if (conn == null) {
9807            Slog.w(TAG, "ContentProviderConnection is null");
9808            return;
9809        }
9810
9811        final ProcessRecord host = conn.provider.proc;
9812        if (host == null) {
9813            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9814            return;
9815        }
9816
9817        final long token = Binder.clearCallingIdentity();
9818        try {
9819            appNotResponding(host, null, null, false, "ContentProvider not responding");
9820        } finally {
9821            Binder.restoreCallingIdentity(token);
9822        }
9823    }
9824
9825    public final void installSystemProviders() {
9826        List<ProviderInfo> providers;
9827        synchronized (this) {
9828            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9829            providers = generateApplicationProvidersLocked(app);
9830            if (providers != null) {
9831                for (int i=providers.size()-1; i>=0; i--) {
9832                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9833                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9834                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9835                                + ": not system .apk");
9836                        providers.remove(i);
9837                    }
9838                }
9839            }
9840        }
9841        if (providers != null) {
9842            mSystemThread.installSystemProviders(providers);
9843        }
9844
9845        mCoreSettingsObserver = new CoreSettingsObserver(this);
9846
9847        //mUsageStatsService.monitorPackages();
9848    }
9849
9850    /**
9851     * Allows apps to retrieve the MIME type of a URI.
9852     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9853     * users, then it does not need permission to access the ContentProvider.
9854     * Either, it needs cross-user uri grants.
9855     *
9856     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9857     *
9858     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9859     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9860     */
9861    public String getProviderMimeType(Uri uri, int userId) {
9862        enforceNotIsolatedCaller("getProviderMimeType");
9863        final String name = uri.getAuthority();
9864        int callingUid = Binder.getCallingUid();
9865        int callingPid = Binder.getCallingPid();
9866        long ident = 0;
9867        boolean clearedIdentity = false;
9868        userId = unsafeConvertIncomingUser(userId);
9869        if (canClearIdentity(callingPid, callingUid, userId)) {
9870            clearedIdentity = true;
9871            ident = Binder.clearCallingIdentity();
9872        }
9873        ContentProviderHolder holder = null;
9874        try {
9875            holder = getContentProviderExternalUnchecked(name, null, userId);
9876            if (holder != null) {
9877                return holder.provider.getType(uri);
9878            }
9879        } catch (RemoteException e) {
9880            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9881            return null;
9882        } finally {
9883            // We need to clear the identity to call removeContentProviderExternalUnchecked
9884            if (!clearedIdentity) {
9885                ident = Binder.clearCallingIdentity();
9886            }
9887            try {
9888                if (holder != null) {
9889                    removeContentProviderExternalUnchecked(name, null, userId);
9890                }
9891            } finally {
9892                Binder.restoreCallingIdentity(ident);
9893            }
9894        }
9895
9896        return null;
9897    }
9898
9899    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9900        if (UserHandle.getUserId(callingUid) == userId) {
9901            return true;
9902        }
9903        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9904                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9905                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9906                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9907                return true;
9908        }
9909        return false;
9910    }
9911
9912    // =========================================================
9913    // GLOBAL MANAGEMENT
9914    // =========================================================
9915
9916    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9917            boolean isolated, int isolatedUid) {
9918        String proc = customProcess != null ? customProcess : info.processName;
9919        BatteryStatsImpl.Uid.Proc ps = null;
9920        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9921        int uid = info.uid;
9922        if (isolated) {
9923            if (isolatedUid == 0) {
9924                int userId = UserHandle.getUserId(uid);
9925                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9926                while (true) {
9927                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9928                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9929                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9930                    }
9931                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9932                    mNextIsolatedProcessUid++;
9933                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9934                        // No process for this uid, use it.
9935                        break;
9936                    }
9937                    stepsLeft--;
9938                    if (stepsLeft <= 0) {
9939                        return null;
9940                    }
9941                }
9942            } else {
9943                // Special case for startIsolatedProcess (internal only), where
9944                // the uid of the isolated process is specified by the caller.
9945                uid = isolatedUid;
9946            }
9947        }
9948        return new ProcessRecord(stats, info, proc, uid);
9949    }
9950
9951    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9952            String abiOverride) {
9953        ProcessRecord app;
9954        if (!isolated) {
9955            app = getProcessRecordLocked(info.processName, info.uid, true);
9956        } else {
9957            app = null;
9958        }
9959
9960        if (app == null) {
9961            app = newProcessRecordLocked(info, null, isolated, 0);
9962            mProcessNames.put(info.processName, app.uid, app);
9963            if (isolated) {
9964                mIsolatedProcesses.put(app.uid, app);
9965            }
9966            updateLruProcessLocked(app, false, null);
9967            updateOomAdjLocked();
9968        }
9969
9970        // This package really, really can not be stopped.
9971        try {
9972            AppGlobals.getPackageManager().setPackageStoppedState(
9973                    info.packageName, false, UserHandle.getUserId(app.uid));
9974        } catch (RemoteException e) {
9975        } catch (IllegalArgumentException e) {
9976            Slog.w(TAG, "Failed trying to unstop package "
9977                    + info.packageName + ": " + e);
9978        }
9979
9980        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9981                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9982            app.persistent = true;
9983            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9984        }
9985        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9986            mPersistentStartingProcesses.add(app);
9987            startProcessLocked(app, "added application", app.processName, abiOverride,
9988                    null /* entryPoint */, null /* entryPointArgs */);
9989        }
9990
9991        return app;
9992    }
9993
9994    public void unhandledBack() {
9995        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9996                "unhandledBack()");
9997
9998        synchronized(this) {
9999            final long origId = Binder.clearCallingIdentity();
10000            try {
10001                getFocusedStack().unhandledBackLocked();
10002            } finally {
10003                Binder.restoreCallingIdentity(origId);
10004            }
10005        }
10006    }
10007
10008    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10009        enforceNotIsolatedCaller("openContentUri");
10010        final int userId = UserHandle.getCallingUserId();
10011        String name = uri.getAuthority();
10012        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10013        ParcelFileDescriptor pfd = null;
10014        if (cph != null) {
10015            // We record the binder invoker's uid in thread-local storage before
10016            // going to the content provider to open the file.  Later, in the code
10017            // that handles all permissions checks, we look for this uid and use
10018            // that rather than the Activity Manager's own uid.  The effect is that
10019            // we do the check against the caller's permissions even though it looks
10020            // to the content provider like the Activity Manager itself is making
10021            // the request.
10022            sCallerIdentity.set(new Identity(
10023                    Binder.getCallingPid(), Binder.getCallingUid()));
10024            try {
10025                pfd = cph.provider.openFile(null, uri, "r", null);
10026            } catch (FileNotFoundException e) {
10027                // do nothing; pfd will be returned null
10028            } finally {
10029                // Ensure that whatever happens, we clean up the identity state
10030                sCallerIdentity.remove();
10031            }
10032
10033            // We've got the fd now, so we're done with the provider.
10034            removeContentProviderExternalUnchecked(name, null, userId);
10035        } else {
10036            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10037        }
10038        return pfd;
10039    }
10040
10041    // Actually is sleeping or shutting down or whatever else in the future
10042    // is an inactive state.
10043    public boolean isSleepingOrShuttingDown() {
10044        return isSleeping() || mShuttingDown;
10045    }
10046
10047    public boolean isSleeping() {
10048        return mSleeping;
10049    }
10050
10051    void goingToSleep() {
10052        synchronized(this) {
10053            mWentToSleep = true;
10054            goToSleepIfNeededLocked();
10055        }
10056    }
10057
10058    void finishRunningVoiceLocked() {
10059        if (mRunningVoice) {
10060            mRunningVoice = false;
10061            goToSleepIfNeededLocked();
10062        }
10063    }
10064
10065    void goToSleepIfNeededLocked() {
10066        if (mWentToSleep && !mRunningVoice) {
10067            if (!mSleeping) {
10068                mSleeping = true;
10069                mStackSupervisor.goingToSleepLocked();
10070
10071                // Initialize the wake times of all processes.
10072                checkExcessivePowerUsageLocked(false);
10073                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10074                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10075                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10076            }
10077        }
10078    }
10079
10080    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10081        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10082            // Never persist the home stack.
10083            return;
10084        }
10085        mTaskPersister.wakeup(task, flush);
10086    }
10087
10088    @Override
10089    public boolean shutdown(int timeout) {
10090        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10091                != PackageManager.PERMISSION_GRANTED) {
10092            throw new SecurityException("Requires permission "
10093                    + android.Manifest.permission.SHUTDOWN);
10094        }
10095
10096        boolean timedout = false;
10097
10098        synchronized(this) {
10099            mShuttingDown = true;
10100            updateEventDispatchingLocked();
10101            timedout = mStackSupervisor.shutdownLocked(timeout);
10102        }
10103
10104        mAppOpsService.shutdown();
10105        if (mUsageStatsService != null) {
10106            mUsageStatsService.prepareShutdown();
10107        }
10108        mBatteryStatsService.shutdown();
10109        synchronized (this) {
10110            mProcessStats.shutdownLocked();
10111        }
10112        notifyTaskPersisterLocked(null, true);
10113
10114        return timedout;
10115    }
10116
10117    public final void activitySlept(IBinder token) {
10118        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10119
10120        final long origId = Binder.clearCallingIdentity();
10121
10122        synchronized (this) {
10123            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10124            if (r != null) {
10125                mStackSupervisor.activitySleptLocked(r);
10126            }
10127        }
10128
10129        Binder.restoreCallingIdentity(origId);
10130    }
10131
10132    void logLockScreen(String msg) {
10133        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10134                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10135                mWentToSleep + " mSleeping=" + mSleeping);
10136    }
10137
10138    private void comeOutOfSleepIfNeededLocked() {
10139        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10140            if (mSleeping) {
10141                mSleeping = false;
10142                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10143            }
10144        }
10145    }
10146
10147    void wakingUp() {
10148        synchronized(this) {
10149            mWentToSleep = false;
10150            comeOutOfSleepIfNeededLocked();
10151        }
10152    }
10153
10154    void startRunningVoiceLocked() {
10155        if (!mRunningVoice) {
10156            mRunningVoice = true;
10157            comeOutOfSleepIfNeededLocked();
10158        }
10159    }
10160
10161    private void updateEventDispatchingLocked() {
10162        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10163    }
10164
10165    public void setLockScreenShown(boolean shown) {
10166        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10167                != PackageManager.PERMISSION_GRANTED) {
10168            throw new SecurityException("Requires permission "
10169                    + android.Manifest.permission.DEVICE_POWER);
10170        }
10171
10172        synchronized(this) {
10173            long ident = Binder.clearCallingIdentity();
10174            try {
10175                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10176                mLockScreenShown = shown;
10177                comeOutOfSleepIfNeededLocked();
10178            } finally {
10179                Binder.restoreCallingIdentity(ident);
10180            }
10181        }
10182    }
10183
10184    @Override
10185    public void stopAppSwitches() {
10186        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10187                != PackageManager.PERMISSION_GRANTED) {
10188            throw new SecurityException("Requires permission "
10189                    + android.Manifest.permission.STOP_APP_SWITCHES);
10190        }
10191
10192        synchronized(this) {
10193            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10194                    + APP_SWITCH_DELAY_TIME;
10195            mDidAppSwitch = false;
10196            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10197            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10198            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10199        }
10200    }
10201
10202    public void resumeAppSwitches() {
10203        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10204                != PackageManager.PERMISSION_GRANTED) {
10205            throw new SecurityException("Requires permission "
10206                    + android.Manifest.permission.STOP_APP_SWITCHES);
10207        }
10208
10209        synchronized(this) {
10210            // Note that we don't execute any pending app switches... we will
10211            // let those wait until either the timeout, or the next start
10212            // activity request.
10213            mAppSwitchesAllowedTime = 0;
10214        }
10215    }
10216
10217    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10218            int callingPid, int callingUid, String name) {
10219        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10220            return true;
10221        }
10222
10223        int perm = checkComponentPermission(
10224                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10225                sourceUid, -1, true);
10226        if (perm == PackageManager.PERMISSION_GRANTED) {
10227            return true;
10228        }
10229
10230        // If the actual IPC caller is different from the logical source, then
10231        // also see if they are allowed to control app switches.
10232        if (callingUid != -1 && callingUid != sourceUid) {
10233            perm = checkComponentPermission(
10234                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10235                    callingUid, -1, true);
10236            if (perm == PackageManager.PERMISSION_GRANTED) {
10237                return true;
10238            }
10239        }
10240
10241        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10242        return false;
10243    }
10244
10245    public void setDebugApp(String packageName, boolean waitForDebugger,
10246            boolean persistent) {
10247        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10248                "setDebugApp()");
10249
10250        long ident = Binder.clearCallingIdentity();
10251        try {
10252            // Note that this is not really thread safe if there are multiple
10253            // callers into it at the same time, but that's not a situation we
10254            // care about.
10255            if (persistent) {
10256                final ContentResolver resolver = mContext.getContentResolver();
10257                Settings.Global.putString(
10258                    resolver, Settings.Global.DEBUG_APP,
10259                    packageName);
10260                Settings.Global.putInt(
10261                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10262                    waitForDebugger ? 1 : 0);
10263            }
10264
10265            synchronized (this) {
10266                if (!persistent) {
10267                    mOrigDebugApp = mDebugApp;
10268                    mOrigWaitForDebugger = mWaitForDebugger;
10269                }
10270                mDebugApp = packageName;
10271                mWaitForDebugger = waitForDebugger;
10272                mDebugTransient = !persistent;
10273                if (packageName != null) {
10274                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10275                            false, UserHandle.USER_ALL, "set debug app");
10276                }
10277            }
10278        } finally {
10279            Binder.restoreCallingIdentity(ident);
10280        }
10281    }
10282
10283    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10284        synchronized (this) {
10285            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10286            if (!isDebuggable) {
10287                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10288                    throw new SecurityException("Process not debuggable: " + app.packageName);
10289                }
10290            }
10291
10292            mOpenGlTraceApp = processName;
10293        }
10294    }
10295
10296    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10297        synchronized (this) {
10298            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10299            if (!isDebuggable) {
10300                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10301                    throw new SecurityException("Process not debuggable: " + app.packageName);
10302                }
10303            }
10304            mProfileApp = processName;
10305            mProfileFile = profilerInfo.profileFile;
10306            if (mProfileFd != null) {
10307                try {
10308                    mProfileFd.close();
10309                } catch (IOException e) {
10310                }
10311                mProfileFd = null;
10312            }
10313            mProfileFd = profilerInfo.profileFd;
10314            mSamplingInterval = profilerInfo.samplingInterval;
10315            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10316            mProfileType = 0;
10317        }
10318    }
10319
10320    @Override
10321    public void setAlwaysFinish(boolean enabled) {
10322        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10323                "setAlwaysFinish()");
10324
10325        Settings.Global.putInt(
10326                mContext.getContentResolver(),
10327                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10328
10329        synchronized (this) {
10330            mAlwaysFinishActivities = enabled;
10331        }
10332    }
10333
10334    @Override
10335    public void setActivityController(IActivityController controller) {
10336        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10337                "setActivityController()");
10338        synchronized (this) {
10339            mController = controller;
10340            Watchdog.getInstance().setActivityController(controller);
10341        }
10342    }
10343
10344    @Override
10345    public void setUserIsMonkey(boolean userIsMonkey) {
10346        synchronized (this) {
10347            synchronized (mPidsSelfLocked) {
10348                final int callingPid = Binder.getCallingPid();
10349                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10350                if (precessRecord == null) {
10351                    throw new SecurityException("Unknown process: " + callingPid);
10352                }
10353                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10354                    throw new SecurityException("Only an instrumentation process "
10355                            + "with a UiAutomation can call setUserIsMonkey");
10356                }
10357            }
10358            mUserIsMonkey = userIsMonkey;
10359        }
10360    }
10361
10362    @Override
10363    public boolean isUserAMonkey() {
10364        synchronized (this) {
10365            // If there is a controller also implies the user is a monkey.
10366            return (mUserIsMonkey || mController != null);
10367        }
10368    }
10369
10370    public void requestBugReport() {
10371        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10372        SystemProperties.set("ctl.start", "bugreport");
10373    }
10374
10375    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10376        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10377    }
10378
10379    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10380        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10381            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10382        }
10383        return KEY_DISPATCHING_TIMEOUT;
10384    }
10385
10386    @Override
10387    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10388        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10389                != PackageManager.PERMISSION_GRANTED) {
10390            throw new SecurityException("Requires permission "
10391                    + android.Manifest.permission.FILTER_EVENTS);
10392        }
10393        ProcessRecord proc;
10394        long timeout;
10395        synchronized (this) {
10396            synchronized (mPidsSelfLocked) {
10397                proc = mPidsSelfLocked.get(pid);
10398            }
10399            timeout = getInputDispatchingTimeoutLocked(proc);
10400        }
10401
10402        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10403            return -1;
10404        }
10405
10406        return timeout;
10407    }
10408
10409    /**
10410     * Handle input dispatching timeouts.
10411     * Returns whether input dispatching should be aborted or not.
10412     */
10413    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10414            final ActivityRecord activity, final ActivityRecord parent,
10415            final boolean aboveSystem, String reason) {
10416        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10417                != PackageManager.PERMISSION_GRANTED) {
10418            throw new SecurityException("Requires permission "
10419                    + android.Manifest.permission.FILTER_EVENTS);
10420        }
10421
10422        final String annotation;
10423        if (reason == null) {
10424            annotation = "Input dispatching timed out";
10425        } else {
10426            annotation = "Input dispatching timed out (" + reason + ")";
10427        }
10428
10429        if (proc != null) {
10430            synchronized (this) {
10431                if (proc.debugging) {
10432                    return false;
10433                }
10434
10435                if (mDidDexOpt) {
10436                    // Give more time since we were dexopting.
10437                    mDidDexOpt = false;
10438                    return false;
10439                }
10440
10441                if (proc.instrumentationClass != null) {
10442                    Bundle info = new Bundle();
10443                    info.putString("shortMsg", "keyDispatchingTimedOut");
10444                    info.putString("longMsg", annotation);
10445                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10446                    return true;
10447                }
10448            }
10449            mHandler.post(new Runnable() {
10450                @Override
10451                public void run() {
10452                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10453                }
10454            });
10455        }
10456
10457        return true;
10458    }
10459
10460    public Bundle getAssistContextExtras(int requestType) {
10461        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10462                UserHandle.getCallingUserId());
10463        if (pae == null) {
10464            return null;
10465        }
10466        synchronized (pae) {
10467            while (!pae.haveResult) {
10468                try {
10469                    pae.wait();
10470                } catch (InterruptedException e) {
10471                }
10472            }
10473            if (pae.result != null) {
10474                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10475            }
10476        }
10477        synchronized (this) {
10478            mPendingAssistExtras.remove(pae);
10479            mHandler.removeCallbacks(pae);
10480        }
10481        return pae.extras;
10482    }
10483
10484    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10485            int userHandle) {
10486        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10487                "getAssistContextExtras()");
10488        PendingAssistExtras pae;
10489        Bundle extras = new Bundle();
10490        synchronized (this) {
10491            ActivityRecord activity = getFocusedStack().mResumedActivity;
10492            if (activity == null) {
10493                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10494                return null;
10495            }
10496            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10497            if (activity.app == null || activity.app.thread == null) {
10498                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10499                return null;
10500            }
10501            if (activity.app.pid == Binder.getCallingPid()) {
10502                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10503                return null;
10504            }
10505            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10506            try {
10507                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10508                        requestType);
10509                mPendingAssistExtras.add(pae);
10510                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10511            } catch (RemoteException e) {
10512                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10513                return null;
10514            }
10515            return pae;
10516        }
10517    }
10518
10519    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10520        PendingAssistExtras pae = (PendingAssistExtras)token;
10521        synchronized (pae) {
10522            pae.result = extras;
10523            pae.haveResult = true;
10524            pae.notifyAll();
10525            if (pae.intent == null) {
10526                // Caller is just waiting for the result.
10527                return;
10528            }
10529        }
10530
10531        // We are now ready to launch the assist activity.
10532        synchronized (this) {
10533            boolean exists = mPendingAssistExtras.remove(pae);
10534            mHandler.removeCallbacks(pae);
10535            if (!exists) {
10536                // Timed out.
10537                return;
10538            }
10539        }
10540        pae.intent.replaceExtras(extras);
10541        if (pae.hint != null) {
10542            pae.intent.putExtra(pae.hint, true);
10543        }
10544        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10545                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10546                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10547        closeSystemDialogs("assist");
10548        try {
10549            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10550        } catch (ActivityNotFoundException e) {
10551            Slog.w(TAG, "No activity to handle assist action.", e);
10552        }
10553    }
10554
10555    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10556        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10557    }
10558
10559    public void registerProcessObserver(IProcessObserver observer) {
10560        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10561                "registerProcessObserver()");
10562        synchronized (this) {
10563            mProcessObservers.register(observer);
10564        }
10565    }
10566
10567    @Override
10568    public void unregisterProcessObserver(IProcessObserver observer) {
10569        synchronized (this) {
10570            mProcessObservers.unregister(observer);
10571        }
10572    }
10573
10574    @Override
10575    public boolean convertFromTranslucent(IBinder token) {
10576        final long origId = Binder.clearCallingIdentity();
10577        try {
10578            synchronized (this) {
10579                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10580                if (r == null) {
10581                    return false;
10582                }
10583                final boolean translucentChanged = r.changeWindowTranslucency(true);
10584                if (translucentChanged) {
10585                    r.task.stack.releaseBackgroundResources();
10586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10587                }
10588                mWindowManager.setAppFullscreen(token, true);
10589                return translucentChanged;
10590            }
10591        } finally {
10592            Binder.restoreCallingIdentity(origId);
10593        }
10594    }
10595
10596    @Override
10597    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10598        final long origId = Binder.clearCallingIdentity();
10599        try {
10600            synchronized (this) {
10601                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10602                if (r == null) {
10603                    return false;
10604                }
10605                int index = r.task.mActivities.lastIndexOf(r);
10606                if (index > 0) {
10607                    ActivityRecord under = r.task.mActivities.get(index - 1);
10608                    under.returningOptions = options;
10609                }
10610                final boolean translucentChanged = r.changeWindowTranslucency(false);
10611                if (translucentChanged) {
10612                    r.task.stack.convertToTranslucent(r);
10613                }
10614                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10615                mWindowManager.setAppFullscreen(token, false);
10616                return translucentChanged;
10617            }
10618        } finally {
10619            Binder.restoreCallingIdentity(origId);
10620        }
10621    }
10622
10623    @Override
10624    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10625        final long origId = Binder.clearCallingIdentity();
10626        try {
10627            synchronized (this) {
10628                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10629                if (r != null) {
10630                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10631                }
10632            }
10633            return false;
10634        } finally {
10635            Binder.restoreCallingIdentity(origId);
10636        }
10637    }
10638
10639    @Override
10640    public boolean isBackgroundVisibleBehind(IBinder token) {
10641        final long origId = Binder.clearCallingIdentity();
10642        try {
10643            synchronized (this) {
10644                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10645                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10646                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10647                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10648                return visible;
10649            }
10650        } finally {
10651            Binder.restoreCallingIdentity(origId);
10652        }
10653    }
10654
10655    @Override
10656    public ActivityOptions getActivityOptions(IBinder token) {
10657        final long origId = Binder.clearCallingIdentity();
10658        try {
10659            synchronized (this) {
10660                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10661                if (r != null) {
10662                    final ActivityOptions activityOptions = r.pendingOptions;
10663                    r.pendingOptions = null;
10664                    return activityOptions;
10665                }
10666                return null;
10667            }
10668        } finally {
10669            Binder.restoreCallingIdentity(origId);
10670        }
10671    }
10672
10673    @Override
10674    public void setImmersive(IBinder token, boolean immersive) {
10675        synchronized(this) {
10676            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10677            if (r == null) {
10678                throw new IllegalArgumentException();
10679            }
10680            r.immersive = immersive;
10681
10682            // update associated state if we're frontmost
10683            if (r == mFocusedActivity) {
10684                if (DEBUG_IMMERSIVE) {
10685                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10686                }
10687                applyUpdateLockStateLocked(r);
10688            }
10689        }
10690    }
10691
10692    @Override
10693    public boolean isImmersive(IBinder token) {
10694        synchronized (this) {
10695            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10696            if (r == null) {
10697                throw new IllegalArgumentException();
10698            }
10699            return r.immersive;
10700        }
10701    }
10702
10703    public boolean isTopActivityImmersive() {
10704        enforceNotIsolatedCaller("startActivity");
10705        synchronized (this) {
10706            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10707            return (r != null) ? r.immersive : false;
10708        }
10709    }
10710
10711    @Override
10712    public boolean isTopOfTask(IBinder token) {
10713        synchronized (this) {
10714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10715            if (r == null) {
10716                throw new IllegalArgumentException();
10717            }
10718            return r.task.getTopActivity() == r;
10719        }
10720    }
10721
10722    public final void enterSafeMode() {
10723        synchronized(this) {
10724            // It only makes sense to do this before the system is ready
10725            // and started launching other packages.
10726            if (!mSystemReady) {
10727                try {
10728                    AppGlobals.getPackageManager().enterSafeMode();
10729                } catch (RemoteException e) {
10730                }
10731            }
10732
10733            mSafeMode = true;
10734        }
10735    }
10736
10737    public final void showSafeModeOverlay() {
10738        View v = LayoutInflater.from(mContext).inflate(
10739                com.android.internal.R.layout.safe_mode, null);
10740        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10741        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10742        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10743        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10744        lp.gravity = Gravity.BOTTOM | Gravity.START;
10745        lp.format = v.getBackground().getOpacity();
10746        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10747                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10748        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10749        ((WindowManager)mContext.getSystemService(
10750                Context.WINDOW_SERVICE)).addView(v, lp);
10751    }
10752
10753    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10754        if (!(sender instanceof PendingIntentRecord)) {
10755            return;
10756        }
10757        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10758        synchronized (stats) {
10759            if (mBatteryStatsService.isOnBattery()) {
10760                mBatteryStatsService.enforceCallingPermission();
10761                PendingIntentRecord rec = (PendingIntentRecord)sender;
10762                int MY_UID = Binder.getCallingUid();
10763                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10764                BatteryStatsImpl.Uid.Pkg pkg =
10765                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10766                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10767                pkg.incWakeupsLocked();
10768            }
10769        }
10770    }
10771
10772    public boolean killPids(int[] pids, String pReason, boolean secure) {
10773        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10774            throw new SecurityException("killPids only available to the system");
10775        }
10776        String reason = (pReason == null) ? "Unknown" : pReason;
10777        // XXX Note: don't acquire main activity lock here, because the window
10778        // manager calls in with its locks held.
10779
10780        boolean killed = false;
10781        synchronized (mPidsSelfLocked) {
10782            int[] types = new int[pids.length];
10783            int worstType = 0;
10784            for (int i=0; i<pids.length; i++) {
10785                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10786                if (proc != null) {
10787                    int type = proc.setAdj;
10788                    types[i] = type;
10789                    if (type > worstType) {
10790                        worstType = type;
10791                    }
10792                }
10793            }
10794
10795            // If the worst oom_adj is somewhere in the cached proc LRU range,
10796            // then constrain it so we will kill all cached procs.
10797            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10798                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10799                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10800            }
10801
10802            // If this is not a secure call, don't let it kill processes that
10803            // are important.
10804            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10805                worstType = ProcessList.SERVICE_ADJ;
10806            }
10807
10808            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10809            for (int i=0; i<pids.length; i++) {
10810                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10811                if (proc == null) {
10812                    continue;
10813                }
10814                int adj = proc.setAdj;
10815                if (adj >= worstType && !proc.killedByAm) {
10816                    proc.kill(reason, true);
10817                    killed = true;
10818                }
10819            }
10820        }
10821        return killed;
10822    }
10823
10824    @Override
10825    public void killUid(int uid, String reason) {
10826        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10827            throw new SecurityException("killUid only available to the system");
10828        }
10829        synchronized (this) {
10830            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10831                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10832                    reason != null ? reason : "kill uid");
10833        }
10834    }
10835
10836    @Override
10837    public boolean killProcessesBelowForeground(String reason) {
10838        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10839            throw new SecurityException("killProcessesBelowForeground() only available to system");
10840        }
10841
10842        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10843    }
10844
10845    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10846        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10847            throw new SecurityException("killProcessesBelowAdj() only available to system");
10848        }
10849
10850        boolean killed = false;
10851        synchronized (mPidsSelfLocked) {
10852            final int size = mPidsSelfLocked.size();
10853            for (int i = 0; i < size; i++) {
10854                final int pid = mPidsSelfLocked.keyAt(i);
10855                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10856                if (proc == null) continue;
10857
10858                final int adj = proc.setAdj;
10859                if (adj > belowAdj && !proc.killedByAm) {
10860                    proc.kill(reason, true);
10861                    killed = true;
10862                }
10863            }
10864        }
10865        return killed;
10866    }
10867
10868    @Override
10869    public void hang(final IBinder who, boolean allowRestart) {
10870        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10871                != PackageManager.PERMISSION_GRANTED) {
10872            throw new SecurityException("Requires permission "
10873                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10874        }
10875
10876        final IBinder.DeathRecipient death = new DeathRecipient() {
10877            @Override
10878            public void binderDied() {
10879                synchronized (this) {
10880                    notifyAll();
10881                }
10882            }
10883        };
10884
10885        try {
10886            who.linkToDeath(death, 0);
10887        } catch (RemoteException e) {
10888            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10889            return;
10890        }
10891
10892        synchronized (this) {
10893            Watchdog.getInstance().setAllowRestart(allowRestart);
10894            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10895            synchronized (death) {
10896                while (who.isBinderAlive()) {
10897                    try {
10898                        death.wait();
10899                    } catch (InterruptedException e) {
10900                    }
10901                }
10902            }
10903            Watchdog.getInstance().setAllowRestart(true);
10904        }
10905    }
10906
10907    @Override
10908    public void restart() {
10909        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10910                != PackageManager.PERMISSION_GRANTED) {
10911            throw new SecurityException("Requires permission "
10912                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10913        }
10914
10915        Log.i(TAG, "Sending shutdown broadcast...");
10916
10917        BroadcastReceiver br = new BroadcastReceiver() {
10918            @Override public void onReceive(Context context, Intent intent) {
10919                // Now the broadcast is done, finish up the low-level shutdown.
10920                Log.i(TAG, "Shutting down activity manager...");
10921                shutdown(10000);
10922                Log.i(TAG, "Shutdown complete, restarting!");
10923                Process.killProcess(Process.myPid());
10924                System.exit(10);
10925            }
10926        };
10927
10928        // First send the high-level shut down broadcast.
10929        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10930        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10931        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10932        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10933        mContext.sendOrderedBroadcastAsUser(intent,
10934                UserHandle.ALL, null, br, mHandler, 0, null, null);
10935        */
10936        br.onReceive(mContext, intent);
10937    }
10938
10939    private long getLowRamTimeSinceIdle(long now) {
10940        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10941    }
10942
10943    @Override
10944    public void performIdleMaintenance() {
10945        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10946                != PackageManager.PERMISSION_GRANTED) {
10947            throw new SecurityException("Requires permission "
10948                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10949        }
10950
10951        synchronized (this) {
10952            final long now = SystemClock.uptimeMillis();
10953            final long timeSinceLastIdle = now - mLastIdleTime;
10954            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10955            mLastIdleTime = now;
10956            mLowRamTimeSinceLastIdle = 0;
10957            if (mLowRamStartTime != 0) {
10958                mLowRamStartTime = now;
10959            }
10960
10961            StringBuilder sb = new StringBuilder(128);
10962            sb.append("Idle maintenance over ");
10963            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10964            sb.append(" low RAM for ");
10965            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10966            Slog.i(TAG, sb.toString());
10967
10968            // If at least 1/3 of our time since the last idle period has been spent
10969            // with RAM low, then we want to kill processes.
10970            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10971
10972            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10973                ProcessRecord proc = mLruProcesses.get(i);
10974                if (proc.notCachedSinceIdle) {
10975                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10976                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10977                        if (doKilling && proc.initialIdlePss != 0
10978                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10979                            proc.kill("idle maint (pss " + proc.lastPss
10980                                    + " from " + proc.initialIdlePss + ")", true);
10981                        }
10982                    }
10983                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10984                    proc.notCachedSinceIdle = true;
10985                    proc.initialIdlePss = 0;
10986                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10987                            isSleeping(), now);
10988                }
10989            }
10990
10991            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10992            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10993        }
10994    }
10995
10996    private void retrieveSettings() {
10997        final ContentResolver resolver = mContext.getContentResolver();
10998        String debugApp = Settings.Global.getString(
10999            resolver, Settings.Global.DEBUG_APP);
11000        boolean waitForDebugger = Settings.Global.getInt(
11001            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11002        boolean alwaysFinishActivities = Settings.Global.getInt(
11003            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11004        boolean forceRtl = Settings.Global.getInt(
11005                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11006        // Transfer any global setting for forcing RTL layout, into a System Property
11007        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11008
11009        Configuration configuration = new Configuration();
11010        Settings.System.getConfiguration(resolver, configuration);
11011        if (forceRtl) {
11012            // This will take care of setting the correct layout direction flags
11013            configuration.setLayoutDirection(configuration.locale);
11014        }
11015
11016        synchronized (this) {
11017            mDebugApp = mOrigDebugApp = debugApp;
11018            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11019            mAlwaysFinishActivities = alwaysFinishActivities;
11020            // This happens before any activities are started, so we can
11021            // change mConfiguration in-place.
11022            updateConfigurationLocked(configuration, null, false, true);
11023            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11024        }
11025    }
11026
11027    /** Loads resources after the current configuration has been set. */
11028    private void loadResourcesOnSystemReady() {
11029        final Resources res = mContext.getResources();
11030        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11031        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11032        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11033    }
11034
11035    public boolean testIsSystemReady() {
11036        // no need to synchronize(this) just to read & return the value
11037        return mSystemReady;
11038    }
11039
11040    private static File getCalledPreBootReceiversFile() {
11041        File dataDir = Environment.getDataDirectory();
11042        File systemDir = new File(dataDir, "system");
11043        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11044        return fname;
11045    }
11046
11047    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11048        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11049        File file = getCalledPreBootReceiversFile();
11050        FileInputStream fis = null;
11051        try {
11052            fis = new FileInputStream(file);
11053            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11054            int fvers = dis.readInt();
11055            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11056                String vers = dis.readUTF();
11057                String codename = dis.readUTF();
11058                String build = dis.readUTF();
11059                if (android.os.Build.VERSION.RELEASE.equals(vers)
11060                        && android.os.Build.VERSION.CODENAME.equals(codename)
11061                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11062                    int num = dis.readInt();
11063                    while (num > 0) {
11064                        num--;
11065                        String pkg = dis.readUTF();
11066                        String cls = dis.readUTF();
11067                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11068                    }
11069                }
11070            }
11071        } catch (FileNotFoundException e) {
11072        } catch (IOException e) {
11073            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11074        } finally {
11075            if (fis != null) {
11076                try {
11077                    fis.close();
11078                } catch (IOException e) {
11079                }
11080            }
11081        }
11082        return lastDoneReceivers;
11083    }
11084
11085    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11086        File file = getCalledPreBootReceiversFile();
11087        FileOutputStream fos = null;
11088        DataOutputStream dos = null;
11089        try {
11090            fos = new FileOutputStream(file);
11091            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11092            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11093            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11094            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11095            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11096            dos.writeInt(list.size());
11097            for (int i=0; i<list.size(); i++) {
11098                dos.writeUTF(list.get(i).getPackageName());
11099                dos.writeUTF(list.get(i).getClassName());
11100            }
11101        } catch (IOException e) {
11102            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11103            file.delete();
11104        } finally {
11105            FileUtils.sync(fos);
11106            if (dos != null) {
11107                try {
11108                    dos.close();
11109                } catch (IOException e) {
11110                    // TODO Auto-generated catch block
11111                    e.printStackTrace();
11112                }
11113            }
11114        }
11115    }
11116
11117    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11118            ArrayList<ComponentName> doneReceivers, int userId) {
11119        boolean waitingUpdate = false;
11120        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11121        List<ResolveInfo> ris = null;
11122        try {
11123            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11124                    intent, null, 0, userId);
11125        } catch (RemoteException e) {
11126        }
11127        if (ris != null) {
11128            for (int i=ris.size()-1; i>=0; i--) {
11129                if ((ris.get(i).activityInfo.applicationInfo.flags
11130                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11131                    ris.remove(i);
11132                }
11133            }
11134            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11135
11136            // For User 0, load the version number. When delivering to a new user, deliver
11137            // to all receivers.
11138            if (userId == UserHandle.USER_OWNER) {
11139                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11140                for (int i=0; i<ris.size(); i++) {
11141                    ActivityInfo ai = ris.get(i).activityInfo;
11142                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11143                    if (lastDoneReceivers.contains(comp)) {
11144                        // We already did the pre boot receiver for this app with the current
11145                        // platform version, so don't do it again...
11146                        ris.remove(i);
11147                        i--;
11148                        // ...however, do keep it as one that has been done, so we don't
11149                        // forget about it when rewriting the file of last done receivers.
11150                        doneReceivers.add(comp);
11151                    }
11152                }
11153            }
11154
11155            // If primary user, send broadcast to all available users, else just to userId
11156            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11157                    : new int[] { userId };
11158            for (int i = 0; i < ris.size(); i++) {
11159                ActivityInfo ai = ris.get(i).activityInfo;
11160                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11161                doneReceivers.add(comp);
11162                intent.setComponent(comp);
11163                for (int j=0; j<users.length; j++) {
11164                    IIntentReceiver finisher = null;
11165                    // On last receiver and user, set up a completion callback
11166                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11167                        finisher = new IIntentReceiver.Stub() {
11168                            public void performReceive(Intent intent, int resultCode,
11169                                    String data, Bundle extras, boolean ordered,
11170                                    boolean sticky, int sendingUser) {
11171                                // The raw IIntentReceiver interface is called
11172                                // with the AM lock held, so redispatch to
11173                                // execute our code without the lock.
11174                                mHandler.post(onFinishCallback);
11175                            }
11176                        };
11177                    }
11178                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11179                            + " for user " + users[j]);
11180                    broadcastIntentLocked(null, null, intent, null, finisher,
11181                            0, null, null, null, AppOpsManager.OP_NONE,
11182                            true, false, MY_PID, Process.SYSTEM_UID,
11183                            users[j]);
11184                    if (finisher != null) {
11185                        waitingUpdate = true;
11186                    }
11187                }
11188            }
11189        }
11190
11191        return waitingUpdate;
11192    }
11193
11194    public void systemReady(final Runnable goingCallback) {
11195        synchronized(this) {
11196            if (mSystemReady) {
11197                // If we're done calling all the receivers, run the next "boot phase" passed in
11198                // by the SystemServer
11199                if (goingCallback != null) {
11200                    goingCallback.run();
11201                }
11202                return;
11203            }
11204
11205            // Make sure we have the current profile info, since it is needed for
11206            // security checks.
11207            updateCurrentProfileIdsLocked();
11208
11209            if (mRecentTasks == null) {
11210                mRecentTasks = mTaskPersister.restoreTasksLocked();
11211                if (!mRecentTasks.isEmpty()) {
11212                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11213                }
11214                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11215                mTaskPersister.startPersisting();
11216            }
11217
11218            // Check to see if there are any update receivers to run.
11219            if (!mDidUpdate) {
11220                if (mWaitingUpdate) {
11221                    return;
11222                }
11223                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11224                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11225                    public void run() {
11226                        synchronized (ActivityManagerService.this) {
11227                            mDidUpdate = true;
11228                        }
11229                        writeLastDonePreBootReceivers(doneReceivers);
11230                        showBootMessage(mContext.getText(
11231                                R.string.android_upgrading_complete),
11232                                false);
11233                        systemReady(goingCallback);
11234                    }
11235                }, doneReceivers, UserHandle.USER_OWNER);
11236
11237                if (mWaitingUpdate) {
11238                    return;
11239                }
11240                mDidUpdate = true;
11241            }
11242
11243            mAppOpsService.systemReady();
11244            mSystemReady = true;
11245        }
11246
11247        ArrayList<ProcessRecord> procsToKill = null;
11248        synchronized(mPidsSelfLocked) {
11249            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11250                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11251                if (!isAllowedWhileBooting(proc.info)){
11252                    if (procsToKill == null) {
11253                        procsToKill = new ArrayList<ProcessRecord>();
11254                    }
11255                    procsToKill.add(proc);
11256                }
11257            }
11258        }
11259
11260        synchronized(this) {
11261            if (procsToKill != null) {
11262                for (int i=procsToKill.size()-1; i>=0; i--) {
11263                    ProcessRecord proc = procsToKill.get(i);
11264                    Slog.i(TAG, "Removing system update proc: " + proc);
11265                    removeProcessLocked(proc, true, false, "system update done");
11266                }
11267            }
11268
11269            // Now that we have cleaned up any update processes, we
11270            // are ready to start launching real processes and know that
11271            // we won't trample on them any more.
11272            mProcessesReady = true;
11273        }
11274
11275        Slog.i(TAG, "System now ready");
11276        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11277            SystemClock.uptimeMillis());
11278
11279        synchronized(this) {
11280            // Make sure we have no pre-ready processes sitting around.
11281
11282            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11283                ResolveInfo ri = mContext.getPackageManager()
11284                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11285                                STOCK_PM_FLAGS);
11286                CharSequence errorMsg = null;
11287                if (ri != null) {
11288                    ActivityInfo ai = ri.activityInfo;
11289                    ApplicationInfo app = ai.applicationInfo;
11290                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11291                        mTopAction = Intent.ACTION_FACTORY_TEST;
11292                        mTopData = null;
11293                        mTopComponent = new ComponentName(app.packageName,
11294                                ai.name);
11295                    } else {
11296                        errorMsg = mContext.getResources().getText(
11297                                com.android.internal.R.string.factorytest_not_system);
11298                    }
11299                } else {
11300                    errorMsg = mContext.getResources().getText(
11301                            com.android.internal.R.string.factorytest_no_action);
11302                }
11303                if (errorMsg != null) {
11304                    mTopAction = null;
11305                    mTopData = null;
11306                    mTopComponent = null;
11307                    Message msg = Message.obtain();
11308                    msg.what = SHOW_FACTORY_ERROR_MSG;
11309                    msg.getData().putCharSequence("msg", errorMsg);
11310                    mHandler.sendMessage(msg);
11311                }
11312            }
11313        }
11314
11315        retrieveSettings();
11316        loadResourcesOnSystemReady();
11317
11318        synchronized (this) {
11319            readGrantedUriPermissionsLocked();
11320        }
11321
11322        if (goingCallback != null) goingCallback.run();
11323
11324        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11325                Integer.toString(mCurrentUserId), mCurrentUserId);
11326        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11327                Integer.toString(mCurrentUserId), mCurrentUserId);
11328        mSystemServiceManager.startUser(mCurrentUserId);
11329
11330        synchronized (this) {
11331            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11332                try {
11333                    List apps = AppGlobals.getPackageManager().
11334                        getPersistentApplications(STOCK_PM_FLAGS);
11335                    if (apps != null) {
11336                        int N = apps.size();
11337                        int i;
11338                        for (i=0; i<N; i++) {
11339                            ApplicationInfo info
11340                                = (ApplicationInfo)apps.get(i);
11341                            if (info != null &&
11342                                    !info.packageName.equals("android")) {
11343                                addAppLocked(info, false, null /* ABI override */);
11344                            }
11345                        }
11346                    }
11347                } catch (RemoteException ex) {
11348                    // pm is in same process, this will never happen.
11349                }
11350            }
11351
11352            // Start up initial activity.
11353            mBooting = true;
11354            startHomeActivityLocked(mCurrentUserId);
11355
11356            try {
11357                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11358                    Message msg = Message.obtain();
11359                    msg.what = SHOW_UID_ERROR_MSG;
11360                    mHandler.sendMessage(msg);
11361                }
11362            } catch (RemoteException e) {
11363            }
11364
11365            long ident = Binder.clearCallingIdentity();
11366            try {
11367                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11368                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11369                        | Intent.FLAG_RECEIVER_FOREGROUND);
11370                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11371                broadcastIntentLocked(null, null, intent,
11372                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11373                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11374                intent = new Intent(Intent.ACTION_USER_STARTING);
11375                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11376                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11377                broadcastIntentLocked(null, null, intent,
11378                        null, new IIntentReceiver.Stub() {
11379                            @Override
11380                            public void performReceive(Intent intent, int resultCode, String data,
11381                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11382                                    throws RemoteException {
11383                            }
11384                        }, 0, null, null,
11385                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11386                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11387            } catch (Throwable t) {
11388                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11389            } finally {
11390                Binder.restoreCallingIdentity(ident);
11391            }
11392            mStackSupervisor.resumeTopActivitiesLocked();
11393            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11394        }
11395    }
11396
11397    private boolean makeAppCrashingLocked(ProcessRecord app,
11398            String shortMsg, String longMsg, String stackTrace) {
11399        app.crashing = true;
11400        app.crashingReport = generateProcessError(app,
11401                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11402        startAppProblemLocked(app);
11403        app.stopFreezingAllLocked();
11404        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11405    }
11406
11407    private void makeAppNotRespondingLocked(ProcessRecord app,
11408            String activity, String shortMsg, String longMsg) {
11409        app.notResponding = true;
11410        app.notRespondingReport = generateProcessError(app,
11411                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11412                activity, shortMsg, longMsg, null);
11413        startAppProblemLocked(app);
11414        app.stopFreezingAllLocked();
11415    }
11416
11417    /**
11418     * Generate a process error record, suitable for attachment to a ProcessRecord.
11419     *
11420     * @param app The ProcessRecord in which the error occurred.
11421     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11422     *                      ActivityManager.AppErrorStateInfo
11423     * @param activity The activity associated with the crash, if known.
11424     * @param shortMsg Short message describing the crash.
11425     * @param longMsg Long message describing the crash.
11426     * @param stackTrace Full crash stack trace, may be null.
11427     *
11428     * @return Returns a fully-formed AppErrorStateInfo record.
11429     */
11430    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11431            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11432        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11433
11434        report.condition = condition;
11435        report.processName = app.processName;
11436        report.pid = app.pid;
11437        report.uid = app.info.uid;
11438        report.tag = activity;
11439        report.shortMsg = shortMsg;
11440        report.longMsg = longMsg;
11441        report.stackTrace = stackTrace;
11442
11443        return report;
11444    }
11445
11446    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11447        synchronized (this) {
11448            app.crashing = false;
11449            app.crashingReport = null;
11450            app.notResponding = false;
11451            app.notRespondingReport = null;
11452            if (app.anrDialog == fromDialog) {
11453                app.anrDialog = null;
11454            }
11455            if (app.waitDialog == fromDialog) {
11456                app.waitDialog = null;
11457            }
11458            if (app.pid > 0 && app.pid != MY_PID) {
11459                handleAppCrashLocked(app, null, null, null);
11460                app.kill("user request after error", true);
11461            }
11462        }
11463    }
11464
11465    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11466            String stackTrace) {
11467        long now = SystemClock.uptimeMillis();
11468
11469        Long crashTime;
11470        if (!app.isolated) {
11471            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11472        } else {
11473            crashTime = null;
11474        }
11475        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11476            // This process loses!
11477            Slog.w(TAG, "Process " + app.info.processName
11478                    + " has crashed too many times: killing!");
11479            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11480                    app.userId, app.info.processName, app.uid);
11481            mStackSupervisor.handleAppCrashLocked(app);
11482            if (!app.persistent) {
11483                // We don't want to start this process again until the user
11484                // explicitly does so...  but for persistent process, we really
11485                // need to keep it running.  If a persistent process is actually
11486                // repeatedly crashing, then badness for everyone.
11487                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11488                        app.info.processName);
11489                if (!app.isolated) {
11490                    // XXX We don't have a way to mark isolated processes
11491                    // as bad, since they don't have a peristent identity.
11492                    mBadProcesses.put(app.info.processName, app.uid,
11493                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11494                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11495                }
11496                app.bad = true;
11497                app.removed = true;
11498                // Don't let services in this process be restarted and potentially
11499                // annoy the user repeatedly.  Unless it is persistent, since those
11500                // processes run critical code.
11501                removeProcessLocked(app, false, false, "crash");
11502                mStackSupervisor.resumeTopActivitiesLocked();
11503                return false;
11504            }
11505            mStackSupervisor.resumeTopActivitiesLocked();
11506        } else {
11507            mStackSupervisor.finishTopRunningActivityLocked(app);
11508        }
11509
11510        // Bump up the crash count of any services currently running in the proc.
11511        for (int i=app.services.size()-1; i>=0; i--) {
11512            // Any services running in the application need to be placed
11513            // back in the pending list.
11514            ServiceRecord sr = app.services.valueAt(i);
11515            sr.crashCount++;
11516        }
11517
11518        // If the crashing process is what we consider to be the "home process" and it has been
11519        // replaced by a third-party app, clear the package preferred activities from packages
11520        // with a home activity running in the process to prevent a repeatedly crashing app
11521        // from blocking the user to manually clear the list.
11522        final ArrayList<ActivityRecord> activities = app.activities;
11523        if (app == mHomeProcess && activities.size() > 0
11524                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11525            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11526                final ActivityRecord r = activities.get(activityNdx);
11527                if (r.isHomeActivity()) {
11528                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11529                    try {
11530                        ActivityThread.getPackageManager()
11531                                .clearPackagePreferredActivities(r.packageName);
11532                    } catch (RemoteException c) {
11533                        // pm is in same process, this will never happen.
11534                    }
11535                }
11536            }
11537        }
11538
11539        if (!app.isolated) {
11540            // XXX Can't keep track of crash times for isolated processes,
11541            // because they don't have a perisistent identity.
11542            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11543        }
11544
11545        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11546        return true;
11547    }
11548
11549    void startAppProblemLocked(ProcessRecord app) {
11550        // If this app is not running under the current user, then we
11551        // can't give it a report button because that would require
11552        // launching the report UI under a different user.
11553        app.errorReportReceiver = null;
11554
11555        for (int userId : mCurrentProfileIds) {
11556            if (app.userId == userId) {
11557                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11558                        mContext, app.info.packageName, app.info.flags);
11559            }
11560        }
11561        skipCurrentReceiverLocked(app);
11562    }
11563
11564    void skipCurrentReceiverLocked(ProcessRecord app) {
11565        for (BroadcastQueue queue : mBroadcastQueues) {
11566            queue.skipCurrentReceiverLocked(app);
11567        }
11568    }
11569
11570    /**
11571     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11572     * The application process will exit immediately after this call returns.
11573     * @param app object of the crashing app, null for the system server
11574     * @param crashInfo describing the exception
11575     */
11576    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11577        ProcessRecord r = findAppProcess(app, "Crash");
11578        final String processName = app == null ? "system_server"
11579                : (r == null ? "unknown" : r.processName);
11580
11581        handleApplicationCrashInner("crash", r, processName, crashInfo);
11582    }
11583
11584    /* Native crash reporting uses this inner version because it needs to be somewhat
11585     * decoupled from the AM-managed cleanup lifecycle
11586     */
11587    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11588            ApplicationErrorReport.CrashInfo crashInfo) {
11589        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11590                UserHandle.getUserId(Binder.getCallingUid()), processName,
11591                r == null ? -1 : r.info.flags,
11592                crashInfo.exceptionClassName,
11593                crashInfo.exceptionMessage,
11594                crashInfo.throwFileName,
11595                crashInfo.throwLineNumber);
11596
11597        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11598
11599        crashApplication(r, crashInfo);
11600    }
11601
11602    public void handleApplicationStrictModeViolation(
11603            IBinder app,
11604            int violationMask,
11605            StrictMode.ViolationInfo info) {
11606        ProcessRecord r = findAppProcess(app, "StrictMode");
11607        if (r == null) {
11608            return;
11609        }
11610
11611        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11612            Integer stackFingerprint = info.hashCode();
11613            boolean logIt = true;
11614            synchronized (mAlreadyLoggedViolatedStacks) {
11615                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11616                    logIt = false;
11617                    // TODO: sub-sample into EventLog for these, with
11618                    // the info.durationMillis?  Then we'd get
11619                    // the relative pain numbers, without logging all
11620                    // the stack traces repeatedly.  We'd want to do
11621                    // likewise in the client code, which also does
11622                    // dup suppression, before the Binder call.
11623                } else {
11624                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11625                        mAlreadyLoggedViolatedStacks.clear();
11626                    }
11627                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11628                }
11629            }
11630            if (logIt) {
11631                logStrictModeViolationToDropBox(r, info);
11632            }
11633        }
11634
11635        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11636            AppErrorResult result = new AppErrorResult();
11637            synchronized (this) {
11638                final long origId = Binder.clearCallingIdentity();
11639
11640                Message msg = Message.obtain();
11641                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11642                HashMap<String, Object> data = new HashMap<String, Object>();
11643                data.put("result", result);
11644                data.put("app", r);
11645                data.put("violationMask", violationMask);
11646                data.put("info", info);
11647                msg.obj = data;
11648                mHandler.sendMessage(msg);
11649
11650                Binder.restoreCallingIdentity(origId);
11651            }
11652            int res = result.get();
11653            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11654        }
11655    }
11656
11657    // Depending on the policy in effect, there could be a bunch of
11658    // these in quick succession so we try to batch these together to
11659    // minimize disk writes, number of dropbox entries, and maximize
11660    // compression, by having more fewer, larger records.
11661    private void logStrictModeViolationToDropBox(
11662            ProcessRecord process,
11663            StrictMode.ViolationInfo info) {
11664        if (info == null) {
11665            return;
11666        }
11667        final boolean isSystemApp = process == null ||
11668                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11669                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11670        final String processName = process == null ? "unknown" : process.processName;
11671        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11672        final DropBoxManager dbox = (DropBoxManager)
11673                mContext.getSystemService(Context.DROPBOX_SERVICE);
11674
11675        // Exit early if the dropbox isn't configured to accept this report type.
11676        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11677
11678        boolean bufferWasEmpty;
11679        boolean needsFlush;
11680        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11681        synchronized (sb) {
11682            bufferWasEmpty = sb.length() == 0;
11683            appendDropBoxProcessHeaders(process, processName, sb);
11684            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11685            sb.append("System-App: ").append(isSystemApp).append("\n");
11686            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11687            if (info.violationNumThisLoop != 0) {
11688                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11689            }
11690            if (info.numAnimationsRunning != 0) {
11691                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11692            }
11693            if (info.broadcastIntentAction != null) {
11694                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11695            }
11696            if (info.durationMillis != -1) {
11697                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11698            }
11699            if (info.numInstances != -1) {
11700                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11701            }
11702            if (info.tags != null) {
11703                for (String tag : info.tags) {
11704                    sb.append("Span-Tag: ").append(tag).append("\n");
11705                }
11706            }
11707            sb.append("\n");
11708            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11709                sb.append(info.crashInfo.stackTrace);
11710            }
11711            sb.append("\n");
11712
11713            // Only buffer up to ~64k.  Various logging bits truncate
11714            // things at 128k.
11715            needsFlush = (sb.length() > 64 * 1024);
11716        }
11717
11718        // Flush immediately if the buffer's grown too large, or this
11719        // is a non-system app.  Non-system apps are isolated with a
11720        // different tag & policy and not batched.
11721        //
11722        // Batching is useful during internal testing with
11723        // StrictMode settings turned up high.  Without batching,
11724        // thousands of separate files could be created on boot.
11725        if (!isSystemApp || needsFlush) {
11726            new Thread("Error dump: " + dropboxTag) {
11727                @Override
11728                public void run() {
11729                    String report;
11730                    synchronized (sb) {
11731                        report = sb.toString();
11732                        sb.delete(0, sb.length());
11733                        sb.trimToSize();
11734                    }
11735                    if (report.length() != 0) {
11736                        dbox.addText(dropboxTag, report);
11737                    }
11738                }
11739            }.start();
11740            return;
11741        }
11742
11743        // System app batching:
11744        if (!bufferWasEmpty) {
11745            // An existing dropbox-writing thread is outstanding, so
11746            // we don't need to start it up.  The existing thread will
11747            // catch the buffer appends we just did.
11748            return;
11749        }
11750
11751        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11752        // (After this point, we shouldn't access AMS internal data structures.)
11753        new Thread("Error dump: " + dropboxTag) {
11754            @Override
11755            public void run() {
11756                // 5 second sleep to let stacks arrive and be batched together
11757                try {
11758                    Thread.sleep(5000);  // 5 seconds
11759                } catch (InterruptedException e) {}
11760
11761                String errorReport;
11762                synchronized (mStrictModeBuffer) {
11763                    errorReport = mStrictModeBuffer.toString();
11764                    if (errorReport.length() == 0) {
11765                        return;
11766                    }
11767                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11768                    mStrictModeBuffer.trimToSize();
11769                }
11770                dbox.addText(dropboxTag, errorReport);
11771            }
11772        }.start();
11773    }
11774
11775    /**
11776     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11777     * @param app object of the crashing app, null for the system server
11778     * @param tag reported by the caller
11779     * @param system whether this wtf is coming from the system
11780     * @param crashInfo describing the context of the error
11781     * @return true if the process should exit immediately (WTF is fatal)
11782     */
11783    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11784            final ApplicationErrorReport.CrashInfo crashInfo) {
11785        final int callingUid = Binder.getCallingUid();
11786        final int callingPid = Binder.getCallingPid();
11787
11788        if (system) {
11789            // If this is coming from the system, we could very well have low-level
11790            // system locks held, so we want to do this all asynchronously.  And we
11791            // never want this to become fatal, so there is that too.
11792            mHandler.post(new Runnable() {
11793                @Override public void run() {
11794                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11795                }
11796            });
11797            return false;
11798        }
11799
11800        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11801                crashInfo);
11802
11803        if (r != null && r.pid != Process.myPid() &&
11804                Settings.Global.getInt(mContext.getContentResolver(),
11805                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11806            crashApplication(r, crashInfo);
11807            return true;
11808        } else {
11809            return false;
11810        }
11811    }
11812
11813    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11814            final ApplicationErrorReport.CrashInfo crashInfo) {
11815        final ProcessRecord r = findAppProcess(app, "WTF");
11816        final String processName = app == null ? "system_server"
11817                : (r == null ? "unknown" : r.processName);
11818
11819        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11820                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11821
11822        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11823
11824        return r;
11825    }
11826
11827    /**
11828     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11829     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11830     */
11831    private ProcessRecord findAppProcess(IBinder app, String reason) {
11832        if (app == null) {
11833            return null;
11834        }
11835
11836        synchronized (this) {
11837            final int NP = mProcessNames.getMap().size();
11838            for (int ip=0; ip<NP; ip++) {
11839                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11840                final int NA = apps.size();
11841                for (int ia=0; ia<NA; ia++) {
11842                    ProcessRecord p = apps.valueAt(ia);
11843                    if (p.thread != null && p.thread.asBinder() == app) {
11844                        return p;
11845                    }
11846                }
11847            }
11848
11849            Slog.w(TAG, "Can't find mystery application for " + reason
11850                    + " from pid=" + Binder.getCallingPid()
11851                    + " uid=" + Binder.getCallingUid() + ": " + app);
11852            return null;
11853        }
11854    }
11855
11856    /**
11857     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11858     * to append various headers to the dropbox log text.
11859     */
11860    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11861            StringBuilder sb) {
11862        // Watchdog thread ends up invoking this function (with
11863        // a null ProcessRecord) to add the stack file to dropbox.
11864        // Do not acquire a lock on this (am) in such cases, as it
11865        // could cause a potential deadlock, if and when watchdog
11866        // is invoked due to unavailability of lock on am and it
11867        // would prevent watchdog from killing system_server.
11868        if (process == null) {
11869            sb.append("Process: ").append(processName).append("\n");
11870            return;
11871        }
11872        // Note: ProcessRecord 'process' is guarded by the service
11873        // instance.  (notably process.pkgList, which could otherwise change
11874        // concurrently during execution of this method)
11875        synchronized (this) {
11876            sb.append("Process: ").append(processName).append("\n");
11877            int flags = process.info.flags;
11878            IPackageManager pm = AppGlobals.getPackageManager();
11879            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11880            for (int ip=0; ip<process.pkgList.size(); ip++) {
11881                String pkg = process.pkgList.keyAt(ip);
11882                sb.append("Package: ").append(pkg);
11883                try {
11884                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11885                    if (pi != null) {
11886                        sb.append(" v").append(pi.versionCode);
11887                        if (pi.versionName != null) {
11888                            sb.append(" (").append(pi.versionName).append(")");
11889                        }
11890                    }
11891                } catch (RemoteException e) {
11892                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11893                }
11894                sb.append("\n");
11895            }
11896        }
11897    }
11898
11899    private static String processClass(ProcessRecord process) {
11900        if (process == null || process.pid == MY_PID) {
11901            return "system_server";
11902        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11903            return "system_app";
11904        } else {
11905            return "data_app";
11906        }
11907    }
11908
11909    /**
11910     * Write a description of an error (crash, WTF, ANR) to the drop box.
11911     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11912     * @param process which caused the error, null means the system server
11913     * @param activity which triggered the error, null if unknown
11914     * @param parent activity related to the error, null if unknown
11915     * @param subject line related to the error, null if absent
11916     * @param report in long form describing the error, null if absent
11917     * @param logFile to include in the report, null if none
11918     * @param crashInfo giving an application stack trace, null if absent
11919     */
11920    public void addErrorToDropBox(String eventType,
11921            ProcessRecord process, String processName, ActivityRecord activity,
11922            ActivityRecord parent, String subject,
11923            final String report, final File logFile,
11924            final ApplicationErrorReport.CrashInfo crashInfo) {
11925        // NOTE -- this must never acquire the ActivityManagerService lock,
11926        // otherwise the watchdog may be prevented from resetting the system.
11927
11928        final String dropboxTag = processClass(process) + "_" + eventType;
11929        final DropBoxManager dbox = (DropBoxManager)
11930                mContext.getSystemService(Context.DROPBOX_SERVICE);
11931
11932        // Exit early if the dropbox isn't configured to accept this report type.
11933        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11934
11935        final StringBuilder sb = new StringBuilder(1024);
11936        appendDropBoxProcessHeaders(process, processName, sb);
11937        if (activity != null) {
11938            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11939        }
11940        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11941            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11942        }
11943        if (parent != null && parent != activity) {
11944            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11945        }
11946        if (subject != null) {
11947            sb.append("Subject: ").append(subject).append("\n");
11948        }
11949        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11950        if (Debug.isDebuggerConnected()) {
11951            sb.append("Debugger: Connected\n");
11952        }
11953        sb.append("\n");
11954
11955        // Do the rest in a worker thread to avoid blocking the caller on I/O
11956        // (After this point, we shouldn't access AMS internal data structures.)
11957        Thread worker = new Thread("Error dump: " + dropboxTag) {
11958            @Override
11959            public void run() {
11960                if (report != null) {
11961                    sb.append(report);
11962                }
11963                if (logFile != null) {
11964                    try {
11965                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11966                                    "\n\n[[TRUNCATED]]"));
11967                    } catch (IOException e) {
11968                        Slog.e(TAG, "Error reading " + logFile, e);
11969                    }
11970                }
11971                if (crashInfo != null && crashInfo.stackTrace != null) {
11972                    sb.append(crashInfo.stackTrace);
11973                }
11974
11975                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11976                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11977                if (lines > 0) {
11978                    sb.append("\n");
11979
11980                    // Merge several logcat streams, and take the last N lines
11981                    InputStreamReader input = null;
11982                    try {
11983                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11984                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11985                                "-b", "crash",
11986                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11987
11988                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11989                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11990                        input = new InputStreamReader(logcat.getInputStream());
11991
11992                        int num;
11993                        char[] buf = new char[8192];
11994                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11995                    } catch (IOException e) {
11996                        Slog.e(TAG, "Error running logcat", e);
11997                    } finally {
11998                        if (input != null) try { input.close(); } catch (IOException e) {}
11999                    }
12000                }
12001
12002                dbox.addText(dropboxTag, sb.toString());
12003            }
12004        };
12005
12006        if (process == null) {
12007            // If process is null, we are being called from some internal code
12008            // and may be about to die -- run this synchronously.
12009            worker.run();
12010        } else {
12011            worker.start();
12012        }
12013    }
12014
12015    /**
12016     * Bring up the "unexpected error" dialog box for a crashing app.
12017     * Deal with edge cases (intercepts from instrumented applications,
12018     * ActivityController, error intent receivers, that sort of thing).
12019     * @param r the application crashing
12020     * @param crashInfo describing the failure
12021     */
12022    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12023        long timeMillis = System.currentTimeMillis();
12024        String shortMsg = crashInfo.exceptionClassName;
12025        String longMsg = crashInfo.exceptionMessage;
12026        String stackTrace = crashInfo.stackTrace;
12027        if (shortMsg != null && longMsg != null) {
12028            longMsg = shortMsg + ": " + longMsg;
12029        } else if (shortMsg != null) {
12030            longMsg = shortMsg;
12031        }
12032
12033        AppErrorResult result = new AppErrorResult();
12034        synchronized (this) {
12035            if (mController != null) {
12036                try {
12037                    String name = r != null ? r.processName : null;
12038                    int pid = r != null ? r.pid : Binder.getCallingPid();
12039                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12040                    if (!mController.appCrashed(name, pid,
12041                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12042                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12043                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12044                            Slog.w(TAG, "Skip killing native crashed app " + name
12045                                    + "(" + pid + ") during testing");
12046                        } else {
12047                            Slog.w(TAG, "Force-killing crashed app " + name
12048                                    + " at watcher's request");
12049                            if (r != null) {
12050                                r.kill("crash", true);
12051                            } else {
12052                                // Huh.
12053                                Process.killProcess(pid);
12054                                Process.killProcessGroup(uid, pid);
12055                            }
12056                        }
12057                        return;
12058                    }
12059                } catch (RemoteException e) {
12060                    mController = null;
12061                    Watchdog.getInstance().setActivityController(null);
12062                }
12063            }
12064
12065            final long origId = Binder.clearCallingIdentity();
12066
12067            // If this process is running instrumentation, finish it.
12068            if (r != null && r.instrumentationClass != null) {
12069                Slog.w(TAG, "Error in app " + r.processName
12070                      + " running instrumentation " + r.instrumentationClass + ":");
12071                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12072                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12073                Bundle info = new Bundle();
12074                info.putString("shortMsg", shortMsg);
12075                info.putString("longMsg", longMsg);
12076                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12077                Binder.restoreCallingIdentity(origId);
12078                return;
12079            }
12080
12081            // If we can't identify the process or it's already exceeded its crash quota,
12082            // quit right away without showing a crash dialog.
12083            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12084                Binder.restoreCallingIdentity(origId);
12085                return;
12086            }
12087
12088            Message msg = Message.obtain();
12089            msg.what = SHOW_ERROR_MSG;
12090            HashMap data = new HashMap();
12091            data.put("result", result);
12092            data.put("app", r);
12093            msg.obj = data;
12094            mHandler.sendMessage(msg);
12095
12096            Binder.restoreCallingIdentity(origId);
12097        }
12098
12099        int res = result.get();
12100
12101        Intent appErrorIntent = null;
12102        synchronized (this) {
12103            if (r != null && !r.isolated) {
12104                // XXX Can't keep track of crash time for isolated processes,
12105                // since they don't have a persistent identity.
12106                mProcessCrashTimes.put(r.info.processName, r.uid,
12107                        SystemClock.uptimeMillis());
12108            }
12109            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12110                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12111            }
12112        }
12113
12114        if (appErrorIntent != null) {
12115            try {
12116                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12117            } catch (ActivityNotFoundException e) {
12118                Slog.w(TAG, "bug report receiver dissappeared", e);
12119            }
12120        }
12121    }
12122
12123    Intent createAppErrorIntentLocked(ProcessRecord r,
12124            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12125        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12126        if (report == null) {
12127            return null;
12128        }
12129        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12130        result.setComponent(r.errorReportReceiver);
12131        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12132        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12133        return result;
12134    }
12135
12136    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12137            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12138        if (r.errorReportReceiver == null) {
12139            return null;
12140        }
12141
12142        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12143            return null;
12144        }
12145
12146        ApplicationErrorReport report = new ApplicationErrorReport();
12147        report.packageName = r.info.packageName;
12148        report.installerPackageName = r.errorReportReceiver.getPackageName();
12149        report.processName = r.processName;
12150        report.time = timeMillis;
12151        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12152
12153        if (r.crashing || r.forceCrashReport) {
12154            report.type = ApplicationErrorReport.TYPE_CRASH;
12155            report.crashInfo = crashInfo;
12156        } else if (r.notResponding) {
12157            report.type = ApplicationErrorReport.TYPE_ANR;
12158            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12159
12160            report.anrInfo.activity = r.notRespondingReport.tag;
12161            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12162            report.anrInfo.info = r.notRespondingReport.longMsg;
12163        }
12164
12165        return report;
12166    }
12167
12168    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12169        enforceNotIsolatedCaller("getProcessesInErrorState");
12170        // assume our apps are happy - lazy create the list
12171        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12172
12173        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12174                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12175        int userId = UserHandle.getUserId(Binder.getCallingUid());
12176
12177        synchronized (this) {
12178
12179            // iterate across all processes
12180            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12181                ProcessRecord app = mLruProcesses.get(i);
12182                if (!allUsers && app.userId != userId) {
12183                    continue;
12184                }
12185                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12186                    // This one's in trouble, so we'll generate a report for it
12187                    // crashes are higher priority (in case there's a crash *and* an anr)
12188                    ActivityManager.ProcessErrorStateInfo report = null;
12189                    if (app.crashing) {
12190                        report = app.crashingReport;
12191                    } else if (app.notResponding) {
12192                        report = app.notRespondingReport;
12193                    }
12194
12195                    if (report != null) {
12196                        if (errList == null) {
12197                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12198                        }
12199                        errList.add(report);
12200                    } else {
12201                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12202                                " crashing = " + app.crashing +
12203                                " notResponding = " + app.notResponding);
12204                    }
12205                }
12206            }
12207        }
12208
12209        return errList;
12210    }
12211
12212    static int procStateToImportance(int procState, int memAdj,
12213            ActivityManager.RunningAppProcessInfo currApp) {
12214        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12215        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12216            currApp.lru = memAdj;
12217        } else {
12218            currApp.lru = 0;
12219        }
12220        return imp;
12221    }
12222
12223    private void fillInProcMemInfo(ProcessRecord app,
12224            ActivityManager.RunningAppProcessInfo outInfo) {
12225        outInfo.pid = app.pid;
12226        outInfo.uid = app.info.uid;
12227        if (mHeavyWeightProcess == app) {
12228            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12229        }
12230        if (app.persistent) {
12231            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12232        }
12233        if (app.activities.size() > 0) {
12234            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12235        }
12236        outInfo.lastTrimLevel = app.trimMemoryLevel;
12237        int adj = app.curAdj;
12238        int procState = app.curProcState;
12239        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12240        outInfo.importanceReasonCode = app.adjTypeCode;
12241        outInfo.processState = app.curProcState;
12242    }
12243
12244    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12245        enforceNotIsolatedCaller("getRunningAppProcesses");
12246        // Lazy instantiation of list
12247        List<ActivityManager.RunningAppProcessInfo> runList = null;
12248        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12249                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12250        int userId = UserHandle.getUserId(Binder.getCallingUid());
12251        synchronized (this) {
12252            // Iterate across all processes
12253            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12254                ProcessRecord app = mLruProcesses.get(i);
12255                if (!allUsers && app.userId != userId) {
12256                    continue;
12257                }
12258                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12259                    // Generate process state info for running application
12260                    ActivityManager.RunningAppProcessInfo currApp =
12261                        new ActivityManager.RunningAppProcessInfo(app.processName,
12262                                app.pid, app.getPackageList());
12263                    fillInProcMemInfo(app, currApp);
12264                    if (app.adjSource instanceof ProcessRecord) {
12265                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12266                        currApp.importanceReasonImportance =
12267                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12268                                        app.adjSourceProcState);
12269                    } else if (app.adjSource instanceof ActivityRecord) {
12270                        ActivityRecord r = (ActivityRecord)app.adjSource;
12271                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12272                    }
12273                    if (app.adjTarget instanceof ComponentName) {
12274                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12275                    }
12276                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12277                    //        + " lru=" + currApp.lru);
12278                    if (runList == null) {
12279                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12280                    }
12281                    runList.add(currApp);
12282                }
12283            }
12284        }
12285        return runList;
12286    }
12287
12288    public List<ApplicationInfo> getRunningExternalApplications() {
12289        enforceNotIsolatedCaller("getRunningExternalApplications");
12290        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12291        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12292        if (runningApps != null && runningApps.size() > 0) {
12293            Set<String> extList = new HashSet<String>();
12294            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12295                if (app.pkgList != null) {
12296                    for (String pkg : app.pkgList) {
12297                        extList.add(pkg);
12298                    }
12299                }
12300            }
12301            IPackageManager pm = AppGlobals.getPackageManager();
12302            for (String pkg : extList) {
12303                try {
12304                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12305                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12306                        retList.add(info);
12307                    }
12308                } catch (RemoteException e) {
12309                }
12310            }
12311        }
12312        return retList;
12313    }
12314
12315    @Override
12316    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12317        enforceNotIsolatedCaller("getMyMemoryState");
12318        synchronized (this) {
12319            ProcessRecord proc;
12320            synchronized (mPidsSelfLocked) {
12321                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12322            }
12323            fillInProcMemInfo(proc, outInfo);
12324        }
12325    }
12326
12327    @Override
12328    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12329        if (checkCallingPermission(android.Manifest.permission.DUMP)
12330                != PackageManager.PERMISSION_GRANTED) {
12331            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12332                    + Binder.getCallingPid()
12333                    + ", uid=" + Binder.getCallingUid()
12334                    + " without permission "
12335                    + android.Manifest.permission.DUMP);
12336            return;
12337        }
12338
12339        boolean dumpAll = false;
12340        boolean dumpClient = false;
12341        String dumpPackage = null;
12342
12343        int opti = 0;
12344        while (opti < args.length) {
12345            String opt = args[opti];
12346            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12347                break;
12348            }
12349            opti++;
12350            if ("-a".equals(opt)) {
12351                dumpAll = true;
12352            } else if ("-c".equals(opt)) {
12353                dumpClient = true;
12354            } else if ("-h".equals(opt)) {
12355                pw.println("Activity manager dump options:");
12356                pw.println("  [-a] [-c] [-h] [cmd] ...");
12357                pw.println("  cmd may be one of:");
12358                pw.println("    a[ctivities]: activity stack state");
12359                pw.println("    r[recents]: recent activities state");
12360                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12361                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12362                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12363                pw.println("    o[om]: out of memory management");
12364                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12365                pw.println("    provider [COMP_SPEC]: provider client-side state");
12366                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12367                pw.println("    service [COMP_SPEC]: service client-side state");
12368                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12369                pw.println("    all: dump all activities");
12370                pw.println("    top: dump the top activity");
12371                pw.println("    write: write all pending state to storage");
12372                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12373                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12374                pw.println("    a partial substring in a component name, a");
12375                pw.println("    hex object identifier.");
12376                pw.println("  -a: include all available server state.");
12377                pw.println("  -c: include client state.");
12378                return;
12379            } else {
12380                pw.println("Unknown argument: " + opt + "; use -h for help");
12381            }
12382        }
12383
12384        long origId = Binder.clearCallingIdentity();
12385        boolean more = false;
12386        // Is the caller requesting to dump a particular piece of data?
12387        if (opti < args.length) {
12388            String cmd = args[opti];
12389            opti++;
12390            if ("activities".equals(cmd) || "a".equals(cmd)) {
12391                synchronized (this) {
12392                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12393                }
12394            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12395                synchronized (this) {
12396                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12397                }
12398            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12399                String[] newArgs;
12400                String name;
12401                if (opti >= args.length) {
12402                    name = null;
12403                    newArgs = EMPTY_STRING_ARRAY;
12404                } else {
12405                    name = args[opti];
12406                    opti++;
12407                    newArgs = new String[args.length - opti];
12408                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12409                            args.length - opti);
12410                }
12411                synchronized (this) {
12412                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12413                }
12414            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12415                String[] newArgs;
12416                String name;
12417                if (opti >= args.length) {
12418                    name = null;
12419                    newArgs = EMPTY_STRING_ARRAY;
12420                } else {
12421                    name = args[opti];
12422                    opti++;
12423                    newArgs = new String[args.length - opti];
12424                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12425                            args.length - opti);
12426                }
12427                synchronized (this) {
12428                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12429                }
12430            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12431                String[] newArgs;
12432                String name;
12433                if (opti >= args.length) {
12434                    name = null;
12435                    newArgs = EMPTY_STRING_ARRAY;
12436                } else {
12437                    name = args[opti];
12438                    opti++;
12439                    newArgs = new String[args.length - opti];
12440                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12441                            args.length - opti);
12442                }
12443                synchronized (this) {
12444                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12445                }
12446            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12447                synchronized (this) {
12448                    dumpOomLocked(fd, pw, args, opti, true);
12449                }
12450            } else if ("provider".equals(cmd)) {
12451                String[] newArgs;
12452                String name;
12453                if (opti >= args.length) {
12454                    name = null;
12455                    newArgs = EMPTY_STRING_ARRAY;
12456                } else {
12457                    name = args[opti];
12458                    opti++;
12459                    newArgs = new String[args.length - opti];
12460                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12461                }
12462                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12463                    pw.println("No providers match: " + name);
12464                    pw.println("Use -h for help.");
12465                }
12466            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12467                synchronized (this) {
12468                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12469                }
12470            } else if ("service".equals(cmd)) {
12471                String[] newArgs;
12472                String name;
12473                if (opti >= args.length) {
12474                    name = null;
12475                    newArgs = EMPTY_STRING_ARRAY;
12476                } else {
12477                    name = args[opti];
12478                    opti++;
12479                    newArgs = new String[args.length - opti];
12480                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12481                            args.length - opti);
12482                }
12483                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12484                    pw.println("No services match: " + name);
12485                    pw.println("Use -h for help.");
12486                }
12487            } else if ("package".equals(cmd)) {
12488                String[] newArgs;
12489                if (opti >= args.length) {
12490                    pw.println("package: no package name specified");
12491                    pw.println("Use -h for help.");
12492                } else {
12493                    dumpPackage = args[opti];
12494                    opti++;
12495                    newArgs = new String[args.length - opti];
12496                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12497                            args.length - opti);
12498                    args = newArgs;
12499                    opti = 0;
12500                    more = true;
12501                }
12502            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12503                synchronized (this) {
12504                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12505                }
12506            } else if ("write".equals(cmd)) {
12507                mTaskPersister.flush();
12508                pw.println("All tasks persisted.");
12509                return;
12510            } else {
12511                // Dumping a single activity?
12512                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12513                    pw.println("Bad activity command, or no activities match: " + cmd);
12514                    pw.println("Use -h for help.");
12515                }
12516            }
12517            if (!more) {
12518                Binder.restoreCallingIdentity(origId);
12519                return;
12520            }
12521        }
12522
12523        // No piece of data specified, dump everything.
12524        synchronized (this) {
12525            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12526            pw.println();
12527            if (dumpAll) {
12528                pw.println("-------------------------------------------------------------------------------");
12529            }
12530            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12531            pw.println();
12532            if (dumpAll) {
12533                pw.println("-------------------------------------------------------------------------------");
12534            }
12535            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12536            pw.println();
12537            if (dumpAll) {
12538                pw.println("-------------------------------------------------------------------------------");
12539            }
12540            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12541            pw.println();
12542            if (dumpAll) {
12543                pw.println("-------------------------------------------------------------------------------");
12544            }
12545            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12546            pw.println();
12547            if (dumpAll) {
12548                pw.println("-------------------------------------------------------------------------------");
12549            }
12550            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12551            pw.println();
12552            if (dumpAll) {
12553                pw.println("-------------------------------------------------------------------------------");
12554            }
12555            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12556        }
12557        Binder.restoreCallingIdentity(origId);
12558    }
12559
12560    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12561            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12562        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12563
12564        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12565                dumpPackage);
12566        boolean needSep = printedAnything;
12567
12568        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12569                dumpPackage, needSep, "  mFocusedActivity: ");
12570        if (printed) {
12571            printedAnything = true;
12572            needSep = false;
12573        }
12574
12575        if (dumpPackage == null) {
12576            if (needSep) {
12577                pw.println();
12578            }
12579            needSep = true;
12580            printedAnything = true;
12581            mStackSupervisor.dump(pw, "  ");
12582        }
12583
12584        if (!printedAnything) {
12585            pw.println("  (nothing)");
12586        }
12587    }
12588
12589    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12590            int opti, boolean dumpAll, String dumpPackage) {
12591        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12592
12593        boolean printedAnything = false;
12594
12595        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12596            boolean printedHeader = false;
12597
12598            final int N = mRecentTasks.size();
12599            for (int i=0; i<N; i++) {
12600                TaskRecord tr = mRecentTasks.get(i);
12601                if (dumpPackage != null) {
12602                    if (tr.realActivity == null ||
12603                            !dumpPackage.equals(tr.realActivity)) {
12604                        continue;
12605                    }
12606                }
12607                if (!printedHeader) {
12608                    pw.println("  Recent tasks:");
12609                    printedHeader = true;
12610                    printedAnything = true;
12611                }
12612                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12613                        pw.println(tr);
12614                if (dumpAll) {
12615                    mRecentTasks.get(i).dump(pw, "    ");
12616                }
12617            }
12618        }
12619
12620        if (!printedAnything) {
12621            pw.println("  (nothing)");
12622        }
12623    }
12624
12625    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12626            int opti, boolean dumpAll, String dumpPackage) {
12627        boolean needSep = false;
12628        boolean printedAnything = false;
12629        int numPers = 0;
12630
12631        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12632
12633        if (dumpAll) {
12634            final int NP = mProcessNames.getMap().size();
12635            for (int ip=0; ip<NP; ip++) {
12636                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12637                final int NA = procs.size();
12638                for (int ia=0; ia<NA; ia++) {
12639                    ProcessRecord r = procs.valueAt(ia);
12640                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12641                        continue;
12642                    }
12643                    if (!needSep) {
12644                        pw.println("  All known processes:");
12645                        needSep = true;
12646                        printedAnything = true;
12647                    }
12648                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12649                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12650                        pw.print(" "); pw.println(r);
12651                    r.dump(pw, "    ");
12652                    if (r.persistent) {
12653                        numPers++;
12654                    }
12655                }
12656            }
12657        }
12658
12659        if (mIsolatedProcesses.size() > 0) {
12660            boolean printed = false;
12661            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12662                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12663                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12664                    continue;
12665                }
12666                if (!printed) {
12667                    if (needSep) {
12668                        pw.println();
12669                    }
12670                    pw.println("  Isolated process list (sorted by uid):");
12671                    printedAnything = true;
12672                    printed = true;
12673                    needSep = true;
12674                }
12675                pw.println(String.format("%sIsolated #%2d: %s",
12676                        "    ", i, r.toString()));
12677            }
12678        }
12679
12680        if (mLruProcesses.size() > 0) {
12681            if (needSep) {
12682                pw.println();
12683            }
12684            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12685                    pw.print(" total, non-act at ");
12686                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12687                    pw.print(", non-svc at ");
12688                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12689                    pw.println("):");
12690            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12691            needSep = true;
12692            printedAnything = true;
12693        }
12694
12695        if (dumpAll || dumpPackage != null) {
12696            synchronized (mPidsSelfLocked) {
12697                boolean printed = false;
12698                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12699                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12700                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12701                        continue;
12702                    }
12703                    if (!printed) {
12704                        if (needSep) pw.println();
12705                        needSep = true;
12706                        pw.println("  PID mappings:");
12707                        printed = true;
12708                        printedAnything = true;
12709                    }
12710                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12711                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12712                }
12713            }
12714        }
12715
12716        if (mForegroundProcesses.size() > 0) {
12717            synchronized (mPidsSelfLocked) {
12718                boolean printed = false;
12719                for (int i=0; i<mForegroundProcesses.size(); i++) {
12720                    ProcessRecord r = mPidsSelfLocked.get(
12721                            mForegroundProcesses.valueAt(i).pid);
12722                    if (dumpPackage != null && (r == null
12723                            || !r.pkgList.containsKey(dumpPackage))) {
12724                        continue;
12725                    }
12726                    if (!printed) {
12727                        if (needSep) pw.println();
12728                        needSep = true;
12729                        pw.println("  Foreground Processes:");
12730                        printed = true;
12731                        printedAnything = true;
12732                    }
12733                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12734                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12735                }
12736            }
12737        }
12738
12739        if (mPersistentStartingProcesses.size() > 0) {
12740            if (needSep) pw.println();
12741            needSep = true;
12742            printedAnything = true;
12743            pw.println("  Persisent processes that are starting:");
12744            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12745                    "Starting Norm", "Restarting PERS", dumpPackage);
12746        }
12747
12748        if (mRemovedProcesses.size() > 0) {
12749            if (needSep) pw.println();
12750            needSep = true;
12751            printedAnything = true;
12752            pw.println("  Processes that are being removed:");
12753            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12754                    "Removed Norm", "Removed PERS", dumpPackage);
12755        }
12756
12757        if (mProcessesOnHold.size() > 0) {
12758            if (needSep) pw.println();
12759            needSep = true;
12760            printedAnything = true;
12761            pw.println("  Processes that are on old until the system is ready:");
12762            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12763                    "OnHold Norm", "OnHold PERS", dumpPackage);
12764        }
12765
12766        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12767
12768        if (mProcessCrashTimes.getMap().size() > 0) {
12769            boolean printed = false;
12770            long now = SystemClock.uptimeMillis();
12771            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12772            final int NP = pmap.size();
12773            for (int ip=0; ip<NP; ip++) {
12774                String pname = pmap.keyAt(ip);
12775                SparseArray<Long> uids = pmap.valueAt(ip);
12776                final int N = uids.size();
12777                for (int i=0; i<N; i++) {
12778                    int puid = uids.keyAt(i);
12779                    ProcessRecord r = mProcessNames.get(pname, puid);
12780                    if (dumpPackage != null && (r == null
12781                            || !r.pkgList.containsKey(dumpPackage))) {
12782                        continue;
12783                    }
12784                    if (!printed) {
12785                        if (needSep) pw.println();
12786                        needSep = true;
12787                        pw.println("  Time since processes crashed:");
12788                        printed = true;
12789                        printedAnything = true;
12790                    }
12791                    pw.print("    Process "); pw.print(pname);
12792                            pw.print(" uid "); pw.print(puid);
12793                            pw.print(": last crashed ");
12794                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12795                            pw.println(" ago");
12796                }
12797            }
12798        }
12799
12800        if (mBadProcesses.getMap().size() > 0) {
12801            boolean printed = false;
12802            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12803            final int NP = pmap.size();
12804            for (int ip=0; ip<NP; ip++) {
12805                String pname = pmap.keyAt(ip);
12806                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12807                final int N = uids.size();
12808                for (int i=0; i<N; i++) {
12809                    int puid = uids.keyAt(i);
12810                    ProcessRecord r = mProcessNames.get(pname, puid);
12811                    if (dumpPackage != null && (r == null
12812                            || !r.pkgList.containsKey(dumpPackage))) {
12813                        continue;
12814                    }
12815                    if (!printed) {
12816                        if (needSep) pw.println();
12817                        needSep = true;
12818                        pw.println("  Bad processes:");
12819                        printedAnything = true;
12820                    }
12821                    BadProcessInfo info = uids.valueAt(i);
12822                    pw.print("    Bad process "); pw.print(pname);
12823                            pw.print(" uid "); pw.print(puid);
12824                            pw.print(": crashed at time "); pw.println(info.time);
12825                    if (info.shortMsg != null) {
12826                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12827                    }
12828                    if (info.longMsg != null) {
12829                        pw.print("      Long msg: "); pw.println(info.longMsg);
12830                    }
12831                    if (info.stack != null) {
12832                        pw.println("      Stack:");
12833                        int lastPos = 0;
12834                        for (int pos=0; pos<info.stack.length(); pos++) {
12835                            if (info.stack.charAt(pos) == '\n') {
12836                                pw.print("        ");
12837                                pw.write(info.stack, lastPos, pos-lastPos);
12838                                pw.println();
12839                                lastPos = pos+1;
12840                            }
12841                        }
12842                        if (lastPos < info.stack.length()) {
12843                            pw.print("        ");
12844                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12845                            pw.println();
12846                        }
12847                    }
12848                }
12849            }
12850        }
12851
12852        if (dumpPackage == null) {
12853            pw.println();
12854            needSep = false;
12855            pw.println("  mStartedUsers:");
12856            for (int i=0; i<mStartedUsers.size(); i++) {
12857                UserStartedState uss = mStartedUsers.valueAt(i);
12858                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12859                        pw.print(": "); uss.dump("", pw);
12860            }
12861            pw.print("  mStartedUserArray: [");
12862            for (int i=0; i<mStartedUserArray.length; i++) {
12863                if (i > 0) pw.print(", ");
12864                pw.print(mStartedUserArray[i]);
12865            }
12866            pw.println("]");
12867            pw.print("  mUserLru: [");
12868            for (int i=0; i<mUserLru.size(); i++) {
12869                if (i > 0) pw.print(", ");
12870                pw.print(mUserLru.get(i));
12871            }
12872            pw.println("]");
12873            if (dumpAll) {
12874                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12875            }
12876            synchronized (mUserProfileGroupIdsSelfLocked) {
12877                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12878                    pw.println("  mUserProfileGroupIds:");
12879                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12880                        pw.print("    User #");
12881                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12882                        pw.print(" -> profile #");
12883                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12884                    }
12885                }
12886            }
12887        }
12888        if (mHomeProcess != null && (dumpPackage == null
12889                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12890            if (needSep) {
12891                pw.println();
12892                needSep = false;
12893            }
12894            pw.println("  mHomeProcess: " + mHomeProcess);
12895        }
12896        if (mPreviousProcess != null && (dumpPackage == null
12897                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12898            if (needSep) {
12899                pw.println();
12900                needSep = false;
12901            }
12902            pw.println("  mPreviousProcess: " + mPreviousProcess);
12903        }
12904        if (dumpAll) {
12905            StringBuilder sb = new StringBuilder(128);
12906            sb.append("  mPreviousProcessVisibleTime: ");
12907            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12908            pw.println(sb);
12909        }
12910        if (mHeavyWeightProcess != null && (dumpPackage == null
12911                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12912            if (needSep) {
12913                pw.println();
12914                needSep = false;
12915            }
12916            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12917        }
12918        if (dumpPackage == null) {
12919            pw.println("  mConfiguration: " + mConfiguration);
12920        }
12921        if (dumpAll) {
12922            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12923            if (mCompatModePackages.getPackages().size() > 0) {
12924                boolean printed = false;
12925                for (Map.Entry<String, Integer> entry
12926                        : mCompatModePackages.getPackages().entrySet()) {
12927                    String pkg = entry.getKey();
12928                    int mode = entry.getValue();
12929                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12930                        continue;
12931                    }
12932                    if (!printed) {
12933                        pw.println("  mScreenCompatPackages:");
12934                        printed = true;
12935                    }
12936                    pw.print("    "); pw.print(pkg); pw.print(": ");
12937                            pw.print(mode); pw.println();
12938                }
12939            }
12940        }
12941        if (dumpPackage == null) {
12942            if (mSleeping || mWentToSleep || mLockScreenShown) {
12943                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12944                        + " mLockScreenShown " + mLockScreenShown);
12945            }
12946            if (mShuttingDown || mRunningVoice) {
12947                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12948            }
12949        }
12950        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12951                || mOrigWaitForDebugger) {
12952            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12953                    || dumpPackage.equals(mOrigDebugApp)) {
12954                if (needSep) {
12955                    pw.println();
12956                    needSep = false;
12957                }
12958                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12959                        + " mDebugTransient=" + mDebugTransient
12960                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12961            }
12962        }
12963        if (mOpenGlTraceApp != null) {
12964            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12965                if (needSep) {
12966                    pw.println();
12967                    needSep = false;
12968                }
12969                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12970            }
12971        }
12972        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12973                || mProfileFd != null) {
12974            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12975                if (needSep) {
12976                    pw.println();
12977                    needSep = false;
12978                }
12979                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12980                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12981                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12982                        + mAutoStopProfiler);
12983                pw.println("  mProfileType=" + mProfileType);
12984            }
12985        }
12986        if (dumpPackage == null) {
12987            if (mAlwaysFinishActivities || mController != null) {
12988                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12989                        + " mController=" + mController);
12990            }
12991            if (dumpAll) {
12992                pw.println("  Total persistent processes: " + numPers);
12993                pw.println("  mProcessesReady=" + mProcessesReady
12994                        + " mSystemReady=" + mSystemReady
12995                        + " mBooted=" + mBooted
12996                        + " mFactoryTest=" + mFactoryTest);
12997                pw.println("  mBooting=" + mBooting
12998                        + " mCallFinishBooting=" + mCallFinishBooting
12999                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13000                pw.print("  mLastPowerCheckRealtime=");
13001                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13002                        pw.println("");
13003                pw.print("  mLastPowerCheckUptime=");
13004                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13005                        pw.println("");
13006                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13007                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13008                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13009                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13010                        + " (" + mLruProcesses.size() + " total)"
13011                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13012                        + " mNumServiceProcs=" + mNumServiceProcs
13013                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13014                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13015                        + " mLastMemoryLevel" + mLastMemoryLevel
13016                        + " mLastNumProcesses" + mLastNumProcesses);
13017                long now = SystemClock.uptimeMillis();
13018                pw.print("  mLastIdleTime=");
13019                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13020                        pw.print(" mLowRamSinceLastIdle=");
13021                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13022                        pw.println();
13023            }
13024        }
13025
13026        if (!printedAnything) {
13027            pw.println("  (nothing)");
13028        }
13029    }
13030
13031    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13032            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13033        if (mProcessesToGc.size() > 0) {
13034            boolean printed = false;
13035            long now = SystemClock.uptimeMillis();
13036            for (int i=0; i<mProcessesToGc.size(); i++) {
13037                ProcessRecord proc = mProcessesToGc.get(i);
13038                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13039                    continue;
13040                }
13041                if (!printed) {
13042                    if (needSep) pw.println();
13043                    needSep = true;
13044                    pw.println("  Processes that are waiting to GC:");
13045                    printed = true;
13046                }
13047                pw.print("    Process "); pw.println(proc);
13048                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13049                        pw.print(", last gced=");
13050                        pw.print(now-proc.lastRequestedGc);
13051                        pw.print(" ms ago, last lowMem=");
13052                        pw.print(now-proc.lastLowMemory);
13053                        pw.println(" ms ago");
13054
13055            }
13056        }
13057        return needSep;
13058    }
13059
13060    void printOomLevel(PrintWriter pw, String name, int adj) {
13061        pw.print("    ");
13062        if (adj >= 0) {
13063            pw.print(' ');
13064            if (adj < 10) pw.print(' ');
13065        } else {
13066            if (adj > -10) pw.print(' ');
13067        }
13068        pw.print(adj);
13069        pw.print(": ");
13070        pw.print(name);
13071        pw.print(" (");
13072        pw.print(mProcessList.getMemLevel(adj)/1024);
13073        pw.println(" kB)");
13074    }
13075
13076    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13077            int opti, boolean dumpAll) {
13078        boolean needSep = false;
13079
13080        if (mLruProcesses.size() > 0) {
13081            if (needSep) pw.println();
13082            needSep = true;
13083            pw.println("  OOM levels:");
13084            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13085            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13086            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13087            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13088            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13089            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13090            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13091            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13092            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13093            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13094            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13095            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13096            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13097
13098            if (needSep) pw.println();
13099            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13100                    pw.print(" total, non-act at ");
13101                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13102                    pw.print(", non-svc at ");
13103                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13104                    pw.println("):");
13105            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13106            needSep = true;
13107        }
13108
13109        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13110
13111        pw.println();
13112        pw.println("  mHomeProcess: " + mHomeProcess);
13113        pw.println("  mPreviousProcess: " + mPreviousProcess);
13114        if (mHeavyWeightProcess != null) {
13115            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13116        }
13117
13118        return true;
13119    }
13120
13121    /**
13122     * There are three ways to call this:
13123     *  - no provider specified: dump all the providers
13124     *  - a flattened component name that matched an existing provider was specified as the
13125     *    first arg: dump that one provider
13126     *  - the first arg isn't the flattened component name of an existing provider:
13127     *    dump all providers whose component contains the first arg as a substring
13128     */
13129    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13130            int opti, boolean dumpAll) {
13131        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13132    }
13133
13134    static class ItemMatcher {
13135        ArrayList<ComponentName> components;
13136        ArrayList<String> strings;
13137        ArrayList<Integer> objects;
13138        boolean all;
13139
13140        ItemMatcher() {
13141            all = true;
13142        }
13143
13144        void build(String name) {
13145            ComponentName componentName = ComponentName.unflattenFromString(name);
13146            if (componentName != null) {
13147                if (components == null) {
13148                    components = new ArrayList<ComponentName>();
13149                }
13150                components.add(componentName);
13151                all = false;
13152            } else {
13153                int objectId = 0;
13154                // Not a '/' separated full component name; maybe an object ID?
13155                try {
13156                    objectId = Integer.parseInt(name, 16);
13157                    if (objects == null) {
13158                        objects = new ArrayList<Integer>();
13159                    }
13160                    objects.add(objectId);
13161                    all = false;
13162                } catch (RuntimeException e) {
13163                    // Not an integer; just do string match.
13164                    if (strings == null) {
13165                        strings = new ArrayList<String>();
13166                    }
13167                    strings.add(name);
13168                    all = false;
13169                }
13170            }
13171        }
13172
13173        int build(String[] args, int opti) {
13174            for (; opti<args.length; opti++) {
13175                String name = args[opti];
13176                if ("--".equals(name)) {
13177                    return opti+1;
13178                }
13179                build(name);
13180            }
13181            return opti;
13182        }
13183
13184        boolean match(Object object, ComponentName comp) {
13185            if (all) {
13186                return true;
13187            }
13188            if (components != null) {
13189                for (int i=0; i<components.size(); i++) {
13190                    if (components.get(i).equals(comp)) {
13191                        return true;
13192                    }
13193                }
13194            }
13195            if (objects != null) {
13196                for (int i=0; i<objects.size(); i++) {
13197                    if (System.identityHashCode(object) == objects.get(i)) {
13198                        return true;
13199                    }
13200                }
13201            }
13202            if (strings != null) {
13203                String flat = comp.flattenToString();
13204                for (int i=0; i<strings.size(); i++) {
13205                    if (flat.contains(strings.get(i))) {
13206                        return true;
13207                    }
13208                }
13209            }
13210            return false;
13211        }
13212    }
13213
13214    /**
13215     * There are three things that cmd can be:
13216     *  - a flattened component name that matches an existing activity
13217     *  - the cmd arg isn't the flattened component name of an existing activity:
13218     *    dump all activity whose component contains the cmd as a substring
13219     *  - A hex number of the ActivityRecord object instance.
13220     */
13221    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13222            int opti, boolean dumpAll) {
13223        ArrayList<ActivityRecord> activities;
13224
13225        synchronized (this) {
13226            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13227        }
13228
13229        if (activities.size() <= 0) {
13230            return false;
13231        }
13232
13233        String[] newArgs = new String[args.length - opti];
13234        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13235
13236        TaskRecord lastTask = null;
13237        boolean needSep = false;
13238        for (int i=activities.size()-1; i>=0; i--) {
13239            ActivityRecord r = activities.get(i);
13240            if (needSep) {
13241                pw.println();
13242            }
13243            needSep = true;
13244            synchronized (this) {
13245                if (lastTask != r.task) {
13246                    lastTask = r.task;
13247                    pw.print("TASK "); pw.print(lastTask.affinity);
13248                            pw.print(" id="); pw.println(lastTask.taskId);
13249                    if (dumpAll) {
13250                        lastTask.dump(pw, "  ");
13251                    }
13252                }
13253            }
13254            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13255        }
13256        return true;
13257    }
13258
13259    /**
13260     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13261     * there is a thread associated with the activity.
13262     */
13263    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13264            final ActivityRecord r, String[] args, boolean dumpAll) {
13265        String innerPrefix = prefix + "  ";
13266        synchronized (this) {
13267            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13268                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13269                    pw.print(" pid=");
13270                    if (r.app != null) pw.println(r.app.pid);
13271                    else pw.println("(not running)");
13272            if (dumpAll) {
13273                r.dump(pw, innerPrefix);
13274            }
13275        }
13276        if (r.app != null && r.app.thread != null) {
13277            // flush anything that is already in the PrintWriter since the thread is going
13278            // to write to the file descriptor directly
13279            pw.flush();
13280            try {
13281                TransferPipe tp = new TransferPipe();
13282                try {
13283                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13284                            r.appToken, innerPrefix, args);
13285                    tp.go(fd);
13286                } finally {
13287                    tp.kill();
13288                }
13289            } catch (IOException e) {
13290                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13291            } catch (RemoteException e) {
13292                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13293            }
13294        }
13295    }
13296
13297    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13298            int opti, boolean dumpAll, String dumpPackage) {
13299        boolean needSep = false;
13300        boolean onlyHistory = false;
13301        boolean printedAnything = false;
13302
13303        if ("history".equals(dumpPackage)) {
13304            if (opti < args.length && "-s".equals(args[opti])) {
13305                dumpAll = false;
13306            }
13307            onlyHistory = true;
13308            dumpPackage = null;
13309        }
13310
13311        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13312        if (!onlyHistory && dumpAll) {
13313            if (mRegisteredReceivers.size() > 0) {
13314                boolean printed = false;
13315                Iterator it = mRegisteredReceivers.values().iterator();
13316                while (it.hasNext()) {
13317                    ReceiverList r = (ReceiverList)it.next();
13318                    if (dumpPackage != null && (r.app == null ||
13319                            !dumpPackage.equals(r.app.info.packageName))) {
13320                        continue;
13321                    }
13322                    if (!printed) {
13323                        pw.println("  Registered Receivers:");
13324                        needSep = true;
13325                        printed = true;
13326                        printedAnything = true;
13327                    }
13328                    pw.print("  * "); pw.println(r);
13329                    r.dump(pw, "    ");
13330                }
13331            }
13332
13333            if (mReceiverResolver.dump(pw, needSep ?
13334                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13335                    "    ", dumpPackage, false)) {
13336                needSep = true;
13337                printedAnything = true;
13338            }
13339        }
13340
13341        for (BroadcastQueue q : mBroadcastQueues) {
13342            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13343            printedAnything |= needSep;
13344        }
13345
13346        needSep = true;
13347
13348        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13349            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13350                if (needSep) {
13351                    pw.println();
13352                }
13353                needSep = true;
13354                printedAnything = true;
13355                pw.print("  Sticky broadcasts for user ");
13356                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13357                StringBuilder sb = new StringBuilder(128);
13358                for (Map.Entry<String, ArrayList<Intent>> ent
13359                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13360                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13361                    if (dumpAll) {
13362                        pw.println(":");
13363                        ArrayList<Intent> intents = ent.getValue();
13364                        final int N = intents.size();
13365                        for (int i=0; i<N; i++) {
13366                            sb.setLength(0);
13367                            sb.append("    Intent: ");
13368                            intents.get(i).toShortString(sb, false, true, false, false);
13369                            pw.println(sb.toString());
13370                            Bundle bundle = intents.get(i).getExtras();
13371                            if (bundle != null) {
13372                                pw.print("      ");
13373                                pw.println(bundle.toString());
13374                            }
13375                        }
13376                    } else {
13377                        pw.println("");
13378                    }
13379                }
13380            }
13381        }
13382
13383        if (!onlyHistory && dumpAll) {
13384            pw.println();
13385            for (BroadcastQueue queue : mBroadcastQueues) {
13386                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13387                        + queue.mBroadcastsScheduled);
13388            }
13389            pw.println("  mHandler:");
13390            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13391            needSep = true;
13392            printedAnything = true;
13393        }
13394
13395        if (!printedAnything) {
13396            pw.println("  (nothing)");
13397        }
13398    }
13399
13400    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13401            int opti, boolean dumpAll, String dumpPackage) {
13402        boolean needSep;
13403        boolean printedAnything = false;
13404
13405        ItemMatcher matcher = new ItemMatcher();
13406        matcher.build(args, opti);
13407
13408        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13409
13410        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13411        printedAnything |= needSep;
13412
13413        if (mLaunchingProviders.size() > 0) {
13414            boolean printed = false;
13415            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13416                ContentProviderRecord r = mLaunchingProviders.get(i);
13417                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13418                    continue;
13419                }
13420                if (!printed) {
13421                    if (needSep) pw.println();
13422                    needSep = true;
13423                    pw.println("  Launching content providers:");
13424                    printed = true;
13425                    printedAnything = true;
13426                }
13427                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13428                        pw.println(r);
13429            }
13430        }
13431
13432        if (mGrantedUriPermissions.size() > 0) {
13433            boolean printed = false;
13434            int dumpUid = -2;
13435            if (dumpPackage != null) {
13436                try {
13437                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13438                } catch (NameNotFoundException e) {
13439                    dumpUid = -1;
13440                }
13441            }
13442            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13443                int uid = mGrantedUriPermissions.keyAt(i);
13444                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13445                    continue;
13446                }
13447                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13448                if (!printed) {
13449                    if (needSep) pw.println();
13450                    needSep = true;
13451                    pw.println("  Granted Uri Permissions:");
13452                    printed = true;
13453                    printedAnything = true;
13454                }
13455                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13456                for (UriPermission perm : perms.values()) {
13457                    pw.print("    "); pw.println(perm);
13458                    if (dumpAll) {
13459                        perm.dump(pw, "      ");
13460                    }
13461                }
13462            }
13463        }
13464
13465        if (!printedAnything) {
13466            pw.println("  (nothing)");
13467        }
13468    }
13469
13470    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13471            int opti, boolean dumpAll, String dumpPackage) {
13472        boolean printed = false;
13473
13474        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13475
13476        if (mIntentSenderRecords.size() > 0) {
13477            Iterator<WeakReference<PendingIntentRecord>> it
13478                    = mIntentSenderRecords.values().iterator();
13479            while (it.hasNext()) {
13480                WeakReference<PendingIntentRecord> ref = it.next();
13481                PendingIntentRecord rec = ref != null ? ref.get(): null;
13482                if (dumpPackage != null && (rec == null
13483                        || !dumpPackage.equals(rec.key.packageName))) {
13484                    continue;
13485                }
13486                printed = true;
13487                if (rec != null) {
13488                    pw.print("  * "); pw.println(rec);
13489                    if (dumpAll) {
13490                        rec.dump(pw, "    ");
13491                    }
13492                } else {
13493                    pw.print("  * "); pw.println(ref);
13494                }
13495            }
13496        }
13497
13498        if (!printed) {
13499            pw.println("  (nothing)");
13500        }
13501    }
13502
13503    private static final int dumpProcessList(PrintWriter pw,
13504            ActivityManagerService service, List list,
13505            String prefix, String normalLabel, String persistentLabel,
13506            String dumpPackage) {
13507        int numPers = 0;
13508        final int N = list.size()-1;
13509        for (int i=N; i>=0; i--) {
13510            ProcessRecord r = (ProcessRecord)list.get(i);
13511            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13512                continue;
13513            }
13514            pw.println(String.format("%s%s #%2d: %s",
13515                    prefix, (r.persistent ? persistentLabel : normalLabel),
13516                    i, r.toString()));
13517            if (r.persistent) {
13518                numPers++;
13519            }
13520        }
13521        return numPers;
13522    }
13523
13524    private static final boolean dumpProcessOomList(PrintWriter pw,
13525            ActivityManagerService service, List<ProcessRecord> origList,
13526            String prefix, String normalLabel, String persistentLabel,
13527            boolean inclDetails, String dumpPackage) {
13528
13529        ArrayList<Pair<ProcessRecord, Integer>> list
13530                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13531        for (int i=0; i<origList.size(); i++) {
13532            ProcessRecord r = origList.get(i);
13533            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13534                continue;
13535            }
13536            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13537        }
13538
13539        if (list.size() <= 0) {
13540            return false;
13541        }
13542
13543        Comparator<Pair<ProcessRecord, Integer>> comparator
13544                = new Comparator<Pair<ProcessRecord, Integer>>() {
13545            @Override
13546            public int compare(Pair<ProcessRecord, Integer> object1,
13547                    Pair<ProcessRecord, Integer> object2) {
13548                if (object1.first.setAdj != object2.first.setAdj) {
13549                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13550                }
13551                if (object1.second.intValue() != object2.second.intValue()) {
13552                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13553                }
13554                return 0;
13555            }
13556        };
13557
13558        Collections.sort(list, comparator);
13559
13560        final long curRealtime = SystemClock.elapsedRealtime();
13561        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13562        final long curUptime = SystemClock.uptimeMillis();
13563        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13564
13565        for (int i=list.size()-1; i>=0; i--) {
13566            ProcessRecord r = list.get(i).first;
13567            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13568            char schedGroup;
13569            switch (r.setSchedGroup) {
13570                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13571                    schedGroup = 'B';
13572                    break;
13573                case Process.THREAD_GROUP_DEFAULT:
13574                    schedGroup = 'F';
13575                    break;
13576                default:
13577                    schedGroup = '?';
13578                    break;
13579            }
13580            char foreground;
13581            if (r.foregroundActivities) {
13582                foreground = 'A';
13583            } else if (r.foregroundServices) {
13584                foreground = 'S';
13585            } else {
13586                foreground = ' ';
13587            }
13588            String procState = ProcessList.makeProcStateString(r.curProcState);
13589            pw.print(prefix);
13590            pw.print(r.persistent ? persistentLabel : normalLabel);
13591            pw.print(" #");
13592            int num = (origList.size()-1)-list.get(i).second;
13593            if (num < 10) pw.print(' ');
13594            pw.print(num);
13595            pw.print(": ");
13596            pw.print(oomAdj);
13597            pw.print(' ');
13598            pw.print(schedGroup);
13599            pw.print('/');
13600            pw.print(foreground);
13601            pw.print('/');
13602            pw.print(procState);
13603            pw.print(" trm:");
13604            if (r.trimMemoryLevel < 10) pw.print(' ');
13605            pw.print(r.trimMemoryLevel);
13606            pw.print(' ');
13607            pw.print(r.toShortString());
13608            pw.print(" (");
13609            pw.print(r.adjType);
13610            pw.println(')');
13611            if (r.adjSource != null || r.adjTarget != null) {
13612                pw.print(prefix);
13613                pw.print("    ");
13614                if (r.adjTarget instanceof ComponentName) {
13615                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13616                } else if (r.adjTarget != null) {
13617                    pw.print(r.adjTarget.toString());
13618                } else {
13619                    pw.print("{null}");
13620                }
13621                pw.print("<=");
13622                if (r.adjSource instanceof ProcessRecord) {
13623                    pw.print("Proc{");
13624                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13625                    pw.println("}");
13626                } else if (r.adjSource != null) {
13627                    pw.println(r.adjSource.toString());
13628                } else {
13629                    pw.println("{null}");
13630                }
13631            }
13632            if (inclDetails) {
13633                pw.print(prefix);
13634                pw.print("    ");
13635                pw.print("oom: max="); pw.print(r.maxAdj);
13636                pw.print(" curRaw="); pw.print(r.curRawAdj);
13637                pw.print(" setRaw="); pw.print(r.setRawAdj);
13638                pw.print(" cur="); pw.print(r.curAdj);
13639                pw.print(" set="); pw.println(r.setAdj);
13640                pw.print(prefix);
13641                pw.print("    ");
13642                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13643                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13644                pw.print(" lastPss="); pw.print(r.lastPss);
13645                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13646                pw.print(prefix);
13647                pw.print("    ");
13648                pw.print("cached="); pw.print(r.cached);
13649                pw.print(" empty="); pw.print(r.empty);
13650                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13651
13652                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13653                    if (r.lastWakeTime != 0) {
13654                        long wtime;
13655                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13656                        synchronized (stats) {
13657                            wtime = stats.getProcessWakeTime(r.info.uid,
13658                                    r.pid, curRealtime);
13659                        }
13660                        long timeUsed = wtime - r.lastWakeTime;
13661                        pw.print(prefix);
13662                        pw.print("    ");
13663                        pw.print("keep awake over ");
13664                        TimeUtils.formatDuration(realtimeSince, pw);
13665                        pw.print(" used ");
13666                        TimeUtils.formatDuration(timeUsed, pw);
13667                        pw.print(" (");
13668                        pw.print((timeUsed*100)/realtimeSince);
13669                        pw.println("%)");
13670                    }
13671                    if (r.lastCpuTime != 0) {
13672                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13673                        pw.print(prefix);
13674                        pw.print("    ");
13675                        pw.print("run cpu over ");
13676                        TimeUtils.formatDuration(uptimeSince, pw);
13677                        pw.print(" used ");
13678                        TimeUtils.formatDuration(timeUsed, pw);
13679                        pw.print(" (");
13680                        pw.print((timeUsed*100)/uptimeSince);
13681                        pw.println("%)");
13682                    }
13683                }
13684            }
13685        }
13686        return true;
13687    }
13688
13689    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13690            String[] args) {
13691        ArrayList<ProcessRecord> procs;
13692        synchronized (this) {
13693            if (args != null && args.length > start
13694                    && args[start].charAt(0) != '-') {
13695                procs = new ArrayList<ProcessRecord>();
13696                int pid = -1;
13697                try {
13698                    pid = Integer.parseInt(args[start]);
13699                } catch (NumberFormatException e) {
13700                }
13701                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13702                    ProcessRecord proc = mLruProcesses.get(i);
13703                    if (proc.pid == pid) {
13704                        procs.add(proc);
13705                    } else if (allPkgs && proc.pkgList != null
13706                            && proc.pkgList.containsKey(args[start])) {
13707                        procs.add(proc);
13708                    } else if (proc.processName.equals(args[start])) {
13709                        procs.add(proc);
13710                    }
13711                }
13712                if (procs.size() <= 0) {
13713                    return null;
13714                }
13715            } else {
13716                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13717            }
13718        }
13719        return procs;
13720    }
13721
13722    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13723            PrintWriter pw, String[] args) {
13724        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13725        if (procs == null) {
13726            pw.println("No process found for: " + args[0]);
13727            return;
13728        }
13729
13730        long uptime = SystemClock.uptimeMillis();
13731        long realtime = SystemClock.elapsedRealtime();
13732        pw.println("Applications Graphics Acceleration Info:");
13733        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13734
13735        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13736            ProcessRecord r = procs.get(i);
13737            if (r.thread != null) {
13738                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13739                pw.flush();
13740                try {
13741                    TransferPipe tp = new TransferPipe();
13742                    try {
13743                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13744                        tp.go(fd);
13745                    } finally {
13746                        tp.kill();
13747                    }
13748                } catch (IOException e) {
13749                    pw.println("Failure while dumping the app: " + r);
13750                    pw.flush();
13751                } catch (RemoteException e) {
13752                    pw.println("Got a RemoteException while dumping the app " + r);
13753                    pw.flush();
13754                }
13755            }
13756        }
13757    }
13758
13759    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13760        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13761        if (procs == null) {
13762            pw.println("No process found for: " + args[0]);
13763            return;
13764        }
13765
13766        pw.println("Applications Database Info:");
13767
13768        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13769            ProcessRecord r = procs.get(i);
13770            if (r.thread != null) {
13771                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13772                pw.flush();
13773                try {
13774                    TransferPipe tp = new TransferPipe();
13775                    try {
13776                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13777                        tp.go(fd);
13778                    } finally {
13779                        tp.kill();
13780                    }
13781                } catch (IOException e) {
13782                    pw.println("Failure while dumping the app: " + r);
13783                    pw.flush();
13784                } catch (RemoteException e) {
13785                    pw.println("Got a RemoteException while dumping the app " + r);
13786                    pw.flush();
13787                }
13788            }
13789        }
13790    }
13791
13792    final static class MemItem {
13793        final boolean isProc;
13794        final String label;
13795        final String shortLabel;
13796        final long pss;
13797        final int id;
13798        final boolean hasActivities;
13799        ArrayList<MemItem> subitems;
13800
13801        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13802                boolean _hasActivities) {
13803            isProc = true;
13804            label = _label;
13805            shortLabel = _shortLabel;
13806            pss = _pss;
13807            id = _id;
13808            hasActivities = _hasActivities;
13809        }
13810
13811        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13812            isProc = false;
13813            label = _label;
13814            shortLabel = _shortLabel;
13815            pss = _pss;
13816            id = _id;
13817            hasActivities = false;
13818        }
13819    }
13820
13821    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13822            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13823        if (sort && !isCompact) {
13824            Collections.sort(items, new Comparator<MemItem>() {
13825                @Override
13826                public int compare(MemItem lhs, MemItem rhs) {
13827                    if (lhs.pss < rhs.pss) {
13828                        return 1;
13829                    } else if (lhs.pss > rhs.pss) {
13830                        return -1;
13831                    }
13832                    return 0;
13833                }
13834            });
13835        }
13836
13837        for (int i=0; i<items.size(); i++) {
13838            MemItem mi = items.get(i);
13839            if (!isCompact) {
13840                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13841            } else if (mi.isProc) {
13842                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13843                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13844                pw.println(mi.hasActivities ? ",a" : ",e");
13845            } else {
13846                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13847                pw.println(mi.pss);
13848            }
13849            if (mi.subitems != null) {
13850                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13851                        true, isCompact);
13852            }
13853        }
13854    }
13855
13856    // These are in KB.
13857    static final long[] DUMP_MEM_BUCKETS = new long[] {
13858        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13859        120*1024, 160*1024, 200*1024,
13860        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13861        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13862    };
13863
13864    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13865            boolean stackLike) {
13866        int start = label.lastIndexOf('.');
13867        if (start >= 0) start++;
13868        else start = 0;
13869        int end = label.length();
13870        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13871            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13872                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13873                out.append(bucket);
13874                out.append(stackLike ? "MB." : "MB ");
13875                out.append(label, start, end);
13876                return;
13877            }
13878        }
13879        out.append(memKB/1024);
13880        out.append(stackLike ? "MB." : "MB ");
13881        out.append(label, start, end);
13882    }
13883
13884    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13885            ProcessList.NATIVE_ADJ,
13886            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13887            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13888            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13889            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13890            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13891    };
13892    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13893            "Native",
13894            "System", "Persistent", "Foreground",
13895            "Visible", "Perceptible",
13896            "Heavy Weight", "Backup",
13897            "A Services", "Home",
13898            "Previous", "B Services", "Cached"
13899    };
13900    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13901            "native",
13902            "sys", "pers", "fore",
13903            "vis", "percept",
13904            "heavy", "backup",
13905            "servicea", "home",
13906            "prev", "serviceb", "cached"
13907    };
13908
13909    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13910            long realtime, boolean isCheckinRequest, boolean isCompact) {
13911        if (isCheckinRequest || isCompact) {
13912            // short checkin version
13913            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13914        } else {
13915            pw.println("Applications Memory Usage (kB):");
13916            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13917        }
13918    }
13919
13920    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13921            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13922        boolean dumpDetails = false;
13923        boolean dumpFullDetails = false;
13924        boolean dumpDalvik = false;
13925        boolean oomOnly = false;
13926        boolean isCompact = false;
13927        boolean localOnly = false;
13928        boolean packages = false;
13929
13930        int opti = 0;
13931        while (opti < args.length) {
13932            String opt = args[opti];
13933            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13934                break;
13935            }
13936            opti++;
13937            if ("-a".equals(opt)) {
13938                dumpDetails = true;
13939                dumpFullDetails = true;
13940                dumpDalvik = true;
13941            } else if ("-d".equals(opt)) {
13942                dumpDalvik = true;
13943            } else if ("-c".equals(opt)) {
13944                isCompact = true;
13945            } else if ("--oom".equals(opt)) {
13946                oomOnly = true;
13947            } else if ("--local".equals(opt)) {
13948                localOnly = true;
13949            } else if ("--package".equals(opt)) {
13950                packages = true;
13951            } else if ("-h".equals(opt)) {
13952                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13953                pw.println("  -a: include all available information for each process.");
13954                pw.println("  -d: include dalvik details when dumping process details.");
13955                pw.println("  -c: dump in a compact machine-parseable representation.");
13956                pw.println("  --oom: only show processes organized by oom adj.");
13957                pw.println("  --local: only collect details locally, don't call process.");
13958                pw.println("  --package: interpret process arg as package, dumping all");
13959                pw.println("             processes that have loaded that package.");
13960                pw.println("If [process] is specified it can be the name or ");
13961                pw.println("pid of a specific process to dump.");
13962                return;
13963            } else {
13964                pw.println("Unknown argument: " + opt + "; use -h for help");
13965            }
13966        }
13967
13968        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13969        long uptime = SystemClock.uptimeMillis();
13970        long realtime = SystemClock.elapsedRealtime();
13971        final long[] tmpLong = new long[1];
13972
13973        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13974        if (procs == null) {
13975            // No Java processes.  Maybe they want to print a native process.
13976            if (args != null && args.length > opti
13977                    && args[opti].charAt(0) != '-') {
13978                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13979                        = new ArrayList<ProcessCpuTracker.Stats>();
13980                updateCpuStatsNow();
13981                int findPid = -1;
13982                try {
13983                    findPid = Integer.parseInt(args[opti]);
13984                } catch (NumberFormatException e) {
13985                }
13986                synchronized (mProcessCpuTracker) {
13987                    final int N = mProcessCpuTracker.countStats();
13988                    for (int i=0; i<N; i++) {
13989                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13990                        if (st.pid == findPid || (st.baseName != null
13991                                && st.baseName.equals(args[opti]))) {
13992                            nativeProcs.add(st);
13993                        }
13994                    }
13995                }
13996                if (nativeProcs.size() > 0) {
13997                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13998                            isCompact);
13999                    Debug.MemoryInfo mi = null;
14000                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14001                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14002                        final int pid = r.pid;
14003                        if (!isCheckinRequest && dumpDetails) {
14004                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14005                        }
14006                        if (mi == null) {
14007                            mi = new Debug.MemoryInfo();
14008                        }
14009                        if (dumpDetails || (!brief && !oomOnly)) {
14010                            Debug.getMemoryInfo(pid, mi);
14011                        } else {
14012                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14013                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14014                        }
14015                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14016                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14017                        if (isCheckinRequest) {
14018                            pw.println();
14019                        }
14020                    }
14021                    return;
14022                }
14023            }
14024            pw.println("No process found for: " + args[opti]);
14025            return;
14026        }
14027
14028        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14029            dumpDetails = true;
14030        }
14031
14032        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14033
14034        String[] innerArgs = new String[args.length-opti];
14035        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14036
14037        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14038        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14039        long nativePss=0, dalvikPss=0, otherPss=0;
14040        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14041
14042        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14043        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14044                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14045
14046        long totalPss = 0;
14047        long cachedPss = 0;
14048
14049        Debug.MemoryInfo mi = null;
14050        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14051            final ProcessRecord r = procs.get(i);
14052            final IApplicationThread thread;
14053            final int pid;
14054            final int oomAdj;
14055            final boolean hasActivities;
14056            synchronized (this) {
14057                thread = r.thread;
14058                pid = r.pid;
14059                oomAdj = r.getSetAdjWithServices();
14060                hasActivities = r.activities.size() > 0;
14061            }
14062            if (thread != null) {
14063                if (!isCheckinRequest && dumpDetails) {
14064                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14065                }
14066                if (mi == null) {
14067                    mi = new Debug.MemoryInfo();
14068                }
14069                if (dumpDetails || (!brief && !oomOnly)) {
14070                    Debug.getMemoryInfo(pid, mi);
14071                } else {
14072                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14073                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14074                }
14075                if (dumpDetails) {
14076                    if (localOnly) {
14077                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14078                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14079                        if (isCheckinRequest) {
14080                            pw.println();
14081                        }
14082                    } else {
14083                        try {
14084                            pw.flush();
14085                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14086                                    dumpDalvik, innerArgs);
14087                        } catch (RemoteException e) {
14088                            if (!isCheckinRequest) {
14089                                pw.println("Got RemoteException!");
14090                                pw.flush();
14091                            }
14092                        }
14093                    }
14094                }
14095
14096                final long myTotalPss = mi.getTotalPss();
14097                final long myTotalUss = mi.getTotalUss();
14098
14099                synchronized (this) {
14100                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14101                        // Record this for posterity if the process has been stable.
14102                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14103                    }
14104                }
14105
14106                if (!isCheckinRequest && mi != null) {
14107                    totalPss += myTotalPss;
14108                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14109                            (hasActivities ? " / activities)" : ")"),
14110                            r.processName, myTotalPss, pid, hasActivities);
14111                    procMems.add(pssItem);
14112                    procMemsMap.put(pid, pssItem);
14113
14114                    nativePss += mi.nativePss;
14115                    dalvikPss += mi.dalvikPss;
14116                    otherPss += mi.otherPss;
14117                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14118                        long mem = mi.getOtherPss(j);
14119                        miscPss[j] += mem;
14120                        otherPss -= mem;
14121                    }
14122
14123                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14124                        cachedPss += myTotalPss;
14125                    }
14126
14127                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14128                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14129                                || oomIndex == (oomPss.length-1)) {
14130                            oomPss[oomIndex] += myTotalPss;
14131                            if (oomProcs[oomIndex] == null) {
14132                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14133                            }
14134                            oomProcs[oomIndex].add(pssItem);
14135                            break;
14136                        }
14137                    }
14138                }
14139            }
14140        }
14141
14142        long nativeProcTotalPss = 0;
14143
14144        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14145            // If we are showing aggregations, also look for native processes to
14146            // include so that our aggregations are more accurate.
14147            updateCpuStatsNow();
14148            synchronized (mProcessCpuTracker) {
14149                final int N = mProcessCpuTracker.countStats();
14150                for (int i=0; i<N; i++) {
14151                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14152                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14153                        if (mi == null) {
14154                            mi = new Debug.MemoryInfo();
14155                        }
14156                        if (!brief && !oomOnly) {
14157                            Debug.getMemoryInfo(st.pid, mi);
14158                        } else {
14159                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14160                            mi.nativePrivateDirty = (int)tmpLong[0];
14161                        }
14162
14163                        final long myTotalPss = mi.getTotalPss();
14164                        totalPss += myTotalPss;
14165                        nativeProcTotalPss += myTotalPss;
14166
14167                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14168                                st.name, myTotalPss, st.pid, false);
14169                        procMems.add(pssItem);
14170
14171                        nativePss += mi.nativePss;
14172                        dalvikPss += mi.dalvikPss;
14173                        otherPss += mi.otherPss;
14174                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14175                            long mem = mi.getOtherPss(j);
14176                            miscPss[j] += mem;
14177                            otherPss -= mem;
14178                        }
14179                        oomPss[0] += myTotalPss;
14180                        if (oomProcs[0] == null) {
14181                            oomProcs[0] = new ArrayList<MemItem>();
14182                        }
14183                        oomProcs[0].add(pssItem);
14184                    }
14185                }
14186            }
14187
14188            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14189
14190            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14191            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14192            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14193            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14194                String label = Debug.MemoryInfo.getOtherLabel(j);
14195                catMems.add(new MemItem(label, label, miscPss[j], j));
14196            }
14197
14198            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14199            for (int j=0; j<oomPss.length; j++) {
14200                if (oomPss[j] != 0) {
14201                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14202                            : DUMP_MEM_OOM_LABEL[j];
14203                    MemItem item = new MemItem(label, label, oomPss[j],
14204                            DUMP_MEM_OOM_ADJ[j]);
14205                    item.subitems = oomProcs[j];
14206                    oomMems.add(item);
14207                }
14208            }
14209
14210            if (!brief && !oomOnly && !isCompact) {
14211                pw.println();
14212                pw.println("Total PSS by process:");
14213                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14214                pw.println();
14215            }
14216            if (!isCompact) {
14217                pw.println("Total PSS by OOM adjustment:");
14218            }
14219            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14220            if (!brief && !oomOnly) {
14221                PrintWriter out = categoryPw != null ? categoryPw : pw;
14222                if (!isCompact) {
14223                    out.println();
14224                    out.println("Total PSS by category:");
14225                }
14226                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14227            }
14228            if (!isCompact) {
14229                pw.println();
14230            }
14231            MemInfoReader memInfo = new MemInfoReader();
14232            memInfo.readMemInfo();
14233            if (nativeProcTotalPss > 0) {
14234                synchronized (this) {
14235                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14236                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14237                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14238                            nativeProcTotalPss);
14239                }
14240            }
14241            if (!brief) {
14242                if (!isCompact) {
14243                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14244                    pw.print(" kB (status ");
14245                    switch (mLastMemoryLevel) {
14246                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14247                            pw.println("normal)");
14248                            break;
14249                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14250                            pw.println("moderate)");
14251                            break;
14252                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14253                            pw.println("low)");
14254                            break;
14255                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14256                            pw.println("critical)");
14257                            break;
14258                        default:
14259                            pw.print(mLastMemoryLevel);
14260                            pw.println(")");
14261                            break;
14262                    }
14263                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14264                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14265                            pw.print(cachedPss); pw.print(" cached pss + ");
14266                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14267                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14268                } else {
14269                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14270                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14271                            + memInfo.getFreeSizeKb()); pw.print(",");
14272                    pw.println(totalPss - cachedPss);
14273                }
14274            }
14275            if (!isCompact) {
14276                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14277                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14278                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14279                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14280                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14281                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14282                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14283                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14284                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14285                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14286                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14287            }
14288            if (!brief) {
14289                if (memInfo.getZramTotalSizeKb() != 0) {
14290                    if (!isCompact) {
14291                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14292                                pw.print(" kB physical used for ");
14293                                pw.print(memInfo.getSwapTotalSizeKb()
14294                                        - memInfo.getSwapFreeSizeKb());
14295                                pw.print(" kB in swap (");
14296                                pw.print(memInfo.getSwapTotalSizeKb());
14297                                pw.println(" kB total swap)");
14298                    } else {
14299                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14300                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14301                                pw.println(memInfo.getSwapFreeSizeKb());
14302                    }
14303                }
14304                final int[] SINGLE_LONG_FORMAT = new int[] {
14305                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14306                };
14307                long[] longOut = new long[1];
14308                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14309                        SINGLE_LONG_FORMAT, null, longOut, null);
14310                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14311                longOut[0] = 0;
14312                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14313                        SINGLE_LONG_FORMAT, null, longOut, null);
14314                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14315                longOut[0] = 0;
14316                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14317                        SINGLE_LONG_FORMAT, null, longOut, null);
14318                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14319                longOut[0] = 0;
14320                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14321                        SINGLE_LONG_FORMAT, null, longOut, null);
14322                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14323                if (!isCompact) {
14324                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14325                        pw.print("      KSM: "); pw.print(sharing);
14326                                pw.print(" kB saved from shared ");
14327                                pw.print(shared); pw.println(" kB");
14328                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14329                                pw.print(voltile); pw.println(" kB volatile");
14330                    }
14331                    pw.print("   Tuning: ");
14332                    pw.print(ActivityManager.staticGetMemoryClass());
14333                    pw.print(" (large ");
14334                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14335                    pw.print("), oom ");
14336                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14337                    pw.print(" kB");
14338                    pw.print(", restore limit ");
14339                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14340                    pw.print(" kB");
14341                    if (ActivityManager.isLowRamDeviceStatic()) {
14342                        pw.print(" (low-ram)");
14343                    }
14344                    if (ActivityManager.isHighEndGfx()) {
14345                        pw.print(" (high-end-gfx)");
14346                    }
14347                    pw.println();
14348                } else {
14349                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14350                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14351                    pw.println(voltile);
14352                    pw.print("tuning,");
14353                    pw.print(ActivityManager.staticGetMemoryClass());
14354                    pw.print(',');
14355                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14356                    pw.print(',');
14357                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14358                    if (ActivityManager.isLowRamDeviceStatic()) {
14359                        pw.print(",low-ram");
14360                    }
14361                    if (ActivityManager.isHighEndGfx()) {
14362                        pw.print(",high-end-gfx");
14363                    }
14364                    pw.println();
14365                }
14366            }
14367        }
14368    }
14369
14370    /**
14371     * Searches array of arguments for the specified string
14372     * @param args array of argument strings
14373     * @param value value to search for
14374     * @return true if the value is contained in the array
14375     */
14376    private static boolean scanArgs(String[] args, String value) {
14377        if (args != null) {
14378            for (String arg : args) {
14379                if (value.equals(arg)) {
14380                    return true;
14381                }
14382            }
14383        }
14384        return false;
14385    }
14386
14387    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14388            ContentProviderRecord cpr, boolean always) {
14389        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14390
14391        if (!inLaunching || always) {
14392            synchronized (cpr) {
14393                cpr.launchingApp = null;
14394                cpr.notifyAll();
14395            }
14396            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14397            String names[] = cpr.info.authority.split(";");
14398            for (int j = 0; j < names.length; j++) {
14399                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14400            }
14401        }
14402
14403        for (int i=0; i<cpr.connections.size(); i++) {
14404            ContentProviderConnection conn = cpr.connections.get(i);
14405            if (conn.waiting) {
14406                // If this connection is waiting for the provider, then we don't
14407                // need to mess with its process unless we are always removing
14408                // or for some reason the provider is not currently launching.
14409                if (inLaunching && !always) {
14410                    continue;
14411                }
14412            }
14413            ProcessRecord capp = conn.client;
14414            conn.dead = true;
14415            if (conn.stableCount > 0) {
14416                if (!capp.persistent && capp.thread != null
14417                        && capp.pid != 0
14418                        && capp.pid != MY_PID) {
14419                    capp.kill("depends on provider "
14420                            + cpr.name.flattenToShortString()
14421                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14422                }
14423            } else if (capp.thread != null && conn.provider.provider != null) {
14424                try {
14425                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14426                } catch (RemoteException e) {
14427                }
14428                // In the protocol here, we don't expect the client to correctly
14429                // clean up this connection, we'll just remove it.
14430                cpr.connections.remove(i);
14431                conn.client.conProviders.remove(conn);
14432            }
14433        }
14434
14435        if (inLaunching && always) {
14436            mLaunchingProviders.remove(cpr);
14437        }
14438        return inLaunching;
14439    }
14440
14441    /**
14442     * Main code for cleaning up a process when it has gone away.  This is
14443     * called both as a result of the process dying, or directly when stopping
14444     * a process when running in single process mode.
14445     *
14446     * @return Returns true if the given process has been restarted, so the
14447     * app that was passed in must remain on the process lists.
14448     */
14449    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14450            boolean restarting, boolean allowRestart, int index) {
14451        if (index >= 0) {
14452            removeLruProcessLocked(app);
14453            ProcessList.remove(app.pid);
14454        }
14455
14456        mProcessesToGc.remove(app);
14457        mPendingPssProcesses.remove(app);
14458
14459        // Dismiss any open dialogs.
14460        if (app.crashDialog != null && !app.forceCrashReport) {
14461            app.crashDialog.dismiss();
14462            app.crashDialog = null;
14463        }
14464        if (app.anrDialog != null) {
14465            app.anrDialog.dismiss();
14466            app.anrDialog = null;
14467        }
14468        if (app.waitDialog != null) {
14469            app.waitDialog.dismiss();
14470            app.waitDialog = null;
14471        }
14472
14473        app.crashing = false;
14474        app.notResponding = false;
14475
14476        app.resetPackageList(mProcessStats);
14477        app.unlinkDeathRecipient();
14478        app.makeInactive(mProcessStats);
14479        app.waitingToKill = null;
14480        app.forcingToForeground = null;
14481        updateProcessForegroundLocked(app, false, false);
14482        app.foregroundActivities = false;
14483        app.hasShownUi = false;
14484        app.treatLikeActivity = false;
14485        app.hasAboveClient = false;
14486        app.hasClientActivities = false;
14487
14488        mServices.killServicesLocked(app, allowRestart);
14489
14490        boolean restart = false;
14491
14492        // Remove published content providers.
14493        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14494            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14495            final boolean always = app.bad || !allowRestart;
14496            if (removeDyingProviderLocked(app, cpr, always) || always) {
14497                // We left the provider in the launching list, need to
14498                // restart it.
14499                restart = true;
14500            }
14501
14502            cpr.provider = null;
14503            cpr.proc = null;
14504        }
14505        app.pubProviders.clear();
14506
14507        // Take care of any launching providers waiting for this process.
14508        if (checkAppInLaunchingProvidersLocked(app, false)) {
14509            restart = true;
14510        }
14511
14512        // Unregister from connected content providers.
14513        if (!app.conProviders.isEmpty()) {
14514            for (int i=0; i<app.conProviders.size(); i++) {
14515                ContentProviderConnection conn = app.conProviders.get(i);
14516                conn.provider.connections.remove(conn);
14517            }
14518            app.conProviders.clear();
14519        }
14520
14521        // At this point there may be remaining entries in mLaunchingProviders
14522        // where we were the only one waiting, so they are no longer of use.
14523        // Look for these and clean up if found.
14524        // XXX Commented out for now.  Trying to figure out a way to reproduce
14525        // the actual situation to identify what is actually going on.
14526        if (false) {
14527            for (int i=0; i<mLaunchingProviders.size(); i++) {
14528                ContentProviderRecord cpr = (ContentProviderRecord)
14529                        mLaunchingProviders.get(i);
14530                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14531                    synchronized (cpr) {
14532                        cpr.launchingApp = null;
14533                        cpr.notifyAll();
14534                    }
14535                }
14536            }
14537        }
14538
14539        skipCurrentReceiverLocked(app);
14540
14541        // Unregister any receivers.
14542        for (int i=app.receivers.size()-1; i>=0; i--) {
14543            removeReceiverLocked(app.receivers.valueAt(i));
14544        }
14545        app.receivers.clear();
14546
14547        // If the app is undergoing backup, tell the backup manager about it
14548        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14549            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14550                    + mBackupTarget.appInfo + " died during backup");
14551            try {
14552                IBackupManager bm = IBackupManager.Stub.asInterface(
14553                        ServiceManager.getService(Context.BACKUP_SERVICE));
14554                bm.agentDisconnected(app.info.packageName);
14555            } catch (RemoteException e) {
14556                // can't happen; backup manager is local
14557            }
14558        }
14559
14560        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14561            ProcessChangeItem item = mPendingProcessChanges.get(i);
14562            if (item.pid == app.pid) {
14563                mPendingProcessChanges.remove(i);
14564                mAvailProcessChanges.add(item);
14565            }
14566        }
14567        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14568
14569        // If the caller is restarting this app, then leave it in its
14570        // current lists and let the caller take care of it.
14571        if (restarting) {
14572            return false;
14573        }
14574
14575        if (!app.persistent || app.isolated) {
14576            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14577                    "Removing non-persistent process during cleanup: " + app);
14578            mProcessNames.remove(app.processName, app.uid);
14579            mIsolatedProcesses.remove(app.uid);
14580            if (mHeavyWeightProcess == app) {
14581                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14582                        mHeavyWeightProcess.userId, 0));
14583                mHeavyWeightProcess = null;
14584            }
14585        } else if (!app.removed) {
14586            // This app is persistent, so we need to keep its record around.
14587            // If it is not already on the pending app list, add it there
14588            // and start a new process for it.
14589            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14590                mPersistentStartingProcesses.add(app);
14591                restart = true;
14592            }
14593        }
14594        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14595                "Clean-up removing on hold: " + app);
14596        mProcessesOnHold.remove(app);
14597
14598        if (app == mHomeProcess) {
14599            mHomeProcess = null;
14600        }
14601        if (app == mPreviousProcess) {
14602            mPreviousProcess = null;
14603        }
14604
14605        if (restart && !app.isolated) {
14606            // We have components that still need to be running in the
14607            // process, so re-launch it.
14608            if (index < 0) {
14609                ProcessList.remove(app.pid);
14610            }
14611            mProcessNames.put(app.processName, app.uid, app);
14612            startProcessLocked(app, "restart", app.processName);
14613            return true;
14614        } else if (app.pid > 0 && app.pid != MY_PID) {
14615            // Goodbye!
14616            boolean removed;
14617            synchronized (mPidsSelfLocked) {
14618                mPidsSelfLocked.remove(app.pid);
14619                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14620            }
14621            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14622            if (app.isolated) {
14623                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14624            }
14625            app.setPid(0);
14626        }
14627        return false;
14628    }
14629
14630    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14631        // Look through the content providers we are waiting to have launched,
14632        // and if any run in this process then either schedule a restart of
14633        // the process or kill the client waiting for it if this process has
14634        // gone bad.
14635        int NL = mLaunchingProviders.size();
14636        boolean restart = false;
14637        for (int i=0; i<NL; i++) {
14638            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14639            if (cpr.launchingApp == app) {
14640                if (!alwaysBad && !app.bad) {
14641                    restart = true;
14642                } else {
14643                    removeDyingProviderLocked(app, cpr, true);
14644                    // cpr should have been removed from mLaunchingProviders
14645                    NL = mLaunchingProviders.size();
14646                    i--;
14647                }
14648            }
14649        }
14650        return restart;
14651    }
14652
14653    // =========================================================
14654    // SERVICES
14655    // =========================================================
14656
14657    @Override
14658    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14659            int flags) {
14660        enforceNotIsolatedCaller("getServices");
14661        synchronized (this) {
14662            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14663        }
14664    }
14665
14666    @Override
14667    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14668        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14669        synchronized (this) {
14670            return mServices.getRunningServiceControlPanelLocked(name);
14671        }
14672    }
14673
14674    @Override
14675    public ComponentName startService(IApplicationThread caller, Intent service,
14676            String resolvedType, int userId) {
14677        enforceNotIsolatedCaller("startService");
14678        // Refuse possible leaked file descriptors
14679        if (service != null && service.hasFileDescriptors() == true) {
14680            throw new IllegalArgumentException("File descriptors passed in Intent");
14681        }
14682
14683        if (DEBUG_SERVICE)
14684            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14685        synchronized(this) {
14686            final int callingPid = Binder.getCallingPid();
14687            final int callingUid = Binder.getCallingUid();
14688            final long origId = Binder.clearCallingIdentity();
14689            ComponentName res = mServices.startServiceLocked(caller, service,
14690                    resolvedType, callingPid, callingUid, userId);
14691            Binder.restoreCallingIdentity(origId);
14692            return res;
14693        }
14694    }
14695
14696    ComponentName startServiceInPackage(int uid,
14697            Intent service, String resolvedType, int userId) {
14698        synchronized(this) {
14699            if (DEBUG_SERVICE)
14700                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14701            final long origId = Binder.clearCallingIdentity();
14702            ComponentName res = mServices.startServiceLocked(null, service,
14703                    resolvedType, -1, uid, userId);
14704            Binder.restoreCallingIdentity(origId);
14705            return res;
14706        }
14707    }
14708
14709    @Override
14710    public int stopService(IApplicationThread caller, Intent service,
14711            String resolvedType, int userId) {
14712        enforceNotIsolatedCaller("stopService");
14713        // Refuse possible leaked file descriptors
14714        if (service != null && service.hasFileDescriptors() == true) {
14715            throw new IllegalArgumentException("File descriptors passed in Intent");
14716        }
14717
14718        synchronized(this) {
14719            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14720        }
14721    }
14722
14723    @Override
14724    public IBinder peekService(Intent service, String resolvedType) {
14725        enforceNotIsolatedCaller("peekService");
14726        // Refuse possible leaked file descriptors
14727        if (service != null && service.hasFileDescriptors() == true) {
14728            throw new IllegalArgumentException("File descriptors passed in Intent");
14729        }
14730        synchronized(this) {
14731            return mServices.peekServiceLocked(service, resolvedType);
14732        }
14733    }
14734
14735    @Override
14736    public boolean stopServiceToken(ComponentName className, IBinder token,
14737            int startId) {
14738        synchronized(this) {
14739            return mServices.stopServiceTokenLocked(className, token, startId);
14740        }
14741    }
14742
14743    @Override
14744    public void setServiceForeground(ComponentName className, IBinder token,
14745            int id, Notification notification, boolean removeNotification) {
14746        synchronized(this) {
14747            mServices.setServiceForegroundLocked(className, token, id, notification,
14748                    removeNotification);
14749        }
14750    }
14751
14752    @Override
14753    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14754            boolean requireFull, String name, String callerPackage) {
14755        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14756                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14757    }
14758
14759    int unsafeConvertIncomingUser(int userId) {
14760        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14761                ? mCurrentUserId : userId;
14762    }
14763
14764    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14765            int allowMode, String name, String callerPackage) {
14766        final int callingUserId = UserHandle.getUserId(callingUid);
14767        if (callingUserId == userId) {
14768            return userId;
14769        }
14770
14771        // Note that we may be accessing mCurrentUserId outside of a lock...
14772        // shouldn't be a big deal, if this is being called outside
14773        // of a locked context there is intrinsically a race with
14774        // the value the caller will receive and someone else changing it.
14775        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14776        // we will switch to the calling user if access to the current user fails.
14777        int targetUserId = unsafeConvertIncomingUser(userId);
14778
14779        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14780            final boolean allow;
14781            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14782                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14783                // If the caller has this permission, they always pass go.  And collect $200.
14784                allow = true;
14785            } else if (allowMode == ALLOW_FULL_ONLY) {
14786                // We require full access, sucks to be you.
14787                allow = false;
14788            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14789                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14790                // If the caller does not have either permission, they are always doomed.
14791                allow = false;
14792            } else if (allowMode == ALLOW_NON_FULL) {
14793                // We are blanket allowing non-full access, you lucky caller!
14794                allow = true;
14795            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14796                // We may or may not allow this depending on whether the two users are
14797                // in the same profile.
14798                synchronized (mUserProfileGroupIdsSelfLocked) {
14799                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14800                            UserInfo.NO_PROFILE_GROUP_ID);
14801                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14802                            UserInfo.NO_PROFILE_GROUP_ID);
14803                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14804                            && callingProfile == targetProfile;
14805                }
14806            } else {
14807                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14808            }
14809            if (!allow) {
14810                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14811                    // In this case, they would like to just execute as their
14812                    // owner user instead of failing.
14813                    targetUserId = callingUserId;
14814                } else {
14815                    StringBuilder builder = new StringBuilder(128);
14816                    builder.append("Permission Denial: ");
14817                    builder.append(name);
14818                    if (callerPackage != null) {
14819                        builder.append(" from ");
14820                        builder.append(callerPackage);
14821                    }
14822                    builder.append(" asks to run as user ");
14823                    builder.append(userId);
14824                    builder.append(" but is calling from user ");
14825                    builder.append(UserHandle.getUserId(callingUid));
14826                    builder.append("; this requires ");
14827                    builder.append(INTERACT_ACROSS_USERS_FULL);
14828                    if (allowMode != ALLOW_FULL_ONLY) {
14829                        builder.append(" or ");
14830                        builder.append(INTERACT_ACROSS_USERS);
14831                    }
14832                    String msg = builder.toString();
14833                    Slog.w(TAG, msg);
14834                    throw new SecurityException(msg);
14835                }
14836            }
14837        }
14838        if (!allowAll && targetUserId < 0) {
14839            throw new IllegalArgumentException(
14840                    "Call does not support special user #" + targetUserId);
14841        }
14842        // Check shell permission
14843        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14844            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14845                    targetUserId)) {
14846                throw new SecurityException("Shell does not have permission to access user "
14847                        + targetUserId + "\n " + Debug.getCallers(3));
14848            }
14849        }
14850        return targetUserId;
14851    }
14852
14853    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14854            String className, int flags) {
14855        boolean result = false;
14856        // For apps that don't have pre-defined UIDs, check for permission
14857        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14858            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14859                if (ActivityManager.checkUidPermission(
14860                        INTERACT_ACROSS_USERS,
14861                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14862                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14863                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14864                            + " requests FLAG_SINGLE_USER, but app does not hold "
14865                            + INTERACT_ACROSS_USERS;
14866                    Slog.w(TAG, msg);
14867                    throw new SecurityException(msg);
14868                }
14869                // Permission passed
14870                result = true;
14871            }
14872        } else if ("system".equals(componentProcessName)) {
14873            result = true;
14874        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14875            // Phone app and persistent apps are allowed to export singleuser providers.
14876            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14877                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14878        }
14879        if (DEBUG_MU) {
14880            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14881                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14882        }
14883        return result;
14884    }
14885
14886    /**
14887     * Checks to see if the caller is in the same app as the singleton
14888     * component, or the component is in a special app. It allows special apps
14889     * to export singleton components but prevents exporting singleton
14890     * components for regular apps.
14891     */
14892    boolean isValidSingletonCall(int callingUid, int componentUid) {
14893        int componentAppId = UserHandle.getAppId(componentUid);
14894        return UserHandle.isSameApp(callingUid, componentUid)
14895                || componentAppId == Process.SYSTEM_UID
14896                || componentAppId == Process.PHONE_UID
14897                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14898                        == PackageManager.PERMISSION_GRANTED;
14899    }
14900
14901    public int bindService(IApplicationThread caller, IBinder token,
14902            Intent service, String resolvedType,
14903            IServiceConnection connection, int flags, int userId) {
14904        enforceNotIsolatedCaller("bindService");
14905
14906        // Refuse possible leaked file descriptors
14907        if (service != null && service.hasFileDescriptors() == true) {
14908            throw new IllegalArgumentException("File descriptors passed in Intent");
14909        }
14910
14911        synchronized(this) {
14912            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14913                    connection, flags, userId);
14914        }
14915    }
14916
14917    public boolean unbindService(IServiceConnection connection) {
14918        synchronized (this) {
14919            return mServices.unbindServiceLocked(connection);
14920        }
14921    }
14922
14923    public void publishService(IBinder token, Intent intent, IBinder service) {
14924        // Refuse possible leaked file descriptors
14925        if (intent != null && intent.hasFileDescriptors() == true) {
14926            throw new IllegalArgumentException("File descriptors passed in Intent");
14927        }
14928
14929        synchronized(this) {
14930            if (!(token instanceof ServiceRecord)) {
14931                throw new IllegalArgumentException("Invalid service token");
14932            }
14933            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14934        }
14935    }
14936
14937    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14938        // Refuse possible leaked file descriptors
14939        if (intent != null && intent.hasFileDescriptors() == true) {
14940            throw new IllegalArgumentException("File descriptors passed in Intent");
14941        }
14942
14943        synchronized(this) {
14944            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14945        }
14946    }
14947
14948    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14949        synchronized(this) {
14950            if (!(token instanceof ServiceRecord)) {
14951                throw new IllegalArgumentException("Invalid service token");
14952            }
14953            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14954        }
14955    }
14956
14957    // =========================================================
14958    // BACKUP AND RESTORE
14959    // =========================================================
14960
14961    // Cause the target app to be launched if necessary and its backup agent
14962    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14963    // activity manager to announce its creation.
14964    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14965        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14966        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14967
14968        synchronized(this) {
14969            // !!! TODO: currently no check here that we're already bound
14970            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14971            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14972            synchronized (stats) {
14973                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14974            }
14975
14976            // Backup agent is now in use, its package can't be stopped.
14977            try {
14978                AppGlobals.getPackageManager().setPackageStoppedState(
14979                        app.packageName, false, UserHandle.getUserId(app.uid));
14980            } catch (RemoteException e) {
14981            } catch (IllegalArgumentException e) {
14982                Slog.w(TAG, "Failed trying to unstop package "
14983                        + app.packageName + ": " + e);
14984            }
14985
14986            BackupRecord r = new BackupRecord(ss, app, backupMode);
14987            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14988                    ? new ComponentName(app.packageName, app.backupAgentName)
14989                    : new ComponentName("android", "FullBackupAgent");
14990            // startProcessLocked() returns existing proc's record if it's already running
14991            ProcessRecord proc = startProcessLocked(app.processName, app,
14992                    false, 0, "backup", hostingName, false, false, false);
14993            if (proc == null) {
14994                Slog.e(TAG, "Unable to start backup agent process " + r);
14995                return false;
14996            }
14997
14998            r.app = proc;
14999            mBackupTarget = r;
15000            mBackupAppName = app.packageName;
15001
15002            // Try not to kill the process during backup
15003            updateOomAdjLocked(proc);
15004
15005            // If the process is already attached, schedule the creation of the backup agent now.
15006            // If it is not yet live, this will be done when it attaches to the framework.
15007            if (proc.thread != null) {
15008                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15009                try {
15010                    proc.thread.scheduleCreateBackupAgent(app,
15011                            compatibilityInfoForPackageLocked(app), backupMode);
15012                } catch (RemoteException e) {
15013                    // Will time out on the backup manager side
15014                }
15015            } else {
15016                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15017            }
15018            // Invariants: at this point, the target app process exists and the application
15019            // is either already running or in the process of coming up.  mBackupTarget and
15020            // mBackupAppName describe the app, so that when it binds back to the AM we
15021            // know that it's scheduled for a backup-agent operation.
15022        }
15023
15024        return true;
15025    }
15026
15027    @Override
15028    public void clearPendingBackup() {
15029        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15030        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15031
15032        synchronized (this) {
15033            mBackupTarget = null;
15034            mBackupAppName = null;
15035        }
15036    }
15037
15038    // A backup agent has just come up
15039    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15040        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15041                + " = " + agent);
15042
15043        synchronized(this) {
15044            if (!agentPackageName.equals(mBackupAppName)) {
15045                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15046                return;
15047            }
15048        }
15049
15050        long oldIdent = Binder.clearCallingIdentity();
15051        try {
15052            IBackupManager bm = IBackupManager.Stub.asInterface(
15053                    ServiceManager.getService(Context.BACKUP_SERVICE));
15054            bm.agentConnected(agentPackageName, agent);
15055        } catch (RemoteException e) {
15056            // can't happen; the backup manager service is local
15057        } catch (Exception e) {
15058            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15059            e.printStackTrace();
15060        } finally {
15061            Binder.restoreCallingIdentity(oldIdent);
15062        }
15063    }
15064
15065    // done with this agent
15066    public void unbindBackupAgent(ApplicationInfo appInfo) {
15067        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15068        if (appInfo == null) {
15069            Slog.w(TAG, "unbind backup agent for null app");
15070            return;
15071        }
15072
15073        synchronized(this) {
15074            try {
15075                if (mBackupAppName == null) {
15076                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15077                    return;
15078                }
15079
15080                if (!mBackupAppName.equals(appInfo.packageName)) {
15081                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15082                    return;
15083                }
15084
15085                // Not backing this app up any more; reset its OOM adjustment
15086                final ProcessRecord proc = mBackupTarget.app;
15087                updateOomAdjLocked(proc);
15088
15089                // If the app crashed during backup, 'thread' will be null here
15090                if (proc.thread != null) {
15091                    try {
15092                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15093                                compatibilityInfoForPackageLocked(appInfo));
15094                    } catch (Exception e) {
15095                        Slog.e(TAG, "Exception when unbinding backup agent:");
15096                        e.printStackTrace();
15097                    }
15098                }
15099            } finally {
15100                mBackupTarget = null;
15101                mBackupAppName = null;
15102            }
15103        }
15104    }
15105    // =========================================================
15106    // BROADCASTS
15107    // =========================================================
15108
15109    private final List getStickiesLocked(String action, IntentFilter filter,
15110            List cur, int userId) {
15111        final ContentResolver resolver = mContext.getContentResolver();
15112        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15113        if (stickies == null) {
15114            return cur;
15115        }
15116        final ArrayList<Intent> list = stickies.get(action);
15117        if (list == null) {
15118            return cur;
15119        }
15120        int N = list.size();
15121        for (int i=0; i<N; i++) {
15122            Intent intent = list.get(i);
15123            if (filter.match(resolver, intent, true, TAG) >= 0) {
15124                if (cur == null) {
15125                    cur = new ArrayList<Intent>();
15126                }
15127                cur.add(intent);
15128            }
15129        }
15130        return cur;
15131    }
15132
15133    boolean isPendingBroadcastProcessLocked(int pid) {
15134        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15135                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15136    }
15137
15138    void skipPendingBroadcastLocked(int pid) {
15139            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15140            for (BroadcastQueue queue : mBroadcastQueues) {
15141                queue.skipPendingBroadcastLocked(pid);
15142            }
15143    }
15144
15145    // The app just attached; send any pending broadcasts that it should receive
15146    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15147        boolean didSomething = false;
15148        for (BroadcastQueue queue : mBroadcastQueues) {
15149            didSomething |= queue.sendPendingBroadcastsLocked(app);
15150        }
15151        return didSomething;
15152    }
15153
15154    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15155            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15156        enforceNotIsolatedCaller("registerReceiver");
15157        int callingUid;
15158        int callingPid;
15159        synchronized(this) {
15160            ProcessRecord callerApp = null;
15161            if (caller != null) {
15162                callerApp = getRecordForAppLocked(caller);
15163                if (callerApp == null) {
15164                    throw new SecurityException(
15165                            "Unable to find app for caller " + caller
15166                            + " (pid=" + Binder.getCallingPid()
15167                            + ") when registering receiver " + receiver);
15168                }
15169                if (callerApp.info.uid != Process.SYSTEM_UID &&
15170                        !callerApp.pkgList.containsKey(callerPackage) &&
15171                        !"android".equals(callerPackage)) {
15172                    throw new SecurityException("Given caller package " + callerPackage
15173                            + " is not running in process " + callerApp);
15174                }
15175                callingUid = callerApp.info.uid;
15176                callingPid = callerApp.pid;
15177            } else {
15178                callerPackage = null;
15179                callingUid = Binder.getCallingUid();
15180                callingPid = Binder.getCallingPid();
15181            }
15182
15183            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15184                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15185
15186            List allSticky = null;
15187
15188            // Look for any matching sticky broadcasts...
15189            Iterator actions = filter.actionsIterator();
15190            if (actions != null) {
15191                while (actions.hasNext()) {
15192                    String action = (String)actions.next();
15193                    allSticky = getStickiesLocked(action, filter, allSticky,
15194                            UserHandle.USER_ALL);
15195                    allSticky = getStickiesLocked(action, filter, allSticky,
15196                            UserHandle.getUserId(callingUid));
15197                }
15198            } else {
15199                allSticky = getStickiesLocked(null, filter, allSticky,
15200                        UserHandle.USER_ALL);
15201                allSticky = getStickiesLocked(null, filter, allSticky,
15202                        UserHandle.getUserId(callingUid));
15203            }
15204
15205            // The first sticky in the list is returned directly back to
15206            // the client.
15207            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15208
15209            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15210                    + ": " + sticky);
15211
15212            if (receiver == null) {
15213                return sticky;
15214            }
15215
15216            ReceiverList rl
15217                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15218            if (rl == null) {
15219                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15220                        userId, receiver);
15221                if (rl.app != null) {
15222                    rl.app.receivers.add(rl);
15223                } else {
15224                    try {
15225                        receiver.asBinder().linkToDeath(rl, 0);
15226                    } catch (RemoteException e) {
15227                        return sticky;
15228                    }
15229                    rl.linkedToDeath = true;
15230                }
15231                mRegisteredReceivers.put(receiver.asBinder(), rl);
15232            } else if (rl.uid != callingUid) {
15233                throw new IllegalArgumentException(
15234                        "Receiver requested to register for uid " + callingUid
15235                        + " was previously registered for uid " + rl.uid);
15236            } else if (rl.pid != callingPid) {
15237                throw new IllegalArgumentException(
15238                        "Receiver requested to register for pid " + callingPid
15239                        + " was previously registered for pid " + rl.pid);
15240            } else if (rl.userId != userId) {
15241                throw new IllegalArgumentException(
15242                        "Receiver requested to register for user " + userId
15243                        + " was previously registered for user " + rl.userId);
15244            }
15245            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15246                    permission, callingUid, userId);
15247            rl.add(bf);
15248            if (!bf.debugCheck()) {
15249                Slog.w(TAG, "==> For Dynamic broadast");
15250            }
15251            mReceiverResolver.addFilter(bf);
15252
15253            // Enqueue broadcasts for all existing stickies that match
15254            // this filter.
15255            if (allSticky != null) {
15256                ArrayList receivers = new ArrayList();
15257                receivers.add(bf);
15258
15259                int N = allSticky.size();
15260                for (int i=0; i<N; i++) {
15261                    Intent intent = (Intent)allSticky.get(i);
15262                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15263                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15264                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15265                            null, null, false, true, true, -1);
15266                    queue.enqueueParallelBroadcastLocked(r);
15267                    queue.scheduleBroadcastsLocked();
15268                }
15269            }
15270
15271            return sticky;
15272        }
15273    }
15274
15275    public void unregisterReceiver(IIntentReceiver receiver) {
15276        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15277
15278        final long origId = Binder.clearCallingIdentity();
15279        try {
15280            boolean doTrim = false;
15281
15282            synchronized(this) {
15283                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15284                if (rl != null) {
15285                    if (rl.curBroadcast != null) {
15286                        BroadcastRecord r = rl.curBroadcast;
15287                        final boolean doNext = finishReceiverLocked(
15288                                receiver.asBinder(), r.resultCode, r.resultData,
15289                                r.resultExtras, r.resultAbort);
15290                        if (doNext) {
15291                            doTrim = true;
15292                            r.queue.processNextBroadcast(false);
15293                        }
15294                    }
15295
15296                    if (rl.app != null) {
15297                        rl.app.receivers.remove(rl);
15298                    }
15299                    removeReceiverLocked(rl);
15300                    if (rl.linkedToDeath) {
15301                        rl.linkedToDeath = false;
15302                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15303                    }
15304                }
15305            }
15306
15307            // If we actually concluded any broadcasts, we might now be able
15308            // to trim the recipients' apps from our working set
15309            if (doTrim) {
15310                trimApplications();
15311                return;
15312            }
15313
15314        } finally {
15315            Binder.restoreCallingIdentity(origId);
15316        }
15317    }
15318
15319    void removeReceiverLocked(ReceiverList rl) {
15320        mRegisteredReceivers.remove(rl.receiver.asBinder());
15321        int N = rl.size();
15322        for (int i=0; i<N; i++) {
15323            mReceiverResolver.removeFilter(rl.get(i));
15324        }
15325    }
15326
15327    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15328        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15329            ProcessRecord r = mLruProcesses.get(i);
15330            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15331                try {
15332                    r.thread.dispatchPackageBroadcast(cmd, packages);
15333                } catch (RemoteException ex) {
15334                }
15335            }
15336        }
15337    }
15338
15339    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15340            int callingUid, int[] users) {
15341        List<ResolveInfo> receivers = null;
15342        try {
15343            HashSet<ComponentName> singleUserReceivers = null;
15344            boolean scannedFirstReceivers = false;
15345            for (int user : users) {
15346                // Skip users that have Shell restrictions
15347                if (callingUid == Process.SHELL_UID
15348                        && getUserManagerLocked().hasUserRestriction(
15349                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15350                    continue;
15351                }
15352                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15353                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15354                if (user != 0 && newReceivers != null) {
15355                    // If this is not the primary user, we need to check for
15356                    // any receivers that should be filtered out.
15357                    for (int i=0; i<newReceivers.size(); i++) {
15358                        ResolveInfo ri = newReceivers.get(i);
15359                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15360                            newReceivers.remove(i);
15361                            i--;
15362                        }
15363                    }
15364                }
15365                if (newReceivers != null && newReceivers.size() == 0) {
15366                    newReceivers = null;
15367                }
15368                if (receivers == null) {
15369                    receivers = newReceivers;
15370                } else if (newReceivers != null) {
15371                    // We need to concatenate the additional receivers
15372                    // found with what we have do far.  This would be easy,
15373                    // but we also need to de-dup any receivers that are
15374                    // singleUser.
15375                    if (!scannedFirstReceivers) {
15376                        // Collect any single user receivers we had already retrieved.
15377                        scannedFirstReceivers = true;
15378                        for (int i=0; i<receivers.size(); i++) {
15379                            ResolveInfo ri = receivers.get(i);
15380                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15381                                ComponentName cn = new ComponentName(
15382                                        ri.activityInfo.packageName, ri.activityInfo.name);
15383                                if (singleUserReceivers == null) {
15384                                    singleUserReceivers = new HashSet<ComponentName>();
15385                                }
15386                                singleUserReceivers.add(cn);
15387                            }
15388                        }
15389                    }
15390                    // Add the new results to the existing results, tracking
15391                    // and de-dupping single user receivers.
15392                    for (int i=0; i<newReceivers.size(); i++) {
15393                        ResolveInfo ri = newReceivers.get(i);
15394                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15395                            ComponentName cn = new ComponentName(
15396                                    ri.activityInfo.packageName, ri.activityInfo.name);
15397                            if (singleUserReceivers == null) {
15398                                singleUserReceivers = new HashSet<ComponentName>();
15399                            }
15400                            if (!singleUserReceivers.contains(cn)) {
15401                                singleUserReceivers.add(cn);
15402                                receivers.add(ri);
15403                            }
15404                        } else {
15405                            receivers.add(ri);
15406                        }
15407                    }
15408                }
15409            }
15410        } catch (RemoteException ex) {
15411            // pm is in same process, this will never happen.
15412        }
15413        return receivers;
15414    }
15415
15416    private final int broadcastIntentLocked(ProcessRecord callerApp,
15417            String callerPackage, Intent intent, String resolvedType,
15418            IIntentReceiver resultTo, int resultCode, String resultData,
15419            Bundle map, String requiredPermission, int appOp,
15420            boolean ordered, boolean sticky, int callingPid, int callingUid,
15421            int userId) {
15422        intent = new Intent(intent);
15423
15424        // By default broadcasts do not go to stopped apps.
15425        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15426
15427        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15428            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15429            + " ordered=" + ordered + " userid=" + userId);
15430        if ((resultTo != null) && !ordered) {
15431            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15432        }
15433
15434        userId = handleIncomingUser(callingPid, callingUid, userId,
15435                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15436
15437        // Make sure that the user who is receiving this broadcast is started.
15438        // If not, we will just skip it.
15439
15440        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15441            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15442                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15443                Slog.w(TAG, "Skipping broadcast of " + intent
15444                        + ": user " + userId + " is stopped");
15445                return ActivityManager.BROADCAST_SUCCESS;
15446            }
15447        }
15448
15449        /*
15450         * Prevent non-system code (defined here to be non-persistent
15451         * processes) from sending protected broadcasts.
15452         */
15453        int callingAppId = UserHandle.getAppId(callingUid);
15454        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15455            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15456            || callingAppId == Process.NFC_UID || callingUid == 0) {
15457            // Always okay.
15458        } else if (callerApp == null || !callerApp.persistent) {
15459            try {
15460                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15461                        intent.getAction())) {
15462                    String msg = "Permission Denial: not allowed to send broadcast "
15463                            + intent.getAction() + " from pid="
15464                            + callingPid + ", uid=" + callingUid;
15465                    Slog.w(TAG, msg);
15466                    throw new SecurityException(msg);
15467                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15468                    // Special case for compatibility: we don't want apps to send this,
15469                    // but historically it has not been protected and apps may be using it
15470                    // to poke their own app widget.  So, instead of making it protected,
15471                    // just limit it to the caller.
15472                    if (callerApp == null) {
15473                        String msg = "Permission Denial: not allowed to send broadcast "
15474                                + intent.getAction() + " from unknown caller.";
15475                        Slog.w(TAG, msg);
15476                        throw new SecurityException(msg);
15477                    } else if (intent.getComponent() != null) {
15478                        // They are good enough to send to an explicit component...  verify
15479                        // it is being sent to the calling app.
15480                        if (!intent.getComponent().getPackageName().equals(
15481                                callerApp.info.packageName)) {
15482                            String msg = "Permission Denial: not allowed to send broadcast "
15483                                    + intent.getAction() + " to "
15484                                    + intent.getComponent().getPackageName() + " from "
15485                                    + callerApp.info.packageName;
15486                            Slog.w(TAG, msg);
15487                            throw new SecurityException(msg);
15488                        }
15489                    } else {
15490                        // Limit broadcast to their own package.
15491                        intent.setPackage(callerApp.info.packageName);
15492                    }
15493                }
15494            } catch (RemoteException e) {
15495                Slog.w(TAG, "Remote exception", e);
15496                return ActivityManager.BROADCAST_SUCCESS;
15497            }
15498        }
15499
15500        // Handle special intents: if this broadcast is from the package
15501        // manager about a package being removed, we need to remove all of
15502        // its activities from the history stack.
15503        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15504                intent.getAction());
15505        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15506                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15507                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15508                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15509                || uidRemoved) {
15510            if (checkComponentPermission(
15511                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15512                    callingPid, callingUid, -1, true)
15513                    == PackageManager.PERMISSION_GRANTED) {
15514                if (uidRemoved) {
15515                    final Bundle intentExtras = intent.getExtras();
15516                    final int uid = intentExtras != null
15517                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15518                    if (uid >= 0) {
15519                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15520                        synchronized (bs) {
15521                            bs.removeUidStatsLocked(uid);
15522                        }
15523                        mAppOpsService.uidRemoved(uid);
15524                    }
15525                } else {
15526                    // If resources are unavailable just force stop all
15527                    // those packages and flush the attribute cache as well.
15528                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15529                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15530                        if (list != null && (list.length > 0)) {
15531                            for (String pkg : list) {
15532                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15533                                        "storage unmount");
15534                            }
15535                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15536                            sendPackageBroadcastLocked(
15537                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15538                        }
15539                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15540                            intent.getAction())) {
15541                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15542                    } else {
15543                        Uri data = intent.getData();
15544                        String ssp;
15545                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15546                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15547                                    intent.getAction());
15548                            boolean fullUninstall = removed &&
15549                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15550                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15551                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15552                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15553                                        false, fullUninstall, userId,
15554                                        removed ? "pkg removed" : "pkg changed");
15555                            }
15556                            if (removed) {
15557                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15558                                        new String[] {ssp}, userId);
15559                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15560                                    mAppOpsService.packageRemoved(
15561                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15562
15563                                    // Remove all permissions granted from/to this package
15564                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15565                                }
15566                            }
15567                        }
15568                    }
15569                }
15570            } else {
15571                String msg = "Permission Denial: " + intent.getAction()
15572                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15573                        + ", uid=" + callingUid + ")"
15574                        + " requires "
15575                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15576                Slog.w(TAG, msg);
15577                throw new SecurityException(msg);
15578            }
15579
15580        // Special case for adding a package: by default turn on compatibility
15581        // mode.
15582        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15583            Uri data = intent.getData();
15584            String ssp;
15585            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15586                mCompatModePackages.handlePackageAddedLocked(ssp,
15587                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15588            }
15589        }
15590
15591        /*
15592         * If this is the time zone changed action, queue up a message that will reset the timezone
15593         * of all currently running processes. This message will get queued up before the broadcast
15594         * happens.
15595         */
15596        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15597            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15598        }
15599
15600        /*
15601         * If the user set the time, let all running processes know.
15602         */
15603        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15604            final int is24Hour = intent.getBooleanExtra(
15605                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15606            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15607            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15608            synchronized (stats) {
15609                stats.noteCurrentTimeChangedLocked();
15610            }
15611        }
15612
15613        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15614            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15615        }
15616
15617        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15618            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15619            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15620        }
15621
15622        // Add to the sticky list if requested.
15623        if (sticky) {
15624            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15625                    callingPid, callingUid)
15626                    != PackageManager.PERMISSION_GRANTED) {
15627                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15628                        + callingPid + ", uid=" + callingUid
15629                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15630                Slog.w(TAG, msg);
15631                throw new SecurityException(msg);
15632            }
15633            if (requiredPermission != null) {
15634                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15635                        + " and enforce permission " + requiredPermission);
15636                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15637            }
15638            if (intent.getComponent() != null) {
15639                throw new SecurityException(
15640                        "Sticky broadcasts can't target a specific component");
15641            }
15642            // We use userId directly here, since the "all" target is maintained
15643            // as a separate set of sticky broadcasts.
15644            if (userId != UserHandle.USER_ALL) {
15645                // But first, if this is not a broadcast to all users, then
15646                // make sure it doesn't conflict with an existing broadcast to
15647                // all users.
15648                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15649                        UserHandle.USER_ALL);
15650                if (stickies != null) {
15651                    ArrayList<Intent> list = stickies.get(intent.getAction());
15652                    if (list != null) {
15653                        int N = list.size();
15654                        int i;
15655                        for (i=0; i<N; i++) {
15656                            if (intent.filterEquals(list.get(i))) {
15657                                throw new IllegalArgumentException(
15658                                        "Sticky broadcast " + intent + " for user "
15659                                        + userId + " conflicts with existing global broadcast");
15660                            }
15661                        }
15662                    }
15663                }
15664            }
15665            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15666            if (stickies == null) {
15667                stickies = new ArrayMap<String, ArrayList<Intent>>();
15668                mStickyBroadcasts.put(userId, stickies);
15669            }
15670            ArrayList<Intent> list = stickies.get(intent.getAction());
15671            if (list == null) {
15672                list = new ArrayList<Intent>();
15673                stickies.put(intent.getAction(), list);
15674            }
15675            int N = list.size();
15676            int i;
15677            for (i=0; i<N; i++) {
15678                if (intent.filterEquals(list.get(i))) {
15679                    // This sticky already exists, replace it.
15680                    list.set(i, new Intent(intent));
15681                    break;
15682                }
15683            }
15684            if (i >= N) {
15685                list.add(new Intent(intent));
15686            }
15687        }
15688
15689        int[] users;
15690        if (userId == UserHandle.USER_ALL) {
15691            // Caller wants broadcast to go to all started users.
15692            users = mStartedUserArray;
15693        } else {
15694            // Caller wants broadcast to go to one specific user.
15695            users = new int[] {userId};
15696        }
15697
15698        // Figure out who all will receive this broadcast.
15699        List receivers = null;
15700        List<BroadcastFilter> registeredReceivers = null;
15701        // Need to resolve the intent to interested receivers...
15702        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15703                 == 0) {
15704            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15705        }
15706        if (intent.getComponent() == null) {
15707            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15708                // Query one target user at a time, excluding shell-restricted users
15709                UserManagerService ums = getUserManagerLocked();
15710                for (int i = 0; i < users.length; i++) {
15711                    if (ums.hasUserRestriction(
15712                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15713                        continue;
15714                    }
15715                    List<BroadcastFilter> registeredReceiversForUser =
15716                            mReceiverResolver.queryIntent(intent,
15717                                    resolvedType, false, users[i]);
15718                    if (registeredReceivers == null) {
15719                        registeredReceivers = registeredReceiversForUser;
15720                    } else if (registeredReceiversForUser != null) {
15721                        registeredReceivers.addAll(registeredReceiversForUser);
15722                    }
15723                }
15724            } else {
15725                registeredReceivers = mReceiverResolver.queryIntent(intent,
15726                        resolvedType, false, userId);
15727            }
15728        }
15729
15730        final boolean replacePending =
15731                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15732
15733        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15734                + " replacePending=" + replacePending);
15735
15736        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15737        if (!ordered && NR > 0) {
15738            // If we are not serializing this broadcast, then send the
15739            // registered receivers separately so they don't wait for the
15740            // components to be launched.
15741            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15742            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15743                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15744                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15745                    ordered, sticky, false, userId);
15746            if (DEBUG_BROADCAST) Slog.v(
15747                    TAG, "Enqueueing parallel broadcast " + r);
15748            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15749            if (!replaced) {
15750                queue.enqueueParallelBroadcastLocked(r);
15751                queue.scheduleBroadcastsLocked();
15752            }
15753            registeredReceivers = null;
15754            NR = 0;
15755        }
15756
15757        // Merge into one list.
15758        int ir = 0;
15759        if (receivers != null) {
15760            // A special case for PACKAGE_ADDED: do not allow the package
15761            // being added to see this broadcast.  This prevents them from
15762            // using this as a back door to get run as soon as they are
15763            // installed.  Maybe in the future we want to have a special install
15764            // broadcast or such for apps, but we'd like to deliberately make
15765            // this decision.
15766            String skipPackages[] = null;
15767            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15768                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15769                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15770                Uri data = intent.getData();
15771                if (data != null) {
15772                    String pkgName = data.getSchemeSpecificPart();
15773                    if (pkgName != null) {
15774                        skipPackages = new String[] { pkgName };
15775                    }
15776                }
15777            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15778                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15779            }
15780            if (skipPackages != null && (skipPackages.length > 0)) {
15781                for (String skipPackage : skipPackages) {
15782                    if (skipPackage != null) {
15783                        int NT = receivers.size();
15784                        for (int it=0; it<NT; it++) {
15785                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15786                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15787                                receivers.remove(it);
15788                                it--;
15789                                NT--;
15790                            }
15791                        }
15792                    }
15793                }
15794            }
15795
15796            int NT = receivers != null ? receivers.size() : 0;
15797            int it = 0;
15798            ResolveInfo curt = null;
15799            BroadcastFilter curr = null;
15800            while (it < NT && ir < NR) {
15801                if (curt == null) {
15802                    curt = (ResolveInfo)receivers.get(it);
15803                }
15804                if (curr == null) {
15805                    curr = registeredReceivers.get(ir);
15806                }
15807                if (curr.getPriority() >= curt.priority) {
15808                    // Insert this broadcast record into the final list.
15809                    receivers.add(it, curr);
15810                    ir++;
15811                    curr = null;
15812                    it++;
15813                    NT++;
15814                } else {
15815                    // Skip to the next ResolveInfo in the final list.
15816                    it++;
15817                    curt = null;
15818                }
15819            }
15820        }
15821        while (ir < NR) {
15822            if (receivers == null) {
15823                receivers = new ArrayList();
15824            }
15825            receivers.add(registeredReceivers.get(ir));
15826            ir++;
15827        }
15828
15829        if ((receivers != null && receivers.size() > 0)
15830                || resultTo != null) {
15831            BroadcastQueue queue = broadcastQueueForIntent(intent);
15832            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15833                    callerPackage, callingPid, callingUid, resolvedType,
15834                    requiredPermission, appOp, receivers, resultTo, resultCode,
15835                    resultData, map, ordered, sticky, false, userId);
15836            if (DEBUG_BROADCAST) Slog.v(
15837                    TAG, "Enqueueing ordered broadcast " + r
15838                    + ": prev had " + queue.mOrderedBroadcasts.size());
15839            if (DEBUG_BROADCAST) {
15840                int seq = r.intent.getIntExtra("seq", -1);
15841                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15842            }
15843            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15844            if (!replaced) {
15845                queue.enqueueOrderedBroadcastLocked(r);
15846                queue.scheduleBroadcastsLocked();
15847            }
15848        }
15849
15850        return ActivityManager.BROADCAST_SUCCESS;
15851    }
15852
15853    final Intent verifyBroadcastLocked(Intent intent) {
15854        // Refuse possible leaked file descriptors
15855        if (intent != null && intent.hasFileDescriptors() == true) {
15856            throw new IllegalArgumentException("File descriptors passed in Intent");
15857        }
15858
15859        int flags = intent.getFlags();
15860
15861        if (!mProcessesReady) {
15862            // if the caller really truly claims to know what they're doing, go
15863            // ahead and allow the broadcast without launching any receivers
15864            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15865                intent = new Intent(intent);
15866                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15867            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15868                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15869                        + " before boot completion");
15870                throw new IllegalStateException("Cannot broadcast before boot completed");
15871            }
15872        }
15873
15874        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15875            throw new IllegalArgumentException(
15876                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15877        }
15878
15879        return intent;
15880    }
15881
15882    public final int broadcastIntent(IApplicationThread caller,
15883            Intent intent, String resolvedType, IIntentReceiver resultTo,
15884            int resultCode, String resultData, Bundle map,
15885            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15886        enforceNotIsolatedCaller("broadcastIntent");
15887        synchronized(this) {
15888            intent = verifyBroadcastLocked(intent);
15889
15890            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15891            final int callingPid = Binder.getCallingPid();
15892            final int callingUid = Binder.getCallingUid();
15893            final long origId = Binder.clearCallingIdentity();
15894            int res = broadcastIntentLocked(callerApp,
15895                    callerApp != null ? callerApp.info.packageName : null,
15896                    intent, resolvedType, resultTo,
15897                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15898                    callingPid, callingUid, userId);
15899            Binder.restoreCallingIdentity(origId);
15900            return res;
15901        }
15902    }
15903
15904    int broadcastIntentInPackage(String packageName, int uid,
15905            Intent intent, String resolvedType, IIntentReceiver resultTo,
15906            int resultCode, String resultData, Bundle map,
15907            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15908        synchronized(this) {
15909            intent = verifyBroadcastLocked(intent);
15910
15911            final long origId = Binder.clearCallingIdentity();
15912            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15913                    resultTo, resultCode, resultData, map, requiredPermission,
15914                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15915            Binder.restoreCallingIdentity(origId);
15916            return res;
15917        }
15918    }
15919
15920    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15921        // Refuse possible leaked file descriptors
15922        if (intent != null && intent.hasFileDescriptors() == true) {
15923            throw new IllegalArgumentException("File descriptors passed in Intent");
15924        }
15925
15926        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15927                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15928
15929        synchronized(this) {
15930            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15931                    != PackageManager.PERMISSION_GRANTED) {
15932                String msg = "Permission Denial: unbroadcastIntent() from pid="
15933                        + Binder.getCallingPid()
15934                        + ", uid=" + Binder.getCallingUid()
15935                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15936                Slog.w(TAG, msg);
15937                throw new SecurityException(msg);
15938            }
15939            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15940            if (stickies != null) {
15941                ArrayList<Intent> list = stickies.get(intent.getAction());
15942                if (list != null) {
15943                    int N = list.size();
15944                    int i;
15945                    for (i=0; i<N; i++) {
15946                        if (intent.filterEquals(list.get(i))) {
15947                            list.remove(i);
15948                            break;
15949                        }
15950                    }
15951                    if (list.size() <= 0) {
15952                        stickies.remove(intent.getAction());
15953                    }
15954                }
15955                if (stickies.size() <= 0) {
15956                    mStickyBroadcasts.remove(userId);
15957                }
15958            }
15959        }
15960    }
15961
15962    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15963            String resultData, Bundle resultExtras, boolean resultAbort) {
15964        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15965        if (r == null) {
15966            Slog.w(TAG, "finishReceiver called but not found on queue");
15967            return false;
15968        }
15969
15970        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15971    }
15972
15973    void backgroundServicesFinishedLocked(int userId) {
15974        for (BroadcastQueue queue : mBroadcastQueues) {
15975            queue.backgroundServicesFinishedLocked(userId);
15976        }
15977    }
15978
15979    public void finishReceiver(IBinder who, int resultCode, String resultData,
15980            Bundle resultExtras, boolean resultAbort) {
15981        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15982
15983        // Refuse possible leaked file descriptors
15984        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15985            throw new IllegalArgumentException("File descriptors passed in Bundle");
15986        }
15987
15988        final long origId = Binder.clearCallingIdentity();
15989        try {
15990            boolean doNext = false;
15991            BroadcastRecord r;
15992
15993            synchronized(this) {
15994                r = broadcastRecordForReceiverLocked(who);
15995                if (r != null) {
15996                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15997                        resultData, resultExtras, resultAbort, true);
15998                }
15999            }
16000
16001            if (doNext) {
16002                r.queue.processNextBroadcast(false);
16003            }
16004            trimApplications();
16005        } finally {
16006            Binder.restoreCallingIdentity(origId);
16007        }
16008    }
16009
16010    // =========================================================
16011    // INSTRUMENTATION
16012    // =========================================================
16013
16014    public boolean startInstrumentation(ComponentName className,
16015            String profileFile, int flags, Bundle arguments,
16016            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16017            int userId, String abiOverride) {
16018        enforceNotIsolatedCaller("startInstrumentation");
16019        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16020                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16021        // Refuse possible leaked file descriptors
16022        if (arguments != null && arguments.hasFileDescriptors()) {
16023            throw new IllegalArgumentException("File descriptors passed in Bundle");
16024        }
16025
16026        synchronized(this) {
16027            InstrumentationInfo ii = null;
16028            ApplicationInfo ai = null;
16029            try {
16030                ii = mContext.getPackageManager().getInstrumentationInfo(
16031                    className, STOCK_PM_FLAGS);
16032                ai = AppGlobals.getPackageManager().getApplicationInfo(
16033                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16034            } catch (PackageManager.NameNotFoundException e) {
16035            } catch (RemoteException e) {
16036            }
16037            if (ii == null) {
16038                reportStartInstrumentationFailure(watcher, className,
16039                        "Unable to find instrumentation info for: " + className);
16040                return false;
16041            }
16042            if (ai == null) {
16043                reportStartInstrumentationFailure(watcher, className,
16044                        "Unable to find instrumentation target package: " + ii.targetPackage);
16045                return false;
16046            }
16047
16048            int match = mContext.getPackageManager().checkSignatures(
16049                    ii.targetPackage, ii.packageName);
16050            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16051                String msg = "Permission Denial: starting instrumentation "
16052                        + className + " from pid="
16053                        + Binder.getCallingPid()
16054                        + ", uid=" + Binder.getCallingPid()
16055                        + " not allowed because package " + ii.packageName
16056                        + " does not have a signature matching the target "
16057                        + ii.targetPackage;
16058                reportStartInstrumentationFailure(watcher, className, msg);
16059                throw new SecurityException(msg);
16060            }
16061
16062            final long origId = Binder.clearCallingIdentity();
16063            // Instrumentation can kill and relaunch even persistent processes
16064            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16065                    "start instr");
16066            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16067            app.instrumentationClass = className;
16068            app.instrumentationInfo = ai;
16069            app.instrumentationProfileFile = profileFile;
16070            app.instrumentationArguments = arguments;
16071            app.instrumentationWatcher = watcher;
16072            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16073            app.instrumentationResultClass = className;
16074            Binder.restoreCallingIdentity(origId);
16075        }
16076
16077        return true;
16078    }
16079
16080    /**
16081     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16082     * error to the logs, but if somebody is watching, send the report there too.  This enables
16083     * the "am" command to report errors with more information.
16084     *
16085     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16086     * @param cn The component name of the instrumentation.
16087     * @param report The error report.
16088     */
16089    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16090            ComponentName cn, String report) {
16091        Slog.w(TAG, report);
16092        try {
16093            if (watcher != null) {
16094                Bundle results = new Bundle();
16095                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16096                results.putString("Error", report);
16097                watcher.instrumentationStatus(cn, -1, results);
16098            }
16099        } catch (RemoteException e) {
16100            Slog.w(TAG, e);
16101        }
16102    }
16103
16104    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16105        if (app.instrumentationWatcher != null) {
16106            try {
16107                // NOTE:  IInstrumentationWatcher *must* be oneway here
16108                app.instrumentationWatcher.instrumentationFinished(
16109                    app.instrumentationClass,
16110                    resultCode,
16111                    results);
16112            } catch (RemoteException e) {
16113            }
16114        }
16115        if (app.instrumentationUiAutomationConnection != null) {
16116            try {
16117                app.instrumentationUiAutomationConnection.shutdown();
16118            } catch (RemoteException re) {
16119                /* ignore */
16120            }
16121            // Only a UiAutomation can set this flag and now that
16122            // it is finished we make sure it is reset to its default.
16123            mUserIsMonkey = false;
16124        }
16125        app.instrumentationWatcher = null;
16126        app.instrumentationUiAutomationConnection = null;
16127        app.instrumentationClass = null;
16128        app.instrumentationInfo = null;
16129        app.instrumentationProfileFile = null;
16130        app.instrumentationArguments = null;
16131
16132        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16133                "finished inst");
16134    }
16135
16136    public void finishInstrumentation(IApplicationThread target,
16137            int resultCode, Bundle results) {
16138        int userId = UserHandle.getCallingUserId();
16139        // Refuse possible leaked file descriptors
16140        if (results != null && results.hasFileDescriptors()) {
16141            throw new IllegalArgumentException("File descriptors passed in Intent");
16142        }
16143
16144        synchronized(this) {
16145            ProcessRecord app = getRecordForAppLocked(target);
16146            if (app == null) {
16147                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16148                return;
16149            }
16150            final long origId = Binder.clearCallingIdentity();
16151            finishInstrumentationLocked(app, resultCode, results);
16152            Binder.restoreCallingIdentity(origId);
16153        }
16154    }
16155
16156    // =========================================================
16157    // CONFIGURATION
16158    // =========================================================
16159
16160    public ConfigurationInfo getDeviceConfigurationInfo() {
16161        ConfigurationInfo config = new ConfigurationInfo();
16162        synchronized (this) {
16163            config.reqTouchScreen = mConfiguration.touchscreen;
16164            config.reqKeyboardType = mConfiguration.keyboard;
16165            config.reqNavigation = mConfiguration.navigation;
16166            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16167                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16168                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16169            }
16170            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16171                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16172                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16173            }
16174            config.reqGlEsVersion = GL_ES_VERSION;
16175        }
16176        return config;
16177    }
16178
16179    ActivityStack getFocusedStack() {
16180        return mStackSupervisor.getFocusedStack();
16181    }
16182
16183    public Configuration getConfiguration() {
16184        Configuration ci;
16185        synchronized(this) {
16186            ci = new Configuration(mConfiguration);
16187        }
16188        return ci;
16189    }
16190
16191    public void updatePersistentConfiguration(Configuration values) {
16192        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16193                "updateConfiguration()");
16194        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16195                "updateConfiguration()");
16196        if (values == null) {
16197            throw new NullPointerException("Configuration must not be null");
16198        }
16199
16200        synchronized(this) {
16201            final long origId = Binder.clearCallingIdentity();
16202            updateConfigurationLocked(values, null, true, false);
16203            Binder.restoreCallingIdentity(origId);
16204        }
16205    }
16206
16207    public void updateConfiguration(Configuration values) {
16208        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16209                "updateConfiguration()");
16210
16211        synchronized(this) {
16212            if (values == null && mWindowManager != null) {
16213                // sentinel: fetch the current configuration from the window manager
16214                values = mWindowManager.computeNewConfiguration();
16215            }
16216
16217            if (mWindowManager != null) {
16218                mProcessList.applyDisplaySize(mWindowManager);
16219            }
16220
16221            final long origId = Binder.clearCallingIdentity();
16222            if (values != null) {
16223                Settings.System.clearConfiguration(values);
16224            }
16225            updateConfigurationLocked(values, null, false, false);
16226            Binder.restoreCallingIdentity(origId);
16227        }
16228    }
16229
16230    /**
16231     * Do either or both things: (1) change the current configuration, and (2)
16232     * make sure the given activity is running with the (now) current
16233     * configuration.  Returns true if the activity has been left running, or
16234     * false if <var>starting</var> is being destroyed to match the new
16235     * configuration.
16236     * @param persistent TODO
16237     */
16238    boolean updateConfigurationLocked(Configuration values,
16239            ActivityRecord starting, boolean persistent, boolean initLocale) {
16240        int changes = 0;
16241
16242        if (values != null) {
16243            Configuration newConfig = new Configuration(mConfiguration);
16244            changes = newConfig.updateFrom(values);
16245            if (changes != 0) {
16246                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16247                    Slog.i(TAG, "Updating configuration to: " + values);
16248                }
16249
16250                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16251
16252                if (values.locale != null && !initLocale) {
16253                    saveLocaleLocked(values.locale,
16254                                     !values.locale.equals(mConfiguration.locale),
16255                                     values.userSetLocale);
16256                }
16257
16258                mConfigurationSeq++;
16259                if (mConfigurationSeq <= 0) {
16260                    mConfigurationSeq = 1;
16261                }
16262                newConfig.seq = mConfigurationSeq;
16263                mConfiguration = newConfig;
16264                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16265                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16266                //mUsageStatsService.noteStartConfig(newConfig);
16267
16268                final Configuration configCopy = new Configuration(mConfiguration);
16269
16270                // TODO: If our config changes, should we auto dismiss any currently
16271                // showing dialogs?
16272                mShowDialogs = shouldShowDialogs(newConfig);
16273
16274                AttributeCache ac = AttributeCache.instance();
16275                if (ac != null) {
16276                    ac.updateConfiguration(configCopy);
16277                }
16278
16279                // Make sure all resources in our process are updated
16280                // right now, so that anyone who is going to retrieve
16281                // resource values after we return will be sure to get
16282                // the new ones.  This is especially important during
16283                // boot, where the first config change needs to guarantee
16284                // all resources have that config before following boot
16285                // code is executed.
16286                mSystemThread.applyConfigurationToResources(configCopy);
16287
16288                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16289                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16290                    msg.obj = new Configuration(configCopy);
16291                    mHandler.sendMessage(msg);
16292                }
16293
16294                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16295                    ProcessRecord app = mLruProcesses.get(i);
16296                    try {
16297                        if (app.thread != null) {
16298                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16299                                    + app.processName + " new config " + mConfiguration);
16300                            app.thread.scheduleConfigurationChanged(configCopy);
16301                        }
16302                    } catch (Exception e) {
16303                    }
16304                }
16305                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16306                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16307                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16308                        | Intent.FLAG_RECEIVER_FOREGROUND);
16309                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16310                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16311                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16312                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16313                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16314                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16315                    broadcastIntentLocked(null, null, intent,
16316                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16317                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16318                }
16319            }
16320        }
16321
16322        boolean kept = true;
16323        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16324        // mainStack is null during startup.
16325        if (mainStack != null) {
16326            if (changes != 0 && starting == null) {
16327                // If the configuration changed, and the caller is not already
16328                // in the process of starting an activity, then find the top
16329                // activity to check if its configuration needs to change.
16330                starting = mainStack.topRunningActivityLocked(null);
16331            }
16332
16333            if (starting != null) {
16334                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16335                // And we need to make sure at this point that all other activities
16336                // are made visible with the correct configuration.
16337                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16338            }
16339        }
16340
16341        if (values != null && mWindowManager != null) {
16342            mWindowManager.setNewConfiguration(mConfiguration);
16343        }
16344
16345        return kept;
16346    }
16347
16348    /**
16349     * Decide based on the configuration whether we should shouw the ANR,
16350     * crash, etc dialogs.  The idea is that if there is no affordnace to
16351     * press the on-screen buttons, we shouldn't show the dialog.
16352     *
16353     * A thought: SystemUI might also want to get told about this, the Power
16354     * dialog / global actions also might want different behaviors.
16355     */
16356    private static final boolean shouldShowDialogs(Configuration config) {
16357        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16358                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16359    }
16360
16361    /**
16362     * Save the locale.  You must be inside a synchronized (this) block.
16363     */
16364    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16365        if(isDiff) {
16366            SystemProperties.set("user.language", l.getLanguage());
16367            SystemProperties.set("user.region", l.getCountry());
16368        }
16369
16370        if(isPersist) {
16371            SystemProperties.set("persist.sys.language", l.getLanguage());
16372            SystemProperties.set("persist.sys.country", l.getCountry());
16373            SystemProperties.set("persist.sys.localevar", l.getVariant());
16374
16375            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16376        }
16377    }
16378
16379    @Override
16380    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16381        synchronized (this) {
16382            ActivityRecord srec = ActivityRecord.forToken(token);
16383            if (srec.task != null && srec.task.stack != null) {
16384                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16385            }
16386        }
16387        return false;
16388    }
16389
16390    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16391            Intent resultData) {
16392
16393        synchronized (this) {
16394            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16395            if (stack != null) {
16396                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16397            }
16398            return false;
16399        }
16400    }
16401
16402    public int getLaunchedFromUid(IBinder activityToken) {
16403        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16404        if (srec == null) {
16405            return -1;
16406        }
16407        return srec.launchedFromUid;
16408    }
16409
16410    public String getLaunchedFromPackage(IBinder activityToken) {
16411        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16412        if (srec == null) {
16413            return null;
16414        }
16415        return srec.launchedFromPackage;
16416    }
16417
16418    // =========================================================
16419    // LIFETIME MANAGEMENT
16420    // =========================================================
16421
16422    // Returns which broadcast queue the app is the current [or imminent] receiver
16423    // on, or 'null' if the app is not an active broadcast recipient.
16424    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16425        BroadcastRecord r = app.curReceiver;
16426        if (r != null) {
16427            return r.queue;
16428        }
16429
16430        // It's not the current receiver, but it might be starting up to become one
16431        synchronized (this) {
16432            for (BroadcastQueue queue : mBroadcastQueues) {
16433                r = queue.mPendingBroadcast;
16434                if (r != null && r.curApp == app) {
16435                    // found it; report which queue it's in
16436                    return queue;
16437                }
16438            }
16439        }
16440
16441        return null;
16442    }
16443
16444    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16445            boolean doingAll, long now) {
16446        if (mAdjSeq == app.adjSeq) {
16447            // This adjustment has already been computed.
16448            return app.curRawAdj;
16449        }
16450
16451        if (app.thread == null) {
16452            app.adjSeq = mAdjSeq;
16453            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16454            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16455            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16456        }
16457
16458        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16459        app.adjSource = null;
16460        app.adjTarget = null;
16461        app.empty = false;
16462        app.cached = false;
16463
16464        final int activitiesSize = app.activities.size();
16465
16466        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16467            // The max adjustment doesn't allow this app to be anything
16468            // below foreground, so it is not worth doing work for it.
16469            app.adjType = "fixed";
16470            app.adjSeq = mAdjSeq;
16471            app.curRawAdj = app.maxAdj;
16472            app.foregroundActivities = false;
16473            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16474            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16475            // System processes can do UI, and when they do we want to have
16476            // them trim their memory after the user leaves the UI.  To
16477            // facilitate this, here we need to determine whether or not it
16478            // is currently showing UI.
16479            app.systemNoUi = true;
16480            if (app == TOP_APP) {
16481                app.systemNoUi = false;
16482            } else if (activitiesSize > 0) {
16483                for (int j = 0; j < activitiesSize; j++) {
16484                    final ActivityRecord r = app.activities.get(j);
16485                    if (r.visible) {
16486                        app.systemNoUi = false;
16487                    }
16488                }
16489            }
16490            if (!app.systemNoUi) {
16491                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16492            }
16493            return (app.curAdj=app.maxAdj);
16494        }
16495
16496        app.systemNoUi = false;
16497
16498        // Determine the importance of the process, starting with most
16499        // important to least, and assign an appropriate OOM adjustment.
16500        int adj;
16501        int schedGroup;
16502        int procState;
16503        boolean foregroundActivities = false;
16504        BroadcastQueue queue;
16505        if (app == TOP_APP) {
16506            // The last app on the list is the foreground app.
16507            adj = ProcessList.FOREGROUND_APP_ADJ;
16508            schedGroup = Process.THREAD_GROUP_DEFAULT;
16509            app.adjType = "top-activity";
16510            foregroundActivities = true;
16511            procState = ActivityManager.PROCESS_STATE_TOP;
16512        } else if (app.instrumentationClass != null) {
16513            // Don't want to kill running instrumentation.
16514            adj = ProcessList.FOREGROUND_APP_ADJ;
16515            schedGroup = Process.THREAD_GROUP_DEFAULT;
16516            app.adjType = "instrumentation";
16517            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16518        } else if ((queue = isReceivingBroadcast(app)) != null) {
16519            // An app that is currently receiving a broadcast also
16520            // counts as being in the foreground for OOM killer purposes.
16521            // It's placed in a sched group based on the nature of the
16522            // broadcast as reflected by which queue it's active in.
16523            adj = ProcessList.FOREGROUND_APP_ADJ;
16524            schedGroup = (queue == mFgBroadcastQueue)
16525                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16526            app.adjType = "broadcast";
16527            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16528        } else if (app.executingServices.size() > 0) {
16529            // An app that is currently executing a service callback also
16530            // counts as being in the foreground.
16531            adj = ProcessList.FOREGROUND_APP_ADJ;
16532            schedGroup = app.execServicesFg ?
16533                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16534            app.adjType = "exec-service";
16535            procState = ActivityManager.PROCESS_STATE_SERVICE;
16536            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16537        } else {
16538            // As far as we know the process is empty.  We may change our mind later.
16539            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16540            // At this point we don't actually know the adjustment.  Use the cached adj
16541            // value that the caller wants us to.
16542            adj = cachedAdj;
16543            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16544            app.cached = true;
16545            app.empty = true;
16546            app.adjType = "cch-empty";
16547        }
16548
16549        // Examine all activities if not already foreground.
16550        if (!foregroundActivities && activitiesSize > 0) {
16551            for (int j = 0; j < activitiesSize; j++) {
16552                final ActivityRecord r = app.activities.get(j);
16553                if (r.app != app) {
16554                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16555                            + app + "?!?");
16556                    continue;
16557                }
16558                if (r.visible) {
16559                    // App has a visible activity; only upgrade adjustment.
16560                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16561                        adj = ProcessList.VISIBLE_APP_ADJ;
16562                        app.adjType = "visible";
16563                    }
16564                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16565                        procState = ActivityManager.PROCESS_STATE_TOP;
16566                    }
16567                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16568                    app.cached = false;
16569                    app.empty = false;
16570                    foregroundActivities = true;
16571                    break;
16572                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16573                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16574                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16575                        app.adjType = "pausing";
16576                    }
16577                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16578                        procState = ActivityManager.PROCESS_STATE_TOP;
16579                    }
16580                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16581                    app.cached = false;
16582                    app.empty = false;
16583                    foregroundActivities = true;
16584                } else if (r.state == ActivityState.STOPPING) {
16585                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16586                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16587                        app.adjType = "stopping";
16588                    }
16589                    // For the process state, we will at this point consider the
16590                    // process to be cached.  It will be cached either as an activity
16591                    // or empty depending on whether the activity is finishing.  We do
16592                    // this so that we can treat the process as cached for purposes of
16593                    // memory trimming (determing current memory level, trim command to
16594                    // send to process) since there can be an arbitrary number of stopping
16595                    // processes and they should soon all go into the cached state.
16596                    if (!r.finishing) {
16597                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16598                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16599                        }
16600                    }
16601                    app.cached = false;
16602                    app.empty = false;
16603                    foregroundActivities = true;
16604                } else {
16605                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16606                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16607                        app.adjType = "cch-act";
16608                    }
16609                }
16610            }
16611        }
16612
16613        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16614            if (app.foregroundServices) {
16615                // The user is aware of this app, so make it visible.
16616                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16617                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16618                app.cached = false;
16619                app.adjType = "fg-service";
16620                schedGroup = Process.THREAD_GROUP_DEFAULT;
16621            } else if (app.forcingToForeground != null) {
16622                // The user is aware of this app, so make it visible.
16623                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16624                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16625                app.cached = false;
16626                app.adjType = "force-fg";
16627                app.adjSource = app.forcingToForeground;
16628                schedGroup = Process.THREAD_GROUP_DEFAULT;
16629            }
16630        }
16631
16632        if (app == mHeavyWeightProcess) {
16633            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16634                // We don't want to kill the current heavy-weight process.
16635                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16636                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16637                app.cached = false;
16638                app.adjType = "heavy";
16639            }
16640            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16641                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16642            }
16643        }
16644
16645        if (app == mHomeProcess) {
16646            if (adj > ProcessList.HOME_APP_ADJ) {
16647                // This process is hosting what we currently consider to be the
16648                // home app, so we don't want to let it go into the background.
16649                adj = ProcessList.HOME_APP_ADJ;
16650                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16651                app.cached = false;
16652                app.adjType = "home";
16653            }
16654            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16655                procState = ActivityManager.PROCESS_STATE_HOME;
16656            }
16657        }
16658
16659        if (app == mPreviousProcess && app.activities.size() > 0) {
16660            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16661                // This was the previous process that showed UI to the user.
16662                // We want to try to keep it around more aggressively, to give
16663                // a good experience around switching between two apps.
16664                adj = ProcessList.PREVIOUS_APP_ADJ;
16665                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16666                app.cached = false;
16667                app.adjType = "previous";
16668            }
16669            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16670                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16671            }
16672        }
16673
16674        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16675                + " reason=" + app.adjType);
16676
16677        // By default, we use the computed adjustment.  It may be changed if
16678        // there are applications dependent on our services or providers, but
16679        // this gives us a baseline and makes sure we don't get into an
16680        // infinite recursion.
16681        app.adjSeq = mAdjSeq;
16682        app.curRawAdj = adj;
16683        app.hasStartedServices = false;
16684
16685        if (mBackupTarget != null && app == mBackupTarget.app) {
16686            // If possible we want to avoid killing apps while they're being backed up
16687            if (adj > ProcessList.BACKUP_APP_ADJ) {
16688                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16689                adj = ProcessList.BACKUP_APP_ADJ;
16690                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16691                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16692                }
16693                app.adjType = "backup";
16694                app.cached = false;
16695            }
16696            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16697                procState = ActivityManager.PROCESS_STATE_BACKUP;
16698            }
16699        }
16700
16701        boolean mayBeTop = false;
16702
16703        for (int is = app.services.size()-1;
16704                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16705                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16706                        || procState > ActivityManager.PROCESS_STATE_TOP);
16707                is--) {
16708            ServiceRecord s = app.services.valueAt(is);
16709            if (s.startRequested) {
16710                app.hasStartedServices = true;
16711                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16712                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16713                }
16714                if (app.hasShownUi && app != mHomeProcess) {
16715                    // If this process has shown some UI, let it immediately
16716                    // go to the LRU list because it may be pretty heavy with
16717                    // UI stuff.  We'll tag it with a label just to help
16718                    // debug and understand what is going on.
16719                    if (adj > ProcessList.SERVICE_ADJ) {
16720                        app.adjType = "cch-started-ui-services";
16721                    }
16722                } else {
16723                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16724                        // This service has seen some activity within
16725                        // recent memory, so we will keep its process ahead
16726                        // of the background processes.
16727                        if (adj > ProcessList.SERVICE_ADJ) {
16728                            adj = ProcessList.SERVICE_ADJ;
16729                            app.adjType = "started-services";
16730                            app.cached = false;
16731                        }
16732                    }
16733                    // If we have let the service slide into the background
16734                    // state, still have some text describing what it is doing
16735                    // even though the service no longer has an impact.
16736                    if (adj > ProcessList.SERVICE_ADJ) {
16737                        app.adjType = "cch-started-services";
16738                    }
16739                }
16740            }
16741            for (int conni = s.connections.size()-1;
16742                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16743                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16744                            || procState > ActivityManager.PROCESS_STATE_TOP);
16745                    conni--) {
16746                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16747                for (int i = 0;
16748                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16749                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16750                                || procState > ActivityManager.PROCESS_STATE_TOP);
16751                        i++) {
16752                    // XXX should compute this based on the max of
16753                    // all connected clients.
16754                    ConnectionRecord cr = clist.get(i);
16755                    if (cr.binding.client == app) {
16756                        // Binding to ourself is not interesting.
16757                        continue;
16758                    }
16759                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16760                        ProcessRecord client = cr.binding.client;
16761                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16762                                TOP_APP, doingAll, now);
16763                        int clientProcState = client.curProcState;
16764                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16765                            // If the other app is cached for any reason, for purposes here
16766                            // we are going to consider it empty.  The specific cached state
16767                            // doesn't propagate except under certain conditions.
16768                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16769                        }
16770                        String adjType = null;
16771                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16772                            // Not doing bind OOM management, so treat
16773                            // this guy more like a started service.
16774                            if (app.hasShownUi && app != mHomeProcess) {
16775                                // If this process has shown some UI, let it immediately
16776                                // go to the LRU list because it may be pretty heavy with
16777                                // UI stuff.  We'll tag it with a label just to help
16778                                // debug and understand what is going on.
16779                                if (adj > clientAdj) {
16780                                    adjType = "cch-bound-ui-services";
16781                                }
16782                                app.cached = false;
16783                                clientAdj = adj;
16784                                clientProcState = procState;
16785                            } else {
16786                                if (now >= (s.lastActivity
16787                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16788                                    // This service has not seen activity within
16789                                    // recent memory, so allow it to drop to the
16790                                    // LRU list if there is no other reason to keep
16791                                    // it around.  We'll also tag it with a label just
16792                                    // to help debug and undertand what is going on.
16793                                    if (adj > clientAdj) {
16794                                        adjType = "cch-bound-services";
16795                                    }
16796                                    clientAdj = adj;
16797                                }
16798                            }
16799                        }
16800                        if (adj > clientAdj) {
16801                            // If this process has recently shown UI, and
16802                            // the process that is binding to it is less
16803                            // important than being visible, then we don't
16804                            // care about the binding as much as we care
16805                            // about letting this process get into the LRU
16806                            // list to be killed and restarted if needed for
16807                            // memory.
16808                            if (app.hasShownUi && app != mHomeProcess
16809                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16810                                adjType = "cch-bound-ui-services";
16811                            } else {
16812                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16813                                        |Context.BIND_IMPORTANT)) != 0) {
16814                                    adj = clientAdj;
16815                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16816                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16817                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16818                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16819                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16820                                    adj = clientAdj;
16821                                } else {
16822                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16823                                        adj = ProcessList.VISIBLE_APP_ADJ;
16824                                    }
16825                                }
16826                                if (!client.cached) {
16827                                    app.cached = false;
16828                                }
16829                                adjType = "service";
16830                            }
16831                        }
16832                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16833                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16834                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16835                            }
16836                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16837                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16838                                    // Special handling of clients who are in the top state.
16839                                    // We *may* want to consider this process to be in the
16840                                    // top state as well, but only if there is not another
16841                                    // reason for it to be running.  Being on the top is a
16842                                    // special state, meaning you are specifically running
16843                                    // for the current top app.  If the process is already
16844                                    // running in the background for some other reason, it
16845                                    // is more important to continue considering it to be
16846                                    // in the background state.
16847                                    mayBeTop = true;
16848                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16849                                } else {
16850                                    // Special handling for above-top states (persistent
16851                                    // processes).  These should not bring the current process
16852                                    // into the top state, since they are not on top.  Instead
16853                                    // give them the best state after that.
16854                                    clientProcState =
16855                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16856                                }
16857                            }
16858                        } else {
16859                            if (clientProcState <
16860                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16861                                clientProcState =
16862                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16863                            }
16864                        }
16865                        if (procState > clientProcState) {
16866                            procState = clientProcState;
16867                        }
16868                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16869                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16870                            app.pendingUiClean = true;
16871                        }
16872                        if (adjType != null) {
16873                            app.adjType = adjType;
16874                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16875                                    .REASON_SERVICE_IN_USE;
16876                            app.adjSource = cr.binding.client;
16877                            app.adjSourceProcState = clientProcState;
16878                            app.adjTarget = s.name;
16879                        }
16880                    }
16881                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16882                        app.treatLikeActivity = true;
16883                    }
16884                    final ActivityRecord a = cr.activity;
16885                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16886                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16887                                (a.visible || a.state == ActivityState.RESUMED
16888                                 || a.state == ActivityState.PAUSING)) {
16889                            adj = ProcessList.FOREGROUND_APP_ADJ;
16890                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16891                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16892                            }
16893                            app.cached = false;
16894                            app.adjType = "service";
16895                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16896                                    .REASON_SERVICE_IN_USE;
16897                            app.adjSource = a;
16898                            app.adjSourceProcState = procState;
16899                            app.adjTarget = s.name;
16900                        }
16901                    }
16902                }
16903            }
16904        }
16905
16906        for (int provi = app.pubProviders.size()-1;
16907                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16908                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16909                        || procState > ActivityManager.PROCESS_STATE_TOP);
16910                provi--) {
16911            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16912            for (int i = cpr.connections.size()-1;
16913                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16914                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16915                            || procState > ActivityManager.PROCESS_STATE_TOP);
16916                    i--) {
16917                ContentProviderConnection conn = cpr.connections.get(i);
16918                ProcessRecord client = conn.client;
16919                if (client == app) {
16920                    // Being our own client is not interesting.
16921                    continue;
16922                }
16923                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16924                int clientProcState = client.curProcState;
16925                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16926                    // If the other app is cached for any reason, for purposes here
16927                    // we are going to consider it empty.
16928                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16929                }
16930                if (adj > clientAdj) {
16931                    if (app.hasShownUi && app != mHomeProcess
16932                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16933                        app.adjType = "cch-ui-provider";
16934                    } else {
16935                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16936                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16937                        app.adjType = "provider";
16938                    }
16939                    app.cached &= client.cached;
16940                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16941                            .REASON_PROVIDER_IN_USE;
16942                    app.adjSource = client;
16943                    app.adjSourceProcState = clientProcState;
16944                    app.adjTarget = cpr.name;
16945                }
16946                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16947                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16948                        // Special handling of clients who are in the top state.
16949                        // We *may* want to consider this process to be in the
16950                        // top state as well, but only if there is not another
16951                        // reason for it to be running.  Being on the top is a
16952                        // special state, meaning you are specifically running
16953                        // for the current top app.  If the process is already
16954                        // running in the background for some other reason, it
16955                        // is more important to continue considering it to be
16956                        // in the background state.
16957                        mayBeTop = true;
16958                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16959                    } else {
16960                        // Special handling for above-top states (persistent
16961                        // processes).  These should not bring the current process
16962                        // into the top state, since they are not on top.  Instead
16963                        // give them the best state after that.
16964                        clientProcState =
16965                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16966                    }
16967                }
16968                if (procState > clientProcState) {
16969                    procState = clientProcState;
16970                }
16971                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16972                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16973                }
16974            }
16975            // If the provider has external (non-framework) process
16976            // dependencies, ensure that its adjustment is at least
16977            // FOREGROUND_APP_ADJ.
16978            if (cpr.hasExternalProcessHandles()) {
16979                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16980                    adj = ProcessList.FOREGROUND_APP_ADJ;
16981                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16982                    app.cached = false;
16983                    app.adjType = "provider";
16984                    app.adjTarget = cpr.name;
16985                }
16986                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16987                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16988                }
16989            }
16990        }
16991
16992        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16993            // A client of one of our services or providers is in the top state.  We
16994            // *may* want to be in the top state, but not if we are already running in
16995            // the background for some other reason.  For the decision here, we are going
16996            // to pick out a few specific states that we want to remain in when a client
16997            // is top (states that tend to be longer-term) and otherwise allow it to go
16998            // to the top state.
16999            switch (procState) {
17000                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17001                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17002                case ActivityManager.PROCESS_STATE_SERVICE:
17003                    // These all are longer-term states, so pull them up to the top
17004                    // of the background states, but not all the way to the top state.
17005                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17006                    break;
17007                default:
17008                    // Otherwise, top is a better choice, so take it.
17009                    procState = ActivityManager.PROCESS_STATE_TOP;
17010                    break;
17011            }
17012        }
17013
17014        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17015            if (app.hasClientActivities) {
17016                // This is a cached process, but with client activities.  Mark it so.
17017                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17018                app.adjType = "cch-client-act";
17019            } else if (app.treatLikeActivity) {
17020                // This is a cached process, but somebody wants us to treat it like it has
17021                // an activity, okay!
17022                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17023                app.adjType = "cch-as-act";
17024            }
17025        }
17026
17027        if (adj == ProcessList.SERVICE_ADJ) {
17028            if (doingAll) {
17029                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17030                mNewNumServiceProcs++;
17031                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17032                if (!app.serviceb) {
17033                    // This service isn't far enough down on the LRU list to
17034                    // normally be a B service, but if we are low on RAM and it
17035                    // is large we want to force it down since we would prefer to
17036                    // keep launcher over it.
17037                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17038                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17039                        app.serviceHighRam = true;
17040                        app.serviceb = true;
17041                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17042                    } else {
17043                        mNewNumAServiceProcs++;
17044                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17045                    }
17046                } else {
17047                    app.serviceHighRam = false;
17048                }
17049            }
17050            if (app.serviceb) {
17051                adj = ProcessList.SERVICE_B_ADJ;
17052            }
17053        }
17054
17055        app.curRawAdj = adj;
17056
17057        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17058        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17059        if (adj > app.maxAdj) {
17060            adj = app.maxAdj;
17061            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17062                schedGroup = Process.THREAD_GROUP_DEFAULT;
17063            }
17064        }
17065
17066        // Do final modification to adj.  Everything we do between here and applying
17067        // the final setAdj must be done in this function, because we will also use
17068        // it when computing the final cached adj later.  Note that we don't need to
17069        // worry about this for max adj above, since max adj will always be used to
17070        // keep it out of the cached vaues.
17071        app.curAdj = app.modifyRawOomAdj(adj);
17072        app.curSchedGroup = schedGroup;
17073        app.curProcState = procState;
17074        app.foregroundActivities = foregroundActivities;
17075
17076        return app.curRawAdj;
17077    }
17078
17079    /**
17080     * Schedule PSS collection of a process.
17081     */
17082    void requestPssLocked(ProcessRecord proc, int procState) {
17083        if (mPendingPssProcesses.contains(proc)) {
17084            return;
17085        }
17086        if (mPendingPssProcesses.size() == 0) {
17087            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17088        }
17089        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17090        proc.pssProcState = procState;
17091        mPendingPssProcesses.add(proc);
17092    }
17093
17094    /**
17095     * Schedule PSS collection of all processes.
17096     */
17097    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17098        if (!always) {
17099            if (now < (mLastFullPssTime +
17100                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17101                return;
17102            }
17103        }
17104        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17105        mLastFullPssTime = now;
17106        mFullPssPending = true;
17107        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17108        mPendingPssProcesses.clear();
17109        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17110            ProcessRecord app = mLruProcesses.get(i);
17111            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17112                app.pssProcState = app.setProcState;
17113                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17114                        isSleeping(), now);
17115                mPendingPssProcesses.add(app);
17116            }
17117        }
17118        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17119    }
17120
17121    /**
17122     * Ask a given process to GC right now.
17123     */
17124    final void performAppGcLocked(ProcessRecord app) {
17125        try {
17126            app.lastRequestedGc = SystemClock.uptimeMillis();
17127            if (app.thread != null) {
17128                if (app.reportLowMemory) {
17129                    app.reportLowMemory = false;
17130                    app.thread.scheduleLowMemory();
17131                } else {
17132                    app.thread.processInBackground();
17133                }
17134            }
17135        } catch (Exception e) {
17136            // whatever.
17137        }
17138    }
17139
17140    /**
17141     * Returns true if things are idle enough to perform GCs.
17142     */
17143    private final boolean canGcNowLocked() {
17144        boolean processingBroadcasts = false;
17145        for (BroadcastQueue q : mBroadcastQueues) {
17146            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17147                processingBroadcasts = true;
17148            }
17149        }
17150        return !processingBroadcasts
17151                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17152    }
17153
17154    /**
17155     * Perform GCs on all processes that are waiting for it, but only
17156     * if things are idle.
17157     */
17158    final void performAppGcsLocked() {
17159        final int N = mProcessesToGc.size();
17160        if (N <= 0) {
17161            return;
17162        }
17163        if (canGcNowLocked()) {
17164            while (mProcessesToGc.size() > 0) {
17165                ProcessRecord proc = mProcessesToGc.remove(0);
17166                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17167                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17168                            <= SystemClock.uptimeMillis()) {
17169                        // To avoid spamming the system, we will GC processes one
17170                        // at a time, waiting a few seconds between each.
17171                        performAppGcLocked(proc);
17172                        scheduleAppGcsLocked();
17173                        return;
17174                    } else {
17175                        // It hasn't been long enough since we last GCed this
17176                        // process...  put it in the list to wait for its time.
17177                        addProcessToGcListLocked(proc);
17178                        break;
17179                    }
17180                }
17181            }
17182
17183            scheduleAppGcsLocked();
17184        }
17185    }
17186
17187    /**
17188     * If all looks good, perform GCs on all processes waiting for them.
17189     */
17190    final void performAppGcsIfAppropriateLocked() {
17191        if (canGcNowLocked()) {
17192            performAppGcsLocked();
17193            return;
17194        }
17195        // Still not idle, wait some more.
17196        scheduleAppGcsLocked();
17197    }
17198
17199    /**
17200     * Schedule the execution of all pending app GCs.
17201     */
17202    final void scheduleAppGcsLocked() {
17203        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17204
17205        if (mProcessesToGc.size() > 0) {
17206            // Schedule a GC for the time to the next process.
17207            ProcessRecord proc = mProcessesToGc.get(0);
17208            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17209
17210            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17211            long now = SystemClock.uptimeMillis();
17212            if (when < (now+GC_TIMEOUT)) {
17213                when = now + GC_TIMEOUT;
17214            }
17215            mHandler.sendMessageAtTime(msg, when);
17216        }
17217    }
17218
17219    /**
17220     * Add a process to the array of processes waiting to be GCed.  Keeps the
17221     * list in sorted order by the last GC time.  The process can't already be
17222     * on the list.
17223     */
17224    final void addProcessToGcListLocked(ProcessRecord proc) {
17225        boolean added = false;
17226        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17227            if (mProcessesToGc.get(i).lastRequestedGc <
17228                    proc.lastRequestedGc) {
17229                added = true;
17230                mProcessesToGc.add(i+1, proc);
17231                break;
17232            }
17233        }
17234        if (!added) {
17235            mProcessesToGc.add(0, proc);
17236        }
17237    }
17238
17239    /**
17240     * Set up to ask a process to GC itself.  This will either do it
17241     * immediately, or put it on the list of processes to gc the next
17242     * time things are idle.
17243     */
17244    final void scheduleAppGcLocked(ProcessRecord app) {
17245        long now = SystemClock.uptimeMillis();
17246        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17247            return;
17248        }
17249        if (!mProcessesToGc.contains(app)) {
17250            addProcessToGcListLocked(app);
17251            scheduleAppGcsLocked();
17252        }
17253    }
17254
17255    final void checkExcessivePowerUsageLocked(boolean doKills) {
17256        updateCpuStatsNow();
17257
17258        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17259        boolean doWakeKills = doKills;
17260        boolean doCpuKills = doKills;
17261        if (mLastPowerCheckRealtime == 0) {
17262            doWakeKills = false;
17263        }
17264        if (mLastPowerCheckUptime == 0) {
17265            doCpuKills = false;
17266        }
17267        if (stats.isScreenOn()) {
17268            doWakeKills = false;
17269        }
17270        final long curRealtime = SystemClock.elapsedRealtime();
17271        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17272        final long curUptime = SystemClock.uptimeMillis();
17273        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17274        mLastPowerCheckRealtime = curRealtime;
17275        mLastPowerCheckUptime = curUptime;
17276        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17277            doWakeKills = false;
17278        }
17279        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17280            doCpuKills = false;
17281        }
17282        int i = mLruProcesses.size();
17283        while (i > 0) {
17284            i--;
17285            ProcessRecord app = mLruProcesses.get(i);
17286            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17287                long wtime;
17288                synchronized (stats) {
17289                    wtime = stats.getProcessWakeTime(app.info.uid,
17290                            app.pid, curRealtime);
17291                }
17292                long wtimeUsed = wtime - app.lastWakeTime;
17293                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17294                if (DEBUG_POWER) {
17295                    StringBuilder sb = new StringBuilder(128);
17296                    sb.append("Wake for ");
17297                    app.toShortString(sb);
17298                    sb.append(": over ");
17299                    TimeUtils.formatDuration(realtimeSince, sb);
17300                    sb.append(" used ");
17301                    TimeUtils.formatDuration(wtimeUsed, sb);
17302                    sb.append(" (");
17303                    sb.append((wtimeUsed*100)/realtimeSince);
17304                    sb.append("%)");
17305                    Slog.i(TAG, sb.toString());
17306                    sb.setLength(0);
17307                    sb.append("CPU for ");
17308                    app.toShortString(sb);
17309                    sb.append(": over ");
17310                    TimeUtils.formatDuration(uptimeSince, sb);
17311                    sb.append(" used ");
17312                    TimeUtils.formatDuration(cputimeUsed, sb);
17313                    sb.append(" (");
17314                    sb.append((cputimeUsed*100)/uptimeSince);
17315                    sb.append("%)");
17316                    Slog.i(TAG, sb.toString());
17317                }
17318                // If a process has held a wake lock for more
17319                // than 50% of the time during this period,
17320                // that sounds bad.  Kill!
17321                if (doWakeKills && realtimeSince > 0
17322                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17323                    synchronized (stats) {
17324                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17325                                realtimeSince, wtimeUsed);
17326                    }
17327                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17328                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17329                } else if (doCpuKills && uptimeSince > 0
17330                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17331                    synchronized (stats) {
17332                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17333                                uptimeSince, cputimeUsed);
17334                    }
17335                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17336                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17337                } else {
17338                    app.lastWakeTime = wtime;
17339                    app.lastCpuTime = app.curCpuTime;
17340                }
17341            }
17342        }
17343    }
17344
17345    private final boolean applyOomAdjLocked(ProcessRecord app,
17346            ProcessRecord TOP_APP, boolean doingAll, long now) {
17347        boolean success = true;
17348
17349        if (app.curRawAdj != app.setRawAdj) {
17350            app.setRawAdj = app.curRawAdj;
17351        }
17352
17353        int changes = 0;
17354
17355        if (app.curAdj != app.setAdj) {
17356            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17357            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17358                TAG, "Set " + app.pid + " " + app.processName +
17359                " adj " + app.curAdj + ": " + app.adjType);
17360            app.setAdj = app.curAdj;
17361        }
17362
17363        if (app.setSchedGroup != app.curSchedGroup) {
17364            app.setSchedGroup = app.curSchedGroup;
17365            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17366                    "Setting process group of " + app.processName
17367                    + " to " + app.curSchedGroup);
17368            if (app.waitingToKill != null &&
17369                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17370                app.kill(app.waitingToKill, true);
17371                success = false;
17372            } else {
17373                if (true) {
17374                    long oldId = Binder.clearCallingIdentity();
17375                    try {
17376                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17377                    } catch (Exception e) {
17378                        Slog.w(TAG, "Failed setting process group of " + app.pid
17379                                + " to " + app.curSchedGroup);
17380                        e.printStackTrace();
17381                    } finally {
17382                        Binder.restoreCallingIdentity(oldId);
17383                    }
17384                } else {
17385                    if (app.thread != null) {
17386                        try {
17387                            app.thread.setSchedulingGroup(app.curSchedGroup);
17388                        } catch (RemoteException e) {
17389                        }
17390                    }
17391                }
17392                Process.setSwappiness(app.pid,
17393                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17394            }
17395        }
17396        if (app.repForegroundActivities != app.foregroundActivities) {
17397            app.repForegroundActivities = app.foregroundActivities;
17398            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17399        }
17400        if (app.repProcState != app.curProcState) {
17401            app.repProcState = app.curProcState;
17402            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17403            if (app.thread != null) {
17404                try {
17405                    if (false) {
17406                        //RuntimeException h = new RuntimeException("here");
17407                        Slog.i(TAG, "Sending new process state " + app.repProcState
17408                                + " to " + app /*, h*/);
17409                    }
17410                    app.thread.setProcessState(app.repProcState);
17411                } catch (RemoteException e) {
17412                }
17413            }
17414        }
17415        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17416                app.setProcState)) {
17417            app.lastStateTime = now;
17418            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17419                    isSleeping(), now);
17420            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17421                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17422                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17423                    + (app.nextPssTime-now) + ": " + app);
17424        } else {
17425            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17426                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17427                requestPssLocked(app, app.setProcState);
17428                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17429                        isSleeping(), now);
17430            } else if (false && DEBUG_PSS) {
17431                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17432            }
17433        }
17434        if (app.setProcState != app.curProcState) {
17435            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17436                    "Proc state change of " + app.processName
17437                    + " to " + app.curProcState);
17438            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17439            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17440            if (setImportant && !curImportant) {
17441                // This app is no longer something we consider important enough to allow to
17442                // use arbitrary amounts of battery power.  Note
17443                // its current wake lock time to later know to kill it if
17444                // it is not behaving well.
17445                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17446                synchronized (stats) {
17447                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17448                            app.pid, SystemClock.elapsedRealtime());
17449                }
17450                app.lastCpuTime = app.curCpuTime;
17451
17452            }
17453            app.setProcState = app.curProcState;
17454            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17455                app.notCachedSinceIdle = false;
17456            }
17457            if (!doingAll) {
17458                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17459            } else {
17460                app.procStateChanged = true;
17461            }
17462        }
17463
17464        if (changes != 0) {
17465            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17466            int i = mPendingProcessChanges.size()-1;
17467            ProcessChangeItem item = null;
17468            while (i >= 0) {
17469                item = mPendingProcessChanges.get(i);
17470                if (item.pid == app.pid) {
17471                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17472                    break;
17473                }
17474                i--;
17475            }
17476            if (i < 0) {
17477                // No existing item in pending changes; need a new one.
17478                final int NA = mAvailProcessChanges.size();
17479                if (NA > 0) {
17480                    item = mAvailProcessChanges.remove(NA-1);
17481                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17482                } else {
17483                    item = new ProcessChangeItem();
17484                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17485                }
17486                item.changes = 0;
17487                item.pid = app.pid;
17488                item.uid = app.info.uid;
17489                if (mPendingProcessChanges.size() == 0) {
17490                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17491                            "*** Enqueueing dispatch processes changed!");
17492                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17493                }
17494                mPendingProcessChanges.add(item);
17495            }
17496            item.changes |= changes;
17497            item.processState = app.repProcState;
17498            item.foregroundActivities = app.repForegroundActivities;
17499            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17500                    + Integer.toHexString(System.identityHashCode(item))
17501                    + " " + app.toShortString() + ": changes=" + item.changes
17502                    + " procState=" + item.processState
17503                    + " foreground=" + item.foregroundActivities
17504                    + " type=" + app.adjType + " source=" + app.adjSource
17505                    + " target=" + app.adjTarget);
17506        }
17507
17508        return success;
17509    }
17510
17511    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17512        if (proc.thread != null) {
17513            if (proc.baseProcessTracker != null) {
17514                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17515            }
17516            if (proc.repProcState >= 0) {
17517                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17518                        proc.repProcState);
17519            }
17520        }
17521    }
17522
17523    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17524            ProcessRecord TOP_APP, boolean doingAll, long now) {
17525        if (app.thread == null) {
17526            return false;
17527        }
17528
17529        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17530
17531        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17532    }
17533
17534    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17535            boolean oomAdj) {
17536        if (isForeground != proc.foregroundServices) {
17537            proc.foregroundServices = isForeground;
17538            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17539                    proc.info.uid);
17540            if (isForeground) {
17541                if (curProcs == null) {
17542                    curProcs = new ArrayList<ProcessRecord>();
17543                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17544                }
17545                if (!curProcs.contains(proc)) {
17546                    curProcs.add(proc);
17547                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17548                            proc.info.packageName, proc.info.uid);
17549                }
17550            } else {
17551                if (curProcs != null) {
17552                    if (curProcs.remove(proc)) {
17553                        mBatteryStatsService.noteEvent(
17554                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17555                                proc.info.packageName, proc.info.uid);
17556                        if (curProcs.size() <= 0) {
17557                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17558                        }
17559                    }
17560                }
17561            }
17562            if (oomAdj) {
17563                updateOomAdjLocked();
17564            }
17565        }
17566    }
17567
17568    private final ActivityRecord resumedAppLocked() {
17569        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17570        String pkg;
17571        int uid;
17572        if (act != null) {
17573            pkg = act.packageName;
17574            uid = act.info.applicationInfo.uid;
17575        } else {
17576            pkg = null;
17577            uid = -1;
17578        }
17579        // Has the UID or resumed package name changed?
17580        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17581                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17582            if (mCurResumedPackage != null) {
17583                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17584                        mCurResumedPackage, mCurResumedUid);
17585            }
17586            mCurResumedPackage = pkg;
17587            mCurResumedUid = uid;
17588            if (mCurResumedPackage != null) {
17589                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17590                        mCurResumedPackage, mCurResumedUid);
17591            }
17592        }
17593        return act;
17594    }
17595
17596    final boolean updateOomAdjLocked(ProcessRecord app) {
17597        final ActivityRecord TOP_ACT = resumedAppLocked();
17598        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17599        final boolean wasCached = app.cached;
17600
17601        mAdjSeq++;
17602
17603        // This is the desired cached adjusment we want to tell it to use.
17604        // If our app is currently cached, we know it, and that is it.  Otherwise,
17605        // we don't know it yet, and it needs to now be cached we will then
17606        // need to do a complete oom adj.
17607        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17608                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17609        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17610                SystemClock.uptimeMillis());
17611        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17612            // Changed to/from cached state, so apps after it in the LRU
17613            // list may also be changed.
17614            updateOomAdjLocked();
17615        }
17616        return success;
17617    }
17618
17619    final void updateOomAdjLocked() {
17620        final ActivityRecord TOP_ACT = resumedAppLocked();
17621        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17622        final long now = SystemClock.uptimeMillis();
17623        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17624        final int N = mLruProcesses.size();
17625
17626        if (false) {
17627            RuntimeException e = new RuntimeException();
17628            e.fillInStackTrace();
17629            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17630        }
17631
17632        mAdjSeq++;
17633        mNewNumServiceProcs = 0;
17634        mNewNumAServiceProcs = 0;
17635
17636        final int emptyProcessLimit;
17637        final int cachedProcessLimit;
17638        if (mProcessLimit <= 0) {
17639            emptyProcessLimit = cachedProcessLimit = 0;
17640        } else if (mProcessLimit == 1) {
17641            emptyProcessLimit = 1;
17642            cachedProcessLimit = 0;
17643        } else {
17644            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17645            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17646        }
17647
17648        // Let's determine how many processes we have running vs.
17649        // how many slots we have for background processes; we may want
17650        // to put multiple processes in a slot of there are enough of
17651        // them.
17652        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17653                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17654        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17655        if (numEmptyProcs > cachedProcessLimit) {
17656            // If there are more empty processes than our limit on cached
17657            // processes, then use the cached process limit for the factor.
17658            // This ensures that the really old empty processes get pushed
17659            // down to the bottom, so if we are running low on memory we will
17660            // have a better chance at keeping around more cached processes
17661            // instead of a gazillion empty processes.
17662            numEmptyProcs = cachedProcessLimit;
17663        }
17664        int emptyFactor = numEmptyProcs/numSlots;
17665        if (emptyFactor < 1) emptyFactor = 1;
17666        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17667        if (cachedFactor < 1) cachedFactor = 1;
17668        int stepCached = 0;
17669        int stepEmpty = 0;
17670        int numCached = 0;
17671        int numEmpty = 0;
17672        int numTrimming = 0;
17673
17674        mNumNonCachedProcs = 0;
17675        mNumCachedHiddenProcs = 0;
17676
17677        // First update the OOM adjustment for each of the
17678        // application processes based on their current state.
17679        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17680        int nextCachedAdj = curCachedAdj+1;
17681        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17682        int nextEmptyAdj = curEmptyAdj+2;
17683        for (int i=N-1; i>=0; i--) {
17684            ProcessRecord app = mLruProcesses.get(i);
17685            if (!app.killedByAm && app.thread != null) {
17686                app.procStateChanged = false;
17687                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17688
17689                // If we haven't yet assigned the final cached adj
17690                // to the process, do that now.
17691                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17692                    switch (app.curProcState) {
17693                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17694                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17695                            // This process is a cached process holding activities...
17696                            // assign it the next cached value for that type, and then
17697                            // step that cached level.
17698                            app.curRawAdj = curCachedAdj;
17699                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17700                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17701                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17702                                    + ")");
17703                            if (curCachedAdj != nextCachedAdj) {
17704                                stepCached++;
17705                                if (stepCached >= cachedFactor) {
17706                                    stepCached = 0;
17707                                    curCachedAdj = nextCachedAdj;
17708                                    nextCachedAdj += 2;
17709                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17710                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17711                                    }
17712                                }
17713                            }
17714                            break;
17715                        default:
17716                            // For everything else, assign next empty cached process
17717                            // level and bump that up.  Note that this means that
17718                            // long-running services that have dropped down to the
17719                            // cached level will be treated as empty (since their process
17720                            // state is still as a service), which is what we want.
17721                            app.curRawAdj = curEmptyAdj;
17722                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17723                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17724                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17725                                    + ")");
17726                            if (curEmptyAdj != nextEmptyAdj) {
17727                                stepEmpty++;
17728                                if (stepEmpty >= emptyFactor) {
17729                                    stepEmpty = 0;
17730                                    curEmptyAdj = nextEmptyAdj;
17731                                    nextEmptyAdj += 2;
17732                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17733                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17734                                    }
17735                                }
17736                            }
17737                            break;
17738                    }
17739                }
17740
17741                applyOomAdjLocked(app, TOP_APP, true, now);
17742
17743                // Count the number of process types.
17744                switch (app.curProcState) {
17745                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17746                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17747                        mNumCachedHiddenProcs++;
17748                        numCached++;
17749                        if (numCached > cachedProcessLimit) {
17750                            app.kill("cached #" + numCached, true);
17751                        }
17752                        break;
17753                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17754                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17755                                && app.lastActivityTime < oldTime) {
17756                            app.kill("empty for "
17757                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17758                                    / 1000) + "s", true);
17759                        } else {
17760                            numEmpty++;
17761                            if (numEmpty > emptyProcessLimit) {
17762                                app.kill("empty #" + numEmpty, true);
17763                            }
17764                        }
17765                        break;
17766                    default:
17767                        mNumNonCachedProcs++;
17768                        break;
17769                }
17770
17771                if (app.isolated && app.services.size() <= 0) {
17772                    // If this is an isolated process, and there are no
17773                    // services running in it, then the process is no longer
17774                    // needed.  We agressively kill these because we can by
17775                    // definition not re-use the same process again, and it is
17776                    // good to avoid having whatever code was running in them
17777                    // left sitting around after no longer needed.
17778                    app.kill("isolated not needed", true);
17779                }
17780
17781                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17782                        && !app.killedByAm) {
17783                    numTrimming++;
17784                }
17785            }
17786        }
17787
17788        mNumServiceProcs = mNewNumServiceProcs;
17789
17790        // Now determine the memory trimming level of background processes.
17791        // Unfortunately we need to start at the back of the list to do this
17792        // properly.  We only do this if the number of background apps we
17793        // are managing to keep around is less than half the maximum we desire;
17794        // if we are keeping a good number around, we'll let them use whatever
17795        // memory they want.
17796        final int numCachedAndEmpty = numCached + numEmpty;
17797        int memFactor;
17798        if (numCached <= ProcessList.TRIM_CACHED_APPS
17799                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17800            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17801                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17802            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17803                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17804            } else {
17805                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17806            }
17807        } else {
17808            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17809        }
17810        // We always allow the memory level to go up (better).  We only allow it to go
17811        // down if we are in a state where that is allowed, *and* the total number of processes
17812        // has gone down since last time.
17813        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17814                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17815                + " last=" + mLastNumProcesses);
17816        if (memFactor > mLastMemoryLevel) {
17817            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17818                memFactor = mLastMemoryLevel;
17819                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17820            }
17821        }
17822        mLastMemoryLevel = memFactor;
17823        mLastNumProcesses = mLruProcesses.size();
17824        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17825        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17826        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17827            if (mLowRamStartTime == 0) {
17828                mLowRamStartTime = now;
17829            }
17830            int step = 0;
17831            int fgTrimLevel;
17832            switch (memFactor) {
17833                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17834                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17835                    break;
17836                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17837                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17838                    break;
17839                default:
17840                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17841                    break;
17842            }
17843            int factor = numTrimming/3;
17844            int minFactor = 2;
17845            if (mHomeProcess != null) minFactor++;
17846            if (mPreviousProcess != null) minFactor++;
17847            if (factor < minFactor) factor = minFactor;
17848            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17849            for (int i=N-1; i>=0; i--) {
17850                ProcessRecord app = mLruProcesses.get(i);
17851                if (allChanged || app.procStateChanged) {
17852                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17853                    app.procStateChanged = false;
17854                }
17855                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17856                        && !app.killedByAm) {
17857                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17858                        try {
17859                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17860                                    "Trimming memory of " + app.processName
17861                                    + " to " + curLevel);
17862                            app.thread.scheduleTrimMemory(curLevel);
17863                        } catch (RemoteException e) {
17864                        }
17865                        if (false) {
17866                            // For now we won't do this; our memory trimming seems
17867                            // to be good enough at this point that destroying
17868                            // activities causes more harm than good.
17869                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17870                                    && app != mHomeProcess && app != mPreviousProcess) {
17871                                // Need to do this on its own message because the stack may not
17872                                // be in a consistent state at this point.
17873                                // For these apps we will also finish their activities
17874                                // to help them free memory.
17875                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17876                            }
17877                        }
17878                    }
17879                    app.trimMemoryLevel = curLevel;
17880                    step++;
17881                    if (step >= factor) {
17882                        step = 0;
17883                        switch (curLevel) {
17884                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17885                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17886                                break;
17887                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17888                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17889                                break;
17890                        }
17891                    }
17892                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17893                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17894                            && app.thread != null) {
17895                        try {
17896                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17897                                    "Trimming memory of heavy-weight " + app.processName
17898                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17899                            app.thread.scheduleTrimMemory(
17900                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17901                        } catch (RemoteException e) {
17902                        }
17903                    }
17904                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17905                } else {
17906                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17907                            || app.systemNoUi) && app.pendingUiClean) {
17908                        // If this application is now in the background and it
17909                        // had done UI, then give it the special trim level to
17910                        // have it free UI resources.
17911                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17912                        if (app.trimMemoryLevel < level && app.thread != null) {
17913                            try {
17914                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17915                                        "Trimming memory of bg-ui " + app.processName
17916                                        + " to " + level);
17917                                app.thread.scheduleTrimMemory(level);
17918                            } catch (RemoteException e) {
17919                            }
17920                        }
17921                        app.pendingUiClean = false;
17922                    }
17923                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17924                        try {
17925                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17926                                    "Trimming memory of fg " + app.processName
17927                                    + " to " + fgTrimLevel);
17928                            app.thread.scheduleTrimMemory(fgTrimLevel);
17929                        } catch (RemoteException e) {
17930                        }
17931                    }
17932                    app.trimMemoryLevel = fgTrimLevel;
17933                }
17934            }
17935        } else {
17936            if (mLowRamStartTime != 0) {
17937                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17938                mLowRamStartTime = 0;
17939            }
17940            for (int i=N-1; i>=0; i--) {
17941                ProcessRecord app = mLruProcesses.get(i);
17942                if (allChanged || app.procStateChanged) {
17943                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17944                    app.procStateChanged = false;
17945                }
17946                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17947                        || app.systemNoUi) && app.pendingUiClean) {
17948                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17949                            && app.thread != null) {
17950                        try {
17951                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17952                                    "Trimming memory of ui hidden " + app.processName
17953                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17954                            app.thread.scheduleTrimMemory(
17955                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17956                        } catch (RemoteException e) {
17957                        }
17958                    }
17959                    app.pendingUiClean = false;
17960                }
17961                app.trimMemoryLevel = 0;
17962            }
17963        }
17964
17965        if (mAlwaysFinishActivities) {
17966            // Need to do this on its own message because the stack may not
17967            // be in a consistent state at this point.
17968            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17969        }
17970
17971        if (allChanged) {
17972            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17973        }
17974
17975        if (mProcessStats.shouldWriteNowLocked(now)) {
17976            mHandler.post(new Runnable() {
17977                @Override public void run() {
17978                    synchronized (ActivityManagerService.this) {
17979                        mProcessStats.writeStateAsyncLocked();
17980                    }
17981                }
17982            });
17983        }
17984
17985        if (DEBUG_OOM_ADJ) {
17986            if (false) {
17987                RuntimeException here = new RuntimeException("here");
17988                here.fillInStackTrace();
17989                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17990            } else {
17991                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17992            }
17993        }
17994    }
17995
17996    final void trimApplications() {
17997        synchronized (this) {
17998            int i;
17999
18000            // First remove any unused application processes whose package
18001            // has been removed.
18002            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18003                final ProcessRecord app = mRemovedProcesses.get(i);
18004                if (app.activities.size() == 0
18005                        && app.curReceiver == null && app.services.size() == 0) {
18006                    Slog.i(
18007                        TAG, "Exiting empty application process "
18008                        + app.processName + " ("
18009                        + (app.thread != null ? app.thread.asBinder() : null)
18010                        + ")\n");
18011                    if (app.pid > 0 && app.pid != MY_PID) {
18012                        app.kill("empty", false);
18013                    } else {
18014                        try {
18015                            app.thread.scheduleExit();
18016                        } catch (Exception e) {
18017                            // Ignore exceptions.
18018                        }
18019                    }
18020                    cleanUpApplicationRecordLocked(app, false, true, -1);
18021                    mRemovedProcesses.remove(i);
18022
18023                    if (app.persistent) {
18024                        addAppLocked(app.info, false, null /* ABI override */);
18025                    }
18026                }
18027            }
18028
18029            // Now update the oom adj for all processes.
18030            updateOomAdjLocked();
18031        }
18032    }
18033
18034    /** This method sends the specified signal to each of the persistent apps */
18035    public void signalPersistentProcesses(int sig) throws RemoteException {
18036        if (sig != Process.SIGNAL_USR1) {
18037            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18038        }
18039
18040        synchronized (this) {
18041            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18042                    != PackageManager.PERMISSION_GRANTED) {
18043                throw new SecurityException("Requires permission "
18044                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18045            }
18046
18047            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18048                ProcessRecord r = mLruProcesses.get(i);
18049                if (r.thread != null && r.persistent) {
18050                    Process.sendSignal(r.pid, sig);
18051                }
18052            }
18053        }
18054    }
18055
18056    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18057        if (proc == null || proc == mProfileProc) {
18058            proc = mProfileProc;
18059            profileType = mProfileType;
18060            clearProfilerLocked();
18061        }
18062        if (proc == null) {
18063            return;
18064        }
18065        try {
18066            proc.thread.profilerControl(false, null, profileType);
18067        } catch (RemoteException e) {
18068            throw new IllegalStateException("Process disappeared");
18069        }
18070    }
18071
18072    private void clearProfilerLocked() {
18073        if (mProfileFd != null) {
18074            try {
18075                mProfileFd.close();
18076            } catch (IOException e) {
18077            }
18078        }
18079        mProfileApp = null;
18080        mProfileProc = null;
18081        mProfileFile = null;
18082        mProfileType = 0;
18083        mAutoStopProfiler = false;
18084        mSamplingInterval = 0;
18085    }
18086
18087    public boolean profileControl(String process, int userId, boolean start,
18088            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18089
18090        try {
18091            synchronized (this) {
18092                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18093                // its own permission.
18094                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18095                        != PackageManager.PERMISSION_GRANTED) {
18096                    throw new SecurityException("Requires permission "
18097                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18098                }
18099
18100                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18101                    throw new IllegalArgumentException("null profile info or fd");
18102                }
18103
18104                ProcessRecord proc = null;
18105                if (process != null) {
18106                    proc = findProcessLocked(process, userId, "profileControl");
18107                }
18108
18109                if (start && (proc == null || proc.thread == null)) {
18110                    throw new IllegalArgumentException("Unknown process: " + process);
18111                }
18112
18113                if (start) {
18114                    stopProfilerLocked(null, 0);
18115                    setProfileApp(proc.info, proc.processName, profilerInfo);
18116                    mProfileProc = proc;
18117                    mProfileType = profileType;
18118                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18119                    try {
18120                        fd = fd.dup();
18121                    } catch (IOException e) {
18122                        fd = null;
18123                    }
18124                    profilerInfo.profileFd = fd;
18125                    proc.thread.profilerControl(start, profilerInfo, profileType);
18126                    fd = null;
18127                    mProfileFd = null;
18128                } else {
18129                    stopProfilerLocked(proc, profileType);
18130                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18131                        try {
18132                            profilerInfo.profileFd.close();
18133                        } catch (IOException e) {
18134                        }
18135                    }
18136                }
18137
18138                return true;
18139            }
18140        } catch (RemoteException e) {
18141            throw new IllegalStateException("Process disappeared");
18142        } finally {
18143            if (profilerInfo != null && profilerInfo.profileFd != null) {
18144                try {
18145                    profilerInfo.profileFd.close();
18146                } catch (IOException e) {
18147                }
18148            }
18149        }
18150    }
18151
18152    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18153        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18154                userId, true, ALLOW_FULL_ONLY, callName, null);
18155        ProcessRecord proc = null;
18156        try {
18157            int pid = Integer.parseInt(process);
18158            synchronized (mPidsSelfLocked) {
18159                proc = mPidsSelfLocked.get(pid);
18160            }
18161        } catch (NumberFormatException e) {
18162        }
18163
18164        if (proc == null) {
18165            ArrayMap<String, SparseArray<ProcessRecord>> all
18166                    = mProcessNames.getMap();
18167            SparseArray<ProcessRecord> procs = all.get(process);
18168            if (procs != null && procs.size() > 0) {
18169                proc = procs.valueAt(0);
18170                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18171                    for (int i=1; i<procs.size(); i++) {
18172                        ProcessRecord thisProc = procs.valueAt(i);
18173                        if (thisProc.userId == userId) {
18174                            proc = thisProc;
18175                            break;
18176                        }
18177                    }
18178                }
18179            }
18180        }
18181
18182        return proc;
18183    }
18184
18185    public boolean dumpHeap(String process, int userId, boolean managed,
18186            String path, ParcelFileDescriptor fd) throws RemoteException {
18187
18188        try {
18189            synchronized (this) {
18190                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18191                // its own permission (same as profileControl).
18192                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18193                        != PackageManager.PERMISSION_GRANTED) {
18194                    throw new SecurityException("Requires permission "
18195                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18196                }
18197
18198                if (fd == null) {
18199                    throw new IllegalArgumentException("null fd");
18200                }
18201
18202                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18203                if (proc == null || proc.thread == null) {
18204                    throw new IllegalArgumentException("Unknown process: " + process);
18205                }
18206
18207                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18208                if (!isDebuggable) {
18209                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18210                        throw new SecurityException("Process not debuggable: " + proc);
18211                    }
18212                }
18213
18214                proc.thread.dumpHeap(managed, path, fd);
18215                fd = null;
18216                return true;
18217            }
18218        } catch (RemoteException e) {
18219            throw new IllegalStateException("Process disappeared");
18220        } finally {
18221            if (fd != null) {
18222                try {
18223                    fd.close();
18224                } catch (IOException e) {
18225                }
18226            }
18227        }
18228    }
18229
18230    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18231    public void monitor() {
18232        synchronized (this) { }
18233    }
18234
18235    void onCoreSettingsChange(Bundle settings) {
18236        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18237            ProcessRecord processRecord = mLruProcesses.get(i);
18238            try {
18239                if (processRecord.thread != null) {
18240                    processRecord.thread.setCoreSettings(settings);
18241                }
18242            } catch (RemoteException re) {
18243                /* ignore */
18244            }
18245        }
18246    }
18247
18248    // Multi-user methods
18249
18250    /**
18251     * Start user, if its not already running, but don't bring it to foreground.
18252     */
18253    @Override
18254    public boolean startUserInBackground(final int userId) {
18255        return startUser(userId, /* foreground */ false);
18256    }
18257
18258    /**
18259     * Start user, if its not already running, and bring it to foreground.
18260     */
18261    boolean startUserInForeground(final int userId, Dialog dlg) {
18262        boolean result = startUser(userId, /* foreground */ true);
18263        dlg.dismiss();
18264        return result;
18265    }
18266
18267    /**
18268     * Refreshes the list of users related to the current user when either a
18269     * user switch happens or when a new related user is started in the
18270     * background.
18271     */
18272    private void updateCurrentProfileIdsLocked() {
18273        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18274                mCurrentUserId, false /* enabledOnly */);
18275        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18276        for (int i = 0; i < currentProfileIds.length; i++) {
18277            currentProfileIds[i] = profiles.get(i).id;
18278        }
18279        mCurrentProfileIds = currentProfileIds;
18280
18281        synchronized (mUserProfileGroupIdsSelfLocked) {
18282            mUserProfileGroupIdsSelfLocked.clear();
18283            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18284            for (int i = 0; i < users.size(); i++) {
18285                UserInfo user = users.get(i);
18286                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18287                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18288                }
18289            }
18290        }
18291    }
18292
18293    private Set getProfileIdsLocked(int userId) {
18294        Set userIds = new HashSet<Integer>();
18295        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18296                userId, false /* enabledOnly */);
18297        for (UserInfo user : profiles) {
18298            userIds.add(Integer.valueOf(user.id));
18299        }
18300        return userIds;
18301    }
18302
18303    @Override
18304    public boolean switchUser(final int userId) {
18305        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18306        String userName;
18307        synchronized (this) {
18308            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18309            if (userInfo == null) {
18310                Slog.w(TAG, "No user info for user #" + userId);
18311                return false;
18312            }
18313            if (userInfo.isManagedProfile()) {
18314                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18315                return false;
18316            }
18317            userName = userInfo.name;
18318            mTargetUserId = userId;
18319        }
18320        mHandler.removeMessages(START_USER_SWITCH_MSG);
18321        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18322        return true;
18323    }
18324
18325    private void showUserSwitchDialog(int userId, String userName) {
18326        // The dialog will show and then initiate the user switch by calling startUserInForeground
18327        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18328                true /* above system */);
18329        d.show();
18330    }
18331
18332    private boolean startUser(final int userId, final boolean foreground) {
18333        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18334                != PackageManager.PERMISSION_GRANTED) {
18335            String msg = "Permission Denial: switchUser() from pid="
18336                    + Binder.getCallingPid()
18337                    + ", uid=" + Binder.getCallingUid()
18338                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18339            Slog.w(TAG, msg);
18340            throw new SecurityException(msg);
18341        }
18342
18343        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18344
18345        final long ident = Binder.clearCallingIdentity();
18346        try {
18347            synchronized (this) {
18348                final int oldUserId = mCurrentUserId;
18349                if (oldUserId == userId) {
18350                    return true;
18351                }
18352
18353                mStackSupervisor.setLockTaskModeLocked(null, false);
18354
18355                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18356                if (userInfo == null) {
18357                    Slog.w(TAG, "No user info for user #" + userId);
18358                    return false;
18359                }
18360                if (foreground && userInfo.isManagedProfile()) {
18361                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18362                    return false;
18363                }
18364
18365                if (foreground) {
18366                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18367                            R.anim.screen_user_enter);
18368                }
18369
18370                boolean needStart = false;
18371
18372                // If the user we are switching to is not currently started, then
18373                // we need to start it now.
18374                if (mStartedUsers.get(userId) == null) {
18375                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18376                    updateStartedUserArrayLocked();
18377                    needStart = true;
18378                }
18379
18380                final Integer userIdInt = Integer.valueOf(userId);
18381                mUserLru.remove(userIdInt);
18382                mUserLru.add(userIdInt);
18383
18384                if (foreground) {
18385                    mCurrentUserId = userId;
18386                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18387                    updateCurrentProfileIdsLocked();
18388                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18389                    // Once the internal notion of the active user has switched, we lock the device
18390                    // with the option to show the user switcher on the keyguard.
18391                    mWindowManager.lockNow(null);
18392                } else {
18393                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18394                    updateCurrentProfileIdsLocked();
18395                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18396                    mUserLru.remove(currentUserIdInt);
18397                    mUserLru.add(currentUserIdInt);
18398                }
18399
18400                final UserStartedState uss = mStartedUsers.get(userId);
18401
18402                // Make sure user is in the started state.  If it is currently
18403                // stopping, we need to knock that off.
18404                if (uss.mState == UserStartedState.STATE_STOPPING) {
18405                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18406                    // so we can just fairly silently bring the user back from
18407                    // the almost-dead.
18408                    uss.mState = UserStartedState.STATE_RUNNING;
18409                    updateStartedUserArrayLocked();
18410                    needStart = true;
18411                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18412                    // This means ACTION_SHUTDOWN has been sent, so we will
18413                    // need to treat this as a new boot of the user.
18414                    uss.mState = UserStartedState.STATE_BOOTING;
18415                    updateStartedUserArrayLocked();
18416                    needStart = true;
18417                }
18418
18419                if (uss.mState == UserStartedState.STATE_BOOTING) {
18420                    // Booting up a new user, need to tell system services about it.
18421                    // Note that this is on the same handler as scheduling of broadcasts,
18422                    // which is important because it needs to go first.
18423                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18424                }
18425
18426                if (foreground) {
18427                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18428                            oldUserId));
18429                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18430                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18431                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18432                            oldUserId, userId, uss));
18433                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18434                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18435                }
18436
18437                if (needStart) {
18438                    // Send USER_STARTED broadcast
18439                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18440                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18441                            | Intent.FLAG_RECEIVER_FOREGROUND);
18442                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18443                    broadcastIntentLocked(null, null, intent,
18444                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18445                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18446                }
18447
18448                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18449                    if (userId != UserHandle.USER_OWNER) {
18450                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18451                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18452                        broadcastIntentLocked(null, null, intent, null,
18453                                new IIntentReceiver.Stub() {
18454                                    public void performReceive(Intent intent, int resultCode,
18455                                            String data, Bundle extras, boolean ordered,
18456                                            boolean sticky, int sendingUser) {
18457                                        onUserInitialized(uss, foreground, oldUserId, userId);
18458                                    }
18459                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18460                                true, false, MY_PID, Process.SYSTEM_UID,
18461                                userId);
18462                        uss.initializing = true;
18463                    } else {
18464                        getUserManagerLocked().makeInitialized(userInfo.id);
18465                    }
18466                }
18467
18468                if (foreground) {
18469                    if (!uss.initializing) {
18470                        moveUserToForeground(uss, oldUserId, userId);
18471                    }
18472                } else {
18473                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18474                }
18475
18476                if (needStart) {
18477                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18478                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18479                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18480                    broadcastIntentLocked(null, null, intent,
18481                            null, new IIntentReceiver.Stub() {
18482                                @Override
18483                                public void performReceive(Intent intent, int resultCode, String data,
18484                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18485                                        throws RemoteException {
18486                                }
18487                            }, 0, null, null,
18488                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18489                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18490                }
18491            }
18492        } finally {
18493            Binder.restoreCallingIdentity(ident);
18494        }
18495
18496        return true;
18497    }
18498
18499    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18500        long ident = Binder.clearCallingIdentity();
18501        try {
18502            Intent intent;
18503            if (oldUserId >= 0) {
18504                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18505                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18506                int count = profiles.size();
18507                for (int i = 0; i < count; i++) {
18508                    int profileUserId = profiles.get(i).id;
18509                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18510                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18511                            | Intent.FLAG_RECEIVER_FOREGROUND);
18512                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18513                    broadcastIntentLocked(null, null, intent,
18514                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18515                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18516                }
18517            }
18518            if (newUserId >= 0) {
18519                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18520                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18521                int count = profiles.size();
18522                for (int i = 0; i < count; i++) {
18523                    int profileUserId = profiles.get(i).id;
18524                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18525                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18526                            | Intent.FLAG_RECEIVER_FOREGROUND);
18527                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18528                    broadcastIntentLocked(null, null, intent,
18529                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18530                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18531                }
18532                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18533                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18534                        | Intent.FLAG_RECEIVER_FOREGROUND);
18535                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18536                broadcastIntentLocked(null, null, intent,
18537                        null, null, 0, null, null,
18538                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18539                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18540            }
18541        } finally {
18542            Binder.restoreCallingIdentity(ident);
18543        }
18544    }
18545
18546    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18547            final int newUserId) {
18548        final int N = mUserSwitchObservers.beginBroadcast();
18549        if (N > 0) {
18550            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18551                int mCount = 0;
18552                @Override
18553                public void sendResult(Bundle data) throws RemoteException {
18554                    synchronized (ActivityManagerService.this) {
18555                        if (mCurUserSwitchCallback == this) {
18556                            mCount++;
18557                            if (mCount == N) {
18558                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18559                            }
18560                        }
18561                    }
18562                }
18563            };
18564            synchronized (this) {
18565                uss.switching = true;
18566                mCurUserSwitchCallback = callback;
18567            }
18568            for (int i=0; i<N; i++) {
18569                try {
18570                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18571                            newUserId, callback);
18572                } catch (RemoteException e) {
18573                }
18574            }
18575        } else {
18576            synchronized (this) {
18577                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18578            }
18579        }
18580        mUserSwitchObservers.finishBroadcast();
18581    }
18582
18583    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18584        synchronized (this) {
18585            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18586            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18587        }
18588    }
18589
18590    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18591        mCurUserSwitchCallback = null;
18592        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18593        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18594                oldUserId, newUserId, uss));
18595    }
18596
18597    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18598        synchronized (this) {
18599            if (foreground) {
18600                moveUserToForeground(uss, oldUserId, newUserId);
18601            }
18602        }
18603
18604        completeSwitchAndInitalize(uss, newUserId, true, false);
18605    }
18606
18607    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18608        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18609        if (homeInFront) {
18610            startHomeActivityLocked(newUserId);
18611        } else {
18612            mStackSupervisor.resumeTopActivitiesLocked();
18613        }
18614        EventLogTags.writeAmSwitchUser(newUserId);
18615        getUserManagerLocked().userForeground(newUserId);
18616        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18617    }
18618
18619    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18620        completeSwitchAndInitalize(uss, newUserId, false, true);
18621    }
18622
18623    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18624            boolean clearInitializing, boolean clearSwitching) {
18625        boolean unfrozen = false;
18626        synchronized (this) {
18627            if (clearInitializing) {
18628                uss.initializing = false;
18629                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18630            }
18631            if (clearSwitching) {
18632                uss.switching = false;
18633            }
18634            if (!uss.switching && !uss.initializing) {
18635                mWindowManager.stopFreezingScreen();
18636                unfrozen = true;
18637            }
18638        }
18639        if (unfrozen) {
18640            final int N = mUserSwitchObservers.beginBroadcast();
18641            for (int i=0; i<N; i++) {
18642                try {
18643                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18644                } catch (RemoteException e) {
18645                }
18646            }
18647            mUserSwitchObservers.finishBroadcast();
18648        }
18649    }
18650
18651    void scheduleStartProfilesLocked() {
18652        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18653            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18654                    DateUtils.SECOND_IN_MILLIS);
18655        }
18656    }
18657
18658    void startProfilesLocked() {
18659        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18660        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18661                mCurrentUserId, false /* enabledOnly */);
18662        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18663        for (UserInfo user : profiles) {
18664            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18665                    && user.id != mCurrentUserId) {
18666                toStart.add(user);
18667            }
18668        }
18669        final int n = toStart.size();
18670        int i = 0;
18671        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18672            startUserInBackground(toStart.get(i).id);
18673        }
18674        if (i < n) {
18675            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18676        }
18677    }
18678
18679    void finishUserBoot(UserStartedState uss) {
18680        synchronized (this) {
18681            if (uss.mState == UserStartedState.STATE_BOOTING
18682                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18683                uss.mState = UserStartedState.STATE_RUNNING;
18684                final int userId = uss.mHandle.getIdentifier();
18685                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18686                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18687                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18688                broadcastIntentLocked(null, null, intent,
18689                        null, null, 0, null, null,
18690                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18691                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18692            }
18693        }
18694    }
18695
18696    void finishUserSwitch(UserStartedState uss) {
18697        synchronized (this) {
18698            finishUserBoot(uss);
18699
18700            startProfilesLocked();
18701
18702            int num = mUserLru.size();
18703            int i = 0;
18704            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18705                Integer oldUserId = mUserLru.get(i);
18706                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18707                if (oldUss == null) {
18708                    // Shouldn't happen, but be sane if it does.
18709                    mUserLru.remove(i);
18710                    num--;
18711                    continue;
18712                }
18713                if (oldUss.mState == UserStartedState.STATE_STOPPING
18714                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18715                    // This user is already stopping, doesn't count.
18716                    num--;
18717                    i++;
18718                    continue;
18719                }
18720                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18721                    // Owner and current can't be stopped, but count as running.
18722                    i++;
18723                    continue;
18724                }
18725                // This is a user to be stopped.
18726                stopUserLocked(oldUserId, null);
18727                num--;
18728                i++;
18729            }
18730        }
18731    }
18732
18733    @Override
18734    public int stopUser(final int userId, final IStopUserCallback callback) {
18735        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18736                != PackageManager.PERMISSION_GRANTED) {
18737            String msg = "Permission Denial: switchUser() from pid="
18738                    + Binder.getCallingPid()
18739                    + ", uid=" + Binder.getCallingUid()
18740                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18741            Slog.w(TAG, msg);
18742            throw new SecurityException(msg);
18743        }
18744        if (userId <= 0) {
18745            throw new IllegalArgumentException("Can't stop primary user " + userId);
18746        }
18747        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18748        synchronized (this) {
18749            return stopUserLocked(userId, callback);
18750        }
18751    }
18752
18753    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18754        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18755        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18756            return ActivityManager.USER_OP_IS_CURRENT;
18757        }
18758
18759        final UserStartedState uss = mStartedUsers.get(userId);
18760        if (uss == null) {
18761            // User is not started, nothing to do...  but we do need to
18762            // callback if requested.
18763            if (callback != null) {
18764                mHandler.post(new Runnable() {
18765                    @Override
18766                    public void run() {
18767                        try {
18768                            callback.userStopped(userId);
18769                        } catch (RemoteException e) {
18770                        }
18771                    }
18772                });
18773            }
18774            return ActivityManager.USER_OP_SUCCESS;
18775        }
18776
18777        if (callback != null) {
18778            uss.mStopCallbacks.add(callback);
18779        }
18780
18781        if (uss.mState != UserStartedState.STATE_STOPPING
18782                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18783            uss.mState = UserStartedState.STATE_STOPPING;
18784            updateStartedUserArrayLocked();
18785
18786            long ident = Binder.clearCallingIdentity();
18787            try {
18788                // We are going to broadcast ACTION_USER_STOPPING and then
18789                // once that is done send a final ACTION_SHUTDOWN and then
18790                // stop the user.
18791                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18792                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18793                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18794                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18795                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18796                // This is the result receiver for the final shutdown broadcast.
18797                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18798                    @Override
18799                    public void performReceive(Intent intent, int resultCode, String data,
18800                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18801                        finishUserStop(uss);
18802                    }
18803                };
18804                // This is the result receiver for the initial stopping broadcast.
18805                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18806                    @Override
18807                    public void performReceive(Intent intent, int resultCode, String data,
18808                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18809                        // On to the next.
18810                        synchronized (ActivityManagerService.this) {
18811                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18812                                // Whoops, we are being started back up.  Abort, abort!
18813                                return;
18814                            }
18815                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18816                        }
18817                        mBatteryStatsService.noteEvent(
18818                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18819                                Integer.toString(userId), userId);
18820                        mSystemServiceManager.stopUser(userId);
18821                        broadcastIntentLocked(null, null, shutdownIntent,
18822                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18823                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18824                    }
18825                };
18826                // Kick things off.
18827                broadcastIntentLocked(null, null, stoppingIntent,
18828                        null, stoppingReceiver, 0, null, null,
18829                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18830                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18831            } finally {
18832                Binder.restoreCallingIdentity(ident);
18833            }
18834        }
18835
18836        return ActivityManager.USER_OP_SUCCESS;
18837    }
18838
18839    void finishUserStop(UserStartedState uss) {
18840        final int userId = uss.mHandle.getIdentifier();
18841        boolean stopped;
18842        ArrayList<IStopUserCallback> callbacks;
18843        synchronized (this) {
18844            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18845            if (mStartedUsers.get(userId) != uss) {
18846                stopped = false;
18847            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18848                stopped = false;
18849            } else {
18850                stopped = true;
18851                // User can no longer run.
18852                mStartedUsers.remove(userId);
18853                mUserLru.remove(Integer.valueOf(userId));
18854                updateStartedUserArrayLocked();
18855
18856                // Clean up all state and processes associated with the user.
18857                // Kill all the processes for the user.
18858                forceStopUserLocked(userId, "finish user");
18859            }
18860
18861            // Explicitly remove the old information in mRecentTasks.
18862            removeRecentTasksForUserLocked(userId);
18863        }
18864
18865        for (int i=0; i<callbacks.size(); i++) {
18866            try {
18867                if (stopped) callbacks.get(i).userStopped(userId);
18868                else callbacks.get(i).userStopAborted(userId);
18869            } catch (RemoteException e) {
18870            }
18871        }
18872
18873        if (stopped) {
18874            mSystemServiceManager.cleanupUser(userId);
18875            synchronized (this) {
18876                mStackSupervisor.removeUserLocked(userId);
18877            }
18878        }
18879    }
18880
18881    @Override
18882    public UserInfo getCurrentUser() {
18883        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18884                != PackageManager.PERMISSION_GRANTED) && (
18885                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18886                != PackageManager.PERMISSION_GRANTED)) {
18887            String msg = "Permission Denial: getCurrentUser() from pid="
18888                    + Binder.getCallingPid()
18889                    + ", uid=" + Binder.getCallingUid()
18890                    + " requires " + INTERACT_ACROSS_USERS;
18891            Slog.w(TAG, msg);
18892            throw new SecurityException(msg);
18893        }
18894        synchronized (this) {
18895            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18896            return getUserManagerLocked().getUserInfo(userId);
18897        }
18898    }
18899
18900    int getCurrentUserIdLocked() {
18901        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18902    }
18903
18904    @Override
18905    public boolean isUserRunning(int userId, boolean orStopped) {
18906        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18907                != PackageManager.PERMISSION_GRANTED) {
18908            String msg = "Permission Denial: isUserRunning() from pid="
18909                    + Binder.getCallingPid()
18910                    + ", uid=" + Binder.getCallingUid()
18911                    + " requires " + INTERACT_ACROSS_USERS;
18912            Slog.w(TAG, msg);
18913            throw new SecurityException(msg);
18914        }
18915        synchronized (this) {
18916            return isUserRunningLocked(userId, orStopped);
18917        }
18918    }
18919
18920    boolean isUserRunningLocked(int userId, boolean orStopped) {
18921        UserStartedState state = mStartedUsers.get(userId);
18922        if (state == null) {
18923            return false;
18924        }
18925        if (orStopped) {
18926            return true;
18927        }
18928        return state.mState != UserStartedState.STATE_STOPPING
18929                && state.mState != UserStartedState.STATE_SHUTDOWN;
18930    }
18931
18932    @Override
18933    public int[] getRunningUserIds() {
18934        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18935                != PackageManager.PERMISSION_GRANTED) {
18936            String msg = "Permission Denial: isUserRunning() from pid="
18937                    + Binder.getCallingPid()
18938                    + ", uid=" + Binder.getCallingUid()
18939                    + " requires " + INTERACT_ACROSS_USERS;
18940            Slog.w(TAG, msg);
18941            throw new SecurityException(msg);
18942        }
18943        synchronized (this) {
18944            return mStartedUserArray;
18945        }
18946    }
18947
18948    private void updateStartedUserArrayLocked() {
18949        int num = 0;
18950        for (int i=0; i<mStartedUsers.size();  i++) {
18951            UserStartedState uss = mStartedUsers.valueAt(i);
18952            // This list does not include stopping users.
18953            if (uss.mState != UserStartedState.STATE_STOPPING
18954                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18955                num++;
18956            }
18957        }
18958        mStartedUserArray = new int[num];
18959        num = 0;
18960        for (int i=0; i<mStartedUsers.size();  i++) {
18961            UserStartedState uss = mStartedUsers.valueAt(i);
18962            if (uss.mState != UserStartedState.STATE_STOPPING
18963                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18964                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18965                num++;
18966            }
18967        }
18968    }
18969
18970    @Override
18971    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18972        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18973                != PackageManager.PERMISSION_GRANTED) {
18974            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18975                    + Binder.getCallingPid()
18976                    + ", uid=" + Binder.getCallingUid()
18977                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18978            Slog.w(TAG, msg);
18979            throw new SecurityException(msg);
18980        }
18981
18982        mUserSwitchObservers.register(observer);
18983    }
18984
18985    @Override
18986    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18987        mUserSwitchObservers.unregister(observer);
18988    }
18989
18990    private boolean userExists(int userId) {
18991        if (userId == 0) {
18992            return true;
18993        }
18994        UserManagerService ums = getUserManagerLocked();
18995        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18996    }
18997
18998    int[] getUsersLocked() {
18999        UserManagerService ums = getUserManagerLocked();
19000        return ums != null ? ums.getUserIds() : new int[] { 0 };
19001    }
19002
19003    UserManagerService getUserManagerLocked() {
19004        if (mUserManager == null) {
19005            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19006            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19007        }
19008        return mUserManager;
19009    }
19010
19011    private int applyUserId(int uid, int userId) {
19012        return UserHandle.getUid(userId, uid);
19013    }
19014
19015    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19016        if (info == null) return null;
19017        ApplicationInfo newInfo = new ApplicationInfo(info);
19018        newInfo.uid = applyUserId(info.uid, userId);
19019        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19020                + info.packageName;
19021        return newInfo;
19022    }
19023
19024    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19025        if (aInfo == null
19026                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19027            return aInfo;
19028        }
19029
19030        ActivityInfo info = new ActivityInfo(aInfo);
19031        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19032        return info;
19033    }
19034
19035    private final class LocalService extends ActivityManagerInternal {
19036        @Override
19037        public void goingToSleep() {
19038            ActivityManagerService.this.goingToSleep();
19039        }
19040
19041        @Override
19042        public void wakingUp() {
19043            ActivityManagerService.this.wakingUp();
19044        }
19045
19046        @Override
19047        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19048                String processName, String abiOverride, int uid, Runnable crashHandler) {
19049            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19050                    processName, abiOverride, uid, crashHandler);
19051        }
19052    }
19053
19054    /**
19055     * An implementation of IAppTask, that allows an app to manage its own tasks via
19056     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19057     * only the process that calls getAppTasks() can call the AppTask methods.
19058     */
19059    class AppTaskImpl extends IAppTask.Stub {
19060        private int mTaskId;
19061        private int mCallingUid;
19062
19063        public AppTaskImpl(int taskId, int callingUid) {
19064            mTaskId = taskId;
19065            mCallingUid = callingUid;
19066        }
19067
19068        private void checkCaller() {
19069            if (mCallingUid != Binder.getCallingUid()) {
19070                throw new SecurityException("Caller " + mCallingUid
19071                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19072            }
19073        }
19074
19075        @Override
19076        public void finishAndRemoveTask() {
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                    // Only kill the process if we are not a new document
19087                    int flags = tr.getBaseIntent().getFlags();
19088                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19089                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19090                    removeTaskByIdLocked(mTaskId,
19091                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19092                } finally {
19093                    Binder.restoreCallingIdentity(origId);
19094                }
19095            }
19096        }
19097
19098        @Override
19099        public ActivityManager.RecentTaskInfo getTaskInfo() {
19100            checkCaller();
19101
19102            synchronized (ActivityManagerService.this) {
19103                long origId = Binder.clearCallingIdentity();
19104                try {
19105                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19106                    if (tr == null) {
19107                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19108                    }
19109                    return createRecentTaskInfoFromTaskRecord(tr);
19110                } finally {
19111                    Binder.restoreCallingIdentity(origId);
19112                }
19113            }
19114        }
19115
19116        @Override
19117        public void moveToFront() {
19118            checkCaller();
19119
19120            final TaskRecord tr;
19121            synchronized (ActivityManagerService.this) {
19122                tr = recentTaskForIdLocked(mTaskId);
19123                if (tr == null) {
19124                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19125                }
19126                if (tr.getRootActivity() != null) {
19127                    moveTaskToFrontLocked(tr.taskId, 0, null);
19128                    return;
19129                }
19130            }
19131
19132            startActivityFromRecentsInner(tr.taskId, null);
19133        }
19134
19135        @Override
19136        public int startActivity(IBinder whoThread, String callingPackage,
19137                Intent intent, String resolvedType, Bundle options) {
19138            checkCaller();
19139
19140            int callingUser = UserHandle.getCallingUserId();
19141            TaskRecord tr;
19142            IApplicationThread appThread;
19143            synchronized (ActivityManagerService.this) {
19144                tr = recentTaskForIdLocked(mTaskId);
19145                if (tr == null) {
19146                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19147                }
19148                appThread = ApplicationThreadNative.asInterface(whoThread);
19149                if (appThread == null) {
19150                    throw new IllegalArgumentException("Bad app thread " + appThread);
19151                }
19152            }
19153            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19154                    resolvedType, null, null, null, null, 0, 0, null, null,
19155                    null, options, callingUser, null, tr);
19156        }
19157
19158        @Override
19159        public void setExcludeFromRecents(boolean exclude) {
19160            checkCaller();
19161
19162            synchronized (ActivityManagerService.this) {
19163                long origId = Binder.clearCallingIdentity();
19164                try {
19165                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19166                    if (tr == null) {
19167                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19168                    }
19169                    Intent intent = tr.getBaseIntent();
19170                    if (exclude) {
19171                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19172                    } else {
19173                        intent.setFlags(intent.getFlags()
19174                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19175                    }
19176                } finally {
19177                    Binder.restoreCallingIdentity(origId);
19178                }
19179            }
19180        }
19181    }
19182}
19183