ActivityManagerService.java revision 605eb79c9519307147fc1795d0eb155638a7f542
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.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203import dalvik.system.VMRuntime;
204
205import java.io.BufferedInputStream;
206import java.io.BufferedOutputStream;
207import java.io.DataInputStream;
208import java.io.DataOutputStream;
209import java.io.File;
210import java.io.FileDescriptor;
211import java.io.FileInputStream;
212import java.io.FileNotFoundException;
213import java.io.FileOutputStream;
214import java.io.IOException;
215import java.io.InputStreamReader;
216import java.io.PrintWriter;
217import java.io.StringWriter;
218import java.lang.ref.WeakReference;
219import java.util.ArrayList;
220import java.util.Arrays;
221import java.util.Collections;
222import java.util.Comparator;
223import java.util.HashMap;
224import java.util.HashSet;
225import java.util.Iterator;
226import java.util.List;
227import java.util.Locale;
228import java.util.Map;
229import java.util.Set;
230import java.util.concurrent.atomic.AtomicBoolean;
231import java.util.concurrent.atomic.AtomicLong;
232
233public final class ActivityManagerService extends ActivityManagerNative
234        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
235
236    private static final String USER_DATA_DIR = "/data/user/";
237    // File that stores last updated system version and called preboot receivers
238    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
239
240    static final String TAG = "ActivityManager";
241    static final String TAG_MU = "ActivityManagerServiceMU";
242    static final boolean DEBUG = false;
243    static final boolean localLOGV = DEBUG;
244    static final boolean DEBUG_BACKUP = localLOGV || false;
245    static final boolean DEBUG_BROADCAST = localLOGV || false;
246    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_CLEANUP = localLOGV || false;
249    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
250    static final boolean DEBUG_FOCUS = false;
251    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
252    static final boolean DEBUG_MU = localLOGV || false;
253    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
254    static final boolean DEBUG_LRU = localLOGV || false;
255    static final boolean DEBUG_PAUSE = localLOGV || false;
256    static final boolean DEBUG_POWER = localLOGV || false;
257    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
258    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
259    static final boolean DEBUG_PROCESSES = localLOGV || false;
260    static final boolean DEBUG_PROVIDER = localLOGV || false;
261    static final boolean DEBUG_RESULTS = localLOGV || false;
262    static final boolean DEBUG_SERVICE = localLOGV || false;
263    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
264    static final boolean DEBUG_STACK = localLOGV || false;
265    static final boolean DEBUG_SWITCH = localLOGV || false;
266    static final boolean DEBUG_TASKS = localLOGV || false;
267    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
268    static final boolean DEBUG_TRANSITION = localLOGV || false;
269    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
270    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
271    static final boolean DEBUG_VISBILITY = localLOGV || false;
272    static final boolean DEBUG_PSS = localLOGV || false;
273    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
274    static final boolean DEBUG_RECENTS = localLOGV || false;
275    static final boolean VALIDATE_TOKENS = false;
276    static final boolean SHOW_ACTIVITY_START_TIME = true;
277
278    // Control over CPU and battery monitoring.
279    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
280    static final boolean MONITOR_CPU_USAGE = true;
281    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
282    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
283    static final boolean MONITOR_THREAD_CPU_USAGE = false;
284
285    // The flags that are set for all calls we make to the package manager.
286    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
287
288    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
289
290    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
291
292    // Maximum number recent bitmaps to keep in memory.
293    static final int MAX_RECENT_BITMAPS = 5;
294
295    // Amount of time after a call to stopAppSwitches() during which we will
296    // prevent further untrusted switches from happening.
297    static final long APP_SWITCH_DELAY_TIME = 5*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real.
301    static final int PROC_START_TIMEOUT = 10*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real, when the process was
305    // started with a wrapper for instrumentation (such as Valgrind) because it
306    // could take much longer than usual.
307    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
308
309    // How long to wait after going idle before forcing apps to GC.
310    static final int GC_TIMEOUT = 5*1000;
311
312    // The minimum amount of time between successive GC requests for a process.
313    static final int GC_MIN_INTERVAL = 60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process.
316    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process
319    // when the request is due to the memory state being lowered.
320    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
321
322    // The rate at which we check for apps using excessive power -- 15 mins.
323    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on wake locks to start killing things.
327    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on CPU usage to start killing things.
331    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // How long we allow a receiver to run before giving up on it.
334    static final int BROADCAST_FG_TIMEOUT = 10*1000;
335    static final int BROADCAST_BG_TIMEOUT = 60*1000;
336
337    // How long we wait until we timeout on key dispatching.
338    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
339
340    // How long we wait until we timeout on key dispatching during instrumentation.
341    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
342
343    // Amount of time we wait for observers to handle a user switch before
344    // giving up on them and unfreezing the screen.
345    static final int USER_SWITCH_TIMEOUT = 2*1000;
346
347    // Maximum number of users we allow to be running at a time.
348    static final int MAX_RUNNING_USERS = 3;
349
350    // How long to wait in getAssistContextExtras for the activity and foreground services
351    // to respond with the result.
352    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
353
354    // Maximum number of persisted Uri grants a package is allowed
355    static final int MAX_PERSISTED_URI_GRANTS = 128;
356
357    static final int MY_PID = Process.myPid();
358
359    static final String[] EMPTY_STRING_ARRAY = new String[0];
360
361    // How many bytes to write into the dropbox log before truncating
362    static final int DROPBOX_MAX_SIZE = 256 * 1024;
363
364    // Access modes for handleIncomingUser.
365    static final int ALLOW_NON_FULL = 0;
366    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
367    static final int ALLOW_FULL_ONLY = 2;
368
369    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
370
371    /** All system services */
372    SystemServiceManager mSystemServiceManager;
373
374    private Installer mInstaller;
375
376    /** Run all ActivityStacks through this */
377    ActivityStackSupervisor mStackSupervisor;
378
379    public IntentFirewall mIntentFirewall;
380
381    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
382    // default actuion automatically.  Important for devices without direct input
383    // devices.
384    private boolean mShowDialogs = true;
385
386    BroadcastQueue mFgBroadcastQueue;
387    BroadcastQueue mBgBroadcastQueue;
388    // Convenient for easy iteration over the queues. Foreground is first
389    // so that dispatch of foreground broadcasts gets precedence.
390    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
391
392    BroadcastQueue broadcastQueueForIntent(Intent intent) {
393        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
394        if (DEBUG_BACKGROUND_BROADCAST) {
395            Slog.i(TAG, "Broadcast intent " + intent + " on "
396                    + (isFg ? "foreground" : "background")
397                    + " queue");
398        }
399        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
412
413    /**
414     * For addAppTask: cached of the last activity component that was added.
415     */
416    ComponentName mLastAddedTaskComponent;
417
418    /**
419     * For addAppTask: cached of the last activity uid that was added.
420     */
421    int mLastAddedTaskUid;
422
423    /**
424     * For addAppTask: cached of the last ActivityInfo that was added.
425     */
426    ActivityInfo mLastAddedTaskActivity;
427
428    public class PendingAssistExtras extends Binder implements Runnable {
429        public final ActivityRecord activity;
430        public final Bundle extras;
431        public final Intent intent;
432        public final String hint;
433        public final int userHandle;
434        public boolean haveResult = false;
435        public Bundle result = null;
436        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
437                String _hint, int _userHandle) {
438            activity = _activity;
439            extras = _extras;
440            intent = _intent;
441            hint = _hint;
442            userHandle = _userHandle;
443        }
444        @Override
445        public void run() {
446            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
447            synchronized (this) {
448                haveResult = true;
449                notifyAll();
450            }
451        }
452    }
453
454    final ArrayList<PendingAssistExtras> mPendingAssistExtras
455            = new ArrayList<PendingAssistExtras>();
456
457    /**
458     * Process management.
459     */
460    final ProcessList mProcessList = new ProcessList();
461
462    /**
463     * All of the applications we currently have running organized by name.
464     * The keys are strings of the application package name (as
465     * returned by the package manager), and the keys are ApplicationRecord
466     * objects.
467     */
468    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
469
470    /**
471     * Tracking long-term execution of processes to look for abuse and other
472     * bad app behavior.
473     */
474    final ProcessStatsService mProcessStats;
475
476    /**
477     * The currently running isolated processes.
478     */
479    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
480
481    /**
482     * Counter for assigning isolated process uids, to avoid frequently reusing the
483     * same ones.
484     */
485    int mNextIsolatedProcessUid = 0;
486
487    /**
488     * The currently running heavy-weight process, if any.
489     */
490    ProcessRecord mHeavyWeightProcess = null;
491
492    /**
493     * The last time that various processes have crashed.
494     */
495    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
496
497    /**
498     * Information about a process that is currently marked as bad.
499     */
500    static final class BadProcessInfo {
501        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
502            this.time = time;
503            this.shortMsg = shortMsg;
504            this.longMsg = longMsg;
505            this.stack = stack;
506        }
507
508        final long time;
509        final String shortMsg;
510        final String longMsg;
511        final String stack;
512    }
513
514    /**
515     * Set of applications that we consider to be bad, and will reject
516     * incoming broadcasts from (which the user has no control over).
517     * Processes are added to this set when they have crashed twice within
518     * a minimum amount of time; they are removed from it when they are
519     * later restarted (hopefully due to some user action).  The value is the
520     * time it was added to the list.
521     */
522    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
523
524    /**
525     * All of the processes we currently have running organized by pid.
526     * The keys are the pid running the application.
527     *
528     * <p>NOTE: This object is protected by its own lock, NOT the global
529     * activity manager lock!
530     */
531    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
532
533    /**
534     * All of the processes that have been forced to be foreground.  The key
535     * is the pid of the caller who requested it (we hold a death
536     * link on it).
537     */
538    abstract class ForegroundToken implements IBinder.DeathRecipient {
539        int pid;
540        IBinder token;
541    }
542    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
543
544    /**
545     * List of records for processes that someone had tried to start before the
546     * system was ready.  We don't start them at that point, but ensure they
547     * are started by the time booting is complete.
548     */
549    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
550
551    /**
552     * List of persistent applications that are in the process
553     * of being started.
554     */
555    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * Processes that are being forcibly torn down.
559     */
560    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
561
562    /**
563     * List of running applications, sorted by recent usage.
564     * The first entry in the list is the least recently used.
565     */
566    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
567
568    /**
569     * Where in mLruProcesses that the processes hosting activities start.
570     */
571    int mLruProcessActivityStart = 0;
572
573    /**
574     * Where in mLruProcesses that the processes hosting services start.
575     * This is after (lower index) than mLruProcessesActivityStart.
576     */
577    int mLruProcessServiceStart = 0;
578
579    /**
580     * List of processes that should gc as soon as things are idle.
581     */
582    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
583
584    /**
585     * Processes we want to collect PSS data from.
586     */
587    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Last time we requested PSS data of all processes.
591     */
592    long mLastFullPssTime = SystemClock.uptimeMillis();
593
594    /**
595     * If set, the next time we collect PSS data we should do a full collection
596     * with data from native processes and the kernel.
597     */
598    boolean mFullPssPending = false;
599
600    /**
601     * This is the process holding what we currently consider to be
602     * the "home" activity.
603     */
604    ProcessRecord mHomeProcess;
605
606    /**
607     * This is the process holding the activity the user last visited that
608     * is in a different process from the one they are currently in.
609     */
610    ProcessRecord mPreviousProcess;
611
612    /**
613     * The time at which the previous process was last visible.
614     */
615    long mPreviousProcessVisibleTime;
616
617    /**
618     * Which uses have been started, so are allowed to run code.
619     */
620    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
621
622    /**
623     * LRU list of history of current users.  Most recently current is at the end.
624     */
625    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
626
627    /**
628     * Constant array of the users that are currently started.
629     */
630    int[] mStartedUserArray = new int[] { 0 };
631
632    /**
633     * Registered observers of the user switching mechanics.
634     */
635    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
636            = new RemoteCallbackList<IUserSwitchObserver>();
637
638    /**
639     * Currently active user switch.
640     */
641    Object mCurUserSwitchCallback;
642
643    /**
644     * Packages that the user has asked to have run in screen size
645     * compatibility mode instead of filling the screen.
646     */
647    final CompatModePackages mCompatModePackages;
648
649    /**
650     * Set of IntentSenderRecord objects that are currently active.
651     */
652    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
653            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
654
655    /**
656     * Fingerprints (hashCode()) of stack traces that we've
657     * already logged DropBox entries for.  Guarded by itself.  If
658     * something (rogue user app) forces this over
659     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
660     */
661    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
662    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
663
664    /**
665     * Strict Mode background batched logging state.
666     *
667     * The string buffer is guarded by itself, and its lock is also
668     * used to determine if another batched write is already
669     * in-flight.
670     */
671    private final StringBuilder mStrictModeBuffer = new StringBuilder();
672
673    /**
674     * Keeps track of all IIntentReceivers that have been registered for
675     * broadcasts.  Hash keys are the receiver IBinder, hash value is
676     * a ReceiverList.
677     */
678    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
679            new HashMap<IBinder, ReceiverList>();
680
681    /**
682     * Resolver for broadcast intents to registered receivers.
683     * Holds BroadcastFilter (subclass of IntentFilter).
684     */
685    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
686            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
687        @Override
688        protected boolean allowFilterResult(
689                BroadcastFilter filter, List<BroadcastFilter> dest) {
690            IBinder target = filter.receiverList.receiver.asBinder();
691            for (int i=dest.size()-1; i>=0; i--) {
692                if (dest.get(i).receiverList.receiver.asBinder() == target) {
693                    return false;
694                }
695            }
696            return true;
697        }
698
699        @Override
700        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
701            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
702                    || userId == filter.owningUserId) {
703                return super.newResult(filter, match, userId);
704            }
705            return null;
706        }
707
708        @Override
709        protected BroadcastFilter[] newArray(int size) {
710            return new BroadcastFilter[size];
711        }
712
713        @Override
714        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
715            return packageName.equals(filter.packageName);
716        }
717    };
718
719    /**
720     * State of all active sticky broadcasts per user.  Keys are the action of the
721     * sticky Intent, values are an ArrayList of all broadcasted intents with
722     * that action (which should usually be one).  The SparseArray is keyed
723     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
724     * for stickies that are sent to all users.
725     */
726    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
727            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
728
729    final ActiveServices mServices;
730
731    /**
732     * Backup/restore process management
733     */
734    String mBackupAppName = null;
735    BackupRecord mBackupTarget = null;
736
737    final ProviderMap mProviderMap;
738
739    /**
740     * List of content providers who have clients waiting for them.  The
741     * application is currently being launched and the provider will be
742     * removed from this list once it is published.
743     */
744    final ArrayList<ContentProviderRecord> mLaunchingProviders
745            = new ArrayList<ContentProviderRecord>();
746
747    /**
748     * File storing persisted {@link #mGrantedUriPermissions}.
749     */
750    private final AtomicFile mGrantFile;
751
752    /** XML constants used in {@link #mGrantFile} */
753    private static final String TAG_URI_GRANTS = "uri-grants";
754    private static final String TAG_URI_GRANT = "uri-grant";
755    private static final String ATTR_USER_HANDLE = "userHandle";
756    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
757    private static final String ATTR_TARGET_USER_ID = "targetUserId";
758    private static final String ATTR_SOURCE_PKG = "sourcePkg";
759    private static final String ATTR_TARGET_PKG = "targetPkg";
760    private static final String ATTR_URI = "uri";
761    private static final String ATTR_MODE_FLAGS = "modeFlags";
762    private static final String ATTR_CREATED_TIME = "createdTime";
763    private static final String ATTR_PREFIX = "prefix";
764
765    /**
766     * Global set of specific {@link Uri} permissions that have been granted.
767     * This optimized lookup structure maps from {@link UriPermission#targetUid}
768     * to {@link UriPermission#uri} to {@link UriPermission}.
769     */
770    @GuardedBy("this")
771    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
772            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
773
774    public static class GrantUri {
775        public final int sourceUserId;
776        public final Uri uri;
777        public boolean prefix;
778
779        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
780            this.sourceUserId = sourceUserId;
781            this.uri = uri;
782            this.prefix = prefix;
783        }
784
785        @Override
786        public int hashCode() {
787            return toString().hashCode();
788        }
789
790        @Override
791        public boolean equals(Object o) {
792            if (o instanceof GrantUri) {
793                GrantUri other = (GrantUri) o;
794                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
795                        && prefix == other.prefix;
796            }
797            return false;
798        }
799
800        @Override
801        public String toString() {
802            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
803            if (prefix) result += " [prefix]";
804            return result;
805        }
806
807        public String toSafeString() {
808            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
809            if (prefix) result += " [prefix]";
810            return result;
811        }
812
813        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
814            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
815                    ContentProvider.getUriWithoutUserId(uri), false);
816        }
817    }
818
819    CoreSettingsObserver mCoreSettingsObserver;
820
821    /**
822     * Thread-local storage used to carry caller permissions over through
823     * indirect content-provider access.
824     */
825    private class Identity {
826        public int pid;
827        public int uid;
828
829        Identity(int _pid, int _uid) {
830            pid = _pid;
831            uid = _uid;
832        }
833    }
834
835    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
836
837    /**
838     * All information we have collected about the runtime performance of
839     * any user id that can impact battery performance.
840     */
841    final BatteryStatsService mBatteryStatsService;
842
843    /**
844     * Information about component usage
845     */
846    UsageStatsManagerInternal mUsageStatsService;
847
848    /**
849     * Information about and control over application operations
850     */
851    final AppOpsService mAppOpsService;
852
853    /**
854     * Save recent tasks information across reboots.
855     */
856    final TaskPersister mTaskPersister;
857
858    /**
859     * Current configuration information.  HistoryRecord objects are given
860     * a reference to this object to indicate which configuration they are
861     * currently running in, so this object must be kept immutable.
862     */
863    Configuration mConfiguration = new Configuration();
864
865    /**
866     * Current sequencing integer of the configuration, for skipping old
867     * configurations.
868     */
869    int mConfigurationSeq = 0;
870
871    /**
872     * Hardware-reported OpenGLES version.
873     */
874    final int GL_ES_VERSION;
875
876    /**
877     * List of initialization arguments to pass to all processes when binding applications to them.
878     * For example, references to the commonly used services.
879     */
880    HashMap<String, IBinder> mAppBindArgs;
881
882    /**
883     * Temporary to avoid allocations.  Protected by main lock.
884     */
885    final StringBuilder mStringBuilder = new StringBuilder(256);
886
887    /**
888     * Used to control how we initialize the service.
889     */
890    ComponentName mTopComponent;
891    String mTopAction = Intent.ACTION_MAIN;
892    String mTopData;
893    boolean mProcessesReady = false;
894    boolean mSystemReady = false;
895    boolean mBooting = false;
896    boolean mCallFinishBooting = false;
897    boolean mBootAnimationComplete = false;
898    boolean mWaitingUpdate = false;
899    boolean mDidUpdate = false;
900    boolean mOnBattery = false;
901    boolean mLaunchWarningShown = false;
902
903    Context mContext;
904
905    int mFactoryTest;
906
907    boolean mCheckedForSetup;
908
909    /**
910     * The time at which we will allow normal application switches again,
911     * after a call to {@link #stopAppSwitches()}.
912     */
913    long mAppSwitchesAllowedTime;
914
915    /**
916     * This is set to true after the first switch after mAppSwitchesAllowedTime
917     * is set; any switches after that will clear the time.
918     */
919    boolean mDidAppSwitch;
920
921    /**
922     * Last time (in realtime) at which we checked for power usage.
923     */
924    long mLastPowerCheckRealtime;
925
926    /**
927     * Last time (in uptime) at which we checked for power usage.
928     */
929    long mLastPowerCheckUptime;
930
931    /**
932     * Set while we are wanting to sleep, to prevent any
933     * activities from being started/resumed.
934     */
935    private boolean mSleeping = false;
936
937    /**
938     * Set while we are running a voice interaction.  This overrides
939     * sleeping while it is active.
940     */
941    private boolean mRunningVoice = false;
942
943    /**
944     * State of external calls telling us if the device is asleep.
945     */
946    private boolean mWentToSleep = false;
947
948    /**
949     * State of external call telling us if the lock screen is shown.
950     */
951    private boolean mLockScreenShown = false;
952
953    /**
954     * Set if we are shutting down the system, similar to sleeping.
955     */
956    boolean mShuttingDown = false;
957
958    /**
959     * Current sequence id for oom_adj computation traversal.
960     */
961    int mAdjSeq = 0;
962
963    /**
964     * Current sequence id for process LRU updating.
965     */
966    int mLruSeq = 0;
967
968    /**
969     * Keep track of the non-cached/empty process we last found, to help
970     * determine how to distribute cached/empty processes next time.
971     */
972    int mNumNonCachedProcs = 0;
973
974    /**
975     * Keep track of the number of cached hidden procs, to balance oom adj
976     * distribution between those and empty procs.
977     */
978    int mNumCachedHiddenProcs = 0;
979
980    /**
981     * Keep track of the number of service processes we last found, to
982     * determine on the next iteration which should be B services.
983     */
984    int mNumServiceProcs = 0;
985    int mNewNumAServiceProcs = 0;
986    int mNewNumServiceProcs = 0;
987
988    /**
989     * Allow the current computed overall memory level of the system to go down?
990     * This is set to false when we are killing processes for reasons other than
991     * memory management, so that the now smaller process list will not be taken as
992     * an indication that memory is tighter.
993     */
994    boolean mAllowLowerMemLevel = false;
995
996    /**
997     * The last computed memory level, for holding when we are in a state that
998     * processes are going away for other reasons.
999     */
1000    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1001
1002    /**
1003     * The last total number of process we have, to determine if changes actually look
1004     * like a shrinking number of process due to lower RAM.
1005     */
1006    int mLastNumProcesses;
1007
1008    /**
1009     * The uptime of the last time we performed idle maintenance.
1010     */
1011    long mLastIdleTime = SystemClock.uptimeMillis();
1012
1013    /**
1014     * Total time spent with RAM that has been added in the past since the last idle time.
1015     */
1016    long mLowRamTimeSinceLastIdle = 0;
1017
1018    /**
1019     * If RAM is currently low, when that horrible situation started.
1020     */
1021    long mLowRamStartTime = 0;
1022
1023    /**
1024     * For reporting to battery stats the current top application.
1025     */
1026    private String mCurResumedPackage = null;
1027    private int mCurResumedUid = -1;
1028
1029    /**
1030     * For reporting to battery stats the apps currently running foreground
1031     * service.  The ProcessMap is package/uid tuples; each of these contain
1032     * an array of the currently foreground processes.
1033     */
1034    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1035            = new ProcessMap<ArrayList<ProcessRecord>>();
1036
1037    /**
1038     * This is set if we had to do a delayed dexopt of an app before launching
1039     * it, to increase the ANR timeouts in that case.
1040     */
1041    boolean mDidDexOpt;
1042
1043    /**
1044     * Set if the systemServer made a call to enterSafeMode.
1045     */
1046    boolean mSafeMode;
1047
1048    String mDebugApp = null;
1049    boolean mWaitForDebugger = false;
1050    boolean mDebugTransient = false;
1051    String mOrigDebugApp = null;
1052    boolean mOrigWaitForDebugger = false;
1053    boolean mAlwaysFinishActivities = false;
1054    IActivityController mController = null;
1055    String mProfileApp = null;
1056    ProcessRecord mProfileProc = null;
1057    String mProfileFile;
1058    ParcelFileDescriptor mProfileFd;
1059    int mSamplingInterval = 0;
1060    boolean mAutoStopProfiler = false;
1061    int mProfileType = 0;
1062    String mOpenGlTraceApp = null;
1063
1064    static class ProcessChangeItem {
1065        static final int CHANGE_ACTIVITIES = 1<<0;
1066        static final int CHANGE_PROCESS_STATE = 1<<1;
1067        int changes;
1068        int uid;
1069        int pid;
1070        int processState;
1071        boolean foregroundActivities;
1072    }
1073
1074    final RemoteCallbackList<IProcessObserver> mProcessObservers
1075            = new RemoteCallbackList<IProcessObserver>();
1076    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1077
1078    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1079            = new ArrayList<ProcessChangeItem>();
1080    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1081            = new ArrayList<ProcessChangeItem>();
1082
1083    /**
1084     * Runtime CPU use collection thread.  This object's lock is used to
1085     * perform synchronization with the thread (notifying it to run).
1086     */
1087    final Thread mProcessCpuThread;
1088
1089    /**
1090     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1091     * Must acquire this object's lock when accessing it.
1092     * NOTE: this lock will be held while doing long operations (trawling
1093     * through all processes in /proc), so it should never be acquired by
1094     * any critical paths such as when holding the main activity manager lock.
1095     */
1096    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1097            MONITOR_THREAD_CPU_USAGE);
1098    final AtomicLong mLastCpuTime = new AtomicLong(0);
1099    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1100
1101    long mLastWriteTime = 0;
1102
1103    /**
1104     * Used to retain an update lock when the foreground activity is in
1105     * immersive mode.
1106     */
1107    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1108
1109    /**
1110     * Set to true after the system has finished booting.
1111     */
1112    boolean mBooted = false;
1113
1114    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1115    int mProcessLimitOverride = -1;
1116
1117    WindowManagerService mWindowManager;
1118
1119    final ActivityThread mSystemThread;
1120
1121    // Holds the current foreground user's id
1122    int mCurrentUserId = 0;
1123    // Holds the target user's id during a user switch
1124    int mTargetUserId = UserHandle.USER_NULL;
1125    // If there are multiple profiles for the current user, their ids are here
1126    // Currently only the primary user can have managed profiles
1127    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1128
1129    /**
1130     * Mapping from each known user ID to the profile group ID it is associated with.
1131     */
1132    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1133
1134    private UserManagerService mUserManager;
1135
1136    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1137        final ProcessRecord mApp;
1138        final int mPid;
1139        final IApplicationThread mAppThread;
1140
1141        AppDeathRecipient(ProcessRecord app, int pid,
1142                IApplicationThread thread) {
1143            if (localLOGV) Slog.v(
1144                TAG, "New death recipient " + this
1145                + " for thread " + thread.asBinder());
1146            mApp = app;
1147            mPid = pid;
1148            mAppThread = thread;
1149        }
1150
1151        @Override
1152        public void binderDied() {
1153            if (localLOGV) Slog.v(
1154                TAG, "Death received in " + this
1155                + " for thread " + mAppThread.asBinder());
1156            synchronized(ActivityManagerService.this) {
1157                appDiedLocked(mApp, mPid, mAppThread);
1158            }
1159        }
1160    }
1161
1162    static final int SHOW_ERROR_MSG = 1;
1163    static final int SHOW_NOT_RESPONDING_MSG = 2;
1164    static final int SHOW_FACTORY_ERROR_MSG = 3;
1165    static final int UPDATE_CONFIGURATION_MSG = 4;
1166    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1167    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1168    static final int SERVICE_TIMEOUT_MSG = 12;
1169    static final int UPDATE_TIME_ZONE = 13;
1170    static final int SHOW_UID_ERROR_MSG = 14;
1171    static final int IM_FEELING_LUCKY_MSG = 15;
1172    static final int PROC_START_TIMEOUT_MSG = 20;
1173    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1174    static final int KILL_APPLICATION_MSG = 22;
1175    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1176    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1177    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1178    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1179    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1180    static final int CLEAR_DNS_CACHE_MSG = 28;
1181    static final int UPDATE_HTTP_PROXY_MSG = 29;
1182    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1183    static final int DISPATCH_PROCESSES_CHANGED = 31;
1184    static final int DISPATCH_PROCESS_DIED = 32;
1185    static final int REPORT_MEM_USAGE_MSG = 33;
1186    static final int REPORT_USER_SWITCH_MSG = 34;
1187    static final int CONTINUE_USER_SWITCH_MSG = 35;
1188    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1189    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1190    static final int PERSIST_URI_GRANTS_MSG = 38;
1191    static final int REQUEST_ALL_PSS_MSG = 39;
1192    static final int START_PROFILES_MSG = 40;
1193    static final int UPDATE_TIME = 41;
1194    static final int SYSTEM_USER_START_MSG = 42;
1195    static final int SYSTEM_USER_CURRENT_MSG = 43;
1196    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1197    static final int FINISH_BOOTING_MSG = 45;
1198    static final int START_USER_SWITCH_MSG = 46;
1199    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1200    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1201
1202    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1203    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1204    static final int FIRST_COMPAT_MODE_MSG = 300;
1205    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1206
1207    AlertDialog mUidAlert;
1208    CompatModeDialog mCompatModeDialog;
1209    long mLastMemUsageReportTime = 0;
1210
1211    private LockToAppRequestDialog mLockToAppRequest;
1212
1213    /**
1214     * Flag whether the current user is a "monkey", i.e. whether
1215     * the UI is driven by a UI automation tool.
1216     */
1217    private boolean mUserIsMonkey;
1218
1219    /** Flag whether the device has a Recents UI */
1220    boolean mHasRecents;
1221
1222    /** The dimensions of the thumbnails in the Recents UI. */
1223    int mThumbnailWidth;
1224    int mThumbnailHeight;
1225
1226    final ServiceThread mHandlerThread;
1227    final MainHandler mHandler;
1228
1229    final class MainHandler extends Handler {
1230        public MainHandler(Looper looper) {
1231            super(looper, null, true);
1232        }
1233
1234        @Override
1235        public void handleMessage(Message msg) {
1236            switch (msg.what) {
1237            case SHOW_ERROR_MSG: {
1238                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1239                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1240                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1241                synchronized (ActivityManagerService.this) {
1242                    ProcessRecord proc = (ProcessRecord)data.get("app");
1243                    AppErrorResult res = (AppErrorResult) data.get("result");
1244                    if (proc != null && proc.crashDialog != null) {
1245                        Slog.e(TAG, "App already has crash dialog: " + proc);
1246                        if (res != null) {
1247                            res.set(0);
1248                        }
1249                        return;
1250                    }
1251                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1252                            >= Process.FIRST_APPLICATION_UID
1253                            && proc.pid != MY_PID);
1254                    for (int userId : mCurrentProfileIds) {
1255                        isBackground &= (proc.userId != userId);
1256                    }
1257                    if (isBackground && !showBackground) {
1258                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1259                        if (res != null) {
1260                            res.set(0);
1261                        }
1262                        return;
1263                    }
1264                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1265                        Dialog d = new AppErrorDialog(mContext,
1266                                ActivityManagerService.this, res, proc);
1267                        d.show();
1268                        proc.crashDialog = d;
1269                    } else {
1270                        // The device is asleep, so just pretend that the user
1271                        // saw a crash dialog and hit "force quit".
1272                        if (res != null) {
1273                            res.set(0);
1274                        }
1275                    }
1276                }
1277
1278                ensureBootCompleted();
1279            } break;
1280            case SHOW_NOT_RESPONDING_MSG: {
1281                synchronized (ActivityManagerService.this) {
1282                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1283                    ProcessRecord proc = (ProcessRecord)data.get("app");
1284                    if (proc != null && proc.anrDialog != null) {
1285                        Slog.e(TAG, "App already has anr dialog: " + proc);
1286                        return;
1287                    }
1288
1289                    Intent intent = new Intent("android.intent.action.ANR");
1290                    if (!mProcessesReady) {
1291                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1292                                | Intent.FLAG_RECEIVER_FOREGROUND);
1293                    }
1294                    broadcastIntentLocked(null, null, intent,
1295                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1296                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1297
1298                    if (mShowDialogs) {
1299                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1300                                mContext, proc, (ActivityRecord)data.get("activity"),
1301                                msg.arg1 != 0);
1302                        d.show();
1303                        proc.anrDialog = d;
1304                    } else {
1305                        // Just kill the app if there is no dialog to be shown.
1306                        killAppAtUsersRequest(proc, null);
1307                    }
1308                }
1309
1310                ensureBootCompleted();
1311            } break;
1312            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1313                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1314                synchronized (ActivityManagerService.this) {
1315                    ProcessRecord proc = (ProcessRecord) data.get("app");
1316                    if (proc == null) {
1317                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1318                        break;
1319                    }
1320                    if (proc.crashDialog != null) {
1321                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1322                        return;
1323                    }
1324                    AppErrorResult res = (AppErrorResult) data.get("result");
1325                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1326                        Dialog d = new StrictModeViolationDialog(mContext,
1327                                ActivityManagerService.this, res, proc);
1328                        d.show();
1329                        proc.crashDialog = d;
1330                    } else {
1331                        // The device is asleep, so just pretend that the user
1332                        // saw a crash dialog and hit "force quit".
1333                        res.set(0);
1334                    }
1335                }
1336                ensureBootCompleted();
1337            } break;
1338            case SHOW_FACTORY_ERROR_MSG: {
1339                Dialog d = new FactoryErrorDialog(
1340                    mContext, msg.getData().getCharSequence("msg"));
1341                d.show();
1342                ensureBootCompleted();
1343            } break;
1344            case UPDATE_CONFIGURATION_MSG: {
1345                final ContentResolver resolver = mContext.getContentResolver();
1346                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1347            } break;
1348            case GC_BACKGROUND_PROCESSES_MSG: {
1349                synchronized (ActivityManagerService.this) {
1350                    performAppGcsIfAppropriateLocked();
1351                }
1352            } break;
1353            case WAIT_FOR_DEBUGGER_MSG: {
1354                synchronized (ActivityManagerService.this) {
1355                    ProcessRecord app = (ProcessRecord)msg.obj;
1356                    if (msg.arg1 != 0) {
1357                        if (!app.waitedForDebugger) {
1358                            Dialog d = new AppWaitingForDebuggerDialog(
1359                                    ActivityManagerService.this,
1360                                    mContext, app);
1361                            app.waitDialog = d;
1362                            app.waitedForDebugger = true;
1363                            d.show();
1364                        }
1365                    } else {
1366                        if (app.waitDialog != null) {
1367                            app.waitDialog.dismiss();
1368                            app.waitDialog = null;
1369                        }
1370                    }
1371                }
1372            } break;
1373            case SERVICE_TIMEOUT_MSG: {
1374                if (mDidDexOpt) {
1375                    mDidDexOpt = false;
1376                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1377                    nmsg.obj = msg.obj;
1378                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1379                    return;
1380                }
1381                mServices.serviceTimeout((ProcessRecord)msg.obj);
1382            } break;
1383            case UPDATE_TIME_ZONE: {
1384                synchronized (ActivityManagerService.this) {
1385                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1386                        ProcessRecord r = mLruProcesses.get(i);
1387                        if (r.thread != null) {
1388                            try {
1389                                r.thread.updateTimeZone();
1390                            } catch (RemoteException ex) {
1391                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1392                            }
1393                        }
1394                    }
1395                }
1396            } break;
1397            case CLEAR_DNS_CACHE_MSG: {
1398                synchronized (ActivityManagerService.this) {
1399                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1400                        ProcessRecord r = mLruProcesses.get(i);
1401                        if (r.thread != null) {
1402                            try {
1403                                r.thread.clearDnsCache();
1404                            } catch (RemoteException ex) {
1405                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1406                            }
1407                        }
1408                    }
1409                }
1410            } break;
1411            case UPDATE_HTTP_PROXY_MSG: {
1412                ProxyInfo proxy = (ProxyInfo)msg.obj;
1413                String host = "";
1414                String port = "";
1415                String exclList = "";
1416                Uri pacFileUrl = Uri.EMPTY;
1417                if (proxy != null) {
1418                    host = proxy.getHost();
1419                    port = Integer.toString(proxy.getPort());
1420                    exclList = proxy.getExclusionListAsString();
1421                    pacFileUrl = proxy.getPacFileUrl();
1422                }
1423                synchronized (ActivityManagerService.this) {
1424                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1425                        ProcessRecord r = mLruProcesses.get(i);
1426                        if (r.thread != null) {
1427                            try {
1428                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1429                            } catch (RemoteException ex) {
1430                                Slog.w(TAG, "Failed to update http proxy for: " +
1431                                        r.info.processName);
1432                            }
1433                        }
1434                    }
1435                }
1436            } break;
1437            case SHOW_UID_ERROR_MSG: {
1438                String title = "System UIDs Inconsistent";
1439                String text = "UIDs on the system are inconsistent, you need to wipe your"
1440                        + " data partition or your device will be unstable.";
1441                Log.e(TAG, title + ": " + text);
1442                if (mShowDialogs) {
1443                    // XXX This is a temporary dialog, no need to localize.
1444                    AlertDialog d = new BaseErrorDialog(mContext);
1445                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1446                    d.setCancelable(false);
1447                    d.setTitle(title);
1448                    d.setMessage(text);
1449                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1450                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1451                    mUidAlert = d;
1452                    d.show();
1453                }
1454            } break;
1455            case IM_FEELING_LUCKY_MSG: {
1456                if (mUidAlert != null) {
1457                    mUidAlert.dismiss();
1458                    mUidAlert = null;
1459                }
1460            } break;
1461            case PROC_START_TIMEOUT_MSG: {
1462                if (mDidDexOpt) {
1463                    mDidDexOpt = false;
1464                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1465                    nmsg.obj = msg.obj;
1466                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1467                    return;
1468                }
1469                ProcessRecord app = (ProcessRecord)msg.obj;
1470                synchronized (ActivityManagerService.this) {
1471                    processStartTimedOutLocked(app);
1472                }
1473            } break;
1474            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1475                synchronized (ActivityManagerService.this) {
1476                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1477                }
1478            } break;
1479            case KILL_APPLICATION_MSG: {
1480                synchronized (ActivityManagerService.this) {
1481                    int appid = msg.arg1;
1482                    boolean restart = (msg.arg2 == 1);
1483                    Bundle bundle = (Bundle)msg.obj;
1484                    String pkg = bundle.getString("pkg");
1485                    String reason = bundle.getString("reason");
1486                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1487                            false, UserHandle.USER_ALL, reason);
1488                }
1489            } break;
1490            case FINALIZE_PENDING_INTENT_MSG: {
1491                ((PendingIntentRecord)msg.obj).completeFinalize();
1492            } break;
1493            case POST_HEAVY_NOTIFICATION_MSG: {
1494                INotificationManager inm = NotificationManager.getService();
1495                if (inm == null) {
1496                    return;
1497                }
1498
1499                ActivityRecord root = (ActivityRecord)msg.obj;
1500                ProcessRecord process = root.app;
1501                if (process == null) {
1502                    return;
1503                }
1504
1505                try {
1506                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1507                    String text = mContext.getString(R.string.heavy_weight_notification,
1508                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1509                    Notification notification = new Notification();
1510                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1511                    notification.when = 0;
1512                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1513                    notification.tickerText = text;
1514                    notification.defaults = 0; // please be quiet
1515                    notification.sound = null;
1516                    notification.vibrate = null;
1517                    notification.color = mContext.getResources().getColor(
1518                            com.android.internal.R.color.system_notification_accent_color);
1519                    notification.setLatestEventInfo(context, text,
1520                            mContext.getText(R.string.heavy_weight_notification_detail),
1521                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1522                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1523                                    new UserHandle(root.userId)));
1524
1525                    try {
1526                        int[] outId = new int[1];
1527                        inm.enqueueNotificationWithTag("android", "android", null,
1528                                R.string.heavy_weight_notification,
1529                                notification, outId, root.userId);
1530                    } catch (RuntimeException e) {
1531                        Slog.w(ActivityManagerService.TAG,
1532                                "Error showing notification for heavy-weight app", e);
1533                    } catch (RemoteException e) {
1534                    }
1535                } catch (NameNotFoundException e) {
1536                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1537                }
1538            } break;
1539            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1540                INotificationManager inm = NotificationManager.getService();
1541                if (inm == null) {
1542                    return;
1543                }
1544                try {
1545                    inm.cancelNotificationWithTag("android", null,
1546                            R.string.heavy_weight_notification,  msg.arg1);
1547                } catch (RuntimeException e) {
1548                    Slog.w(ActivityManagerService.TAG,
1549                            "Error canceling notification for service", e);
1550                } catch (RemoteException e) {
1551                }
1552            } break;
1553            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1554                synchronized (ActivityManagerService.this) {
1555                    checkExcessivePowerUsageLocked(true);
1556                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1557                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1558                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1559                }
1560            } break;
1561            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1562                synchronized (ActivityManagerService.this) {
1563                    ActivityRecord ar = (ActivityRecord)msg.obj;
1564                    if (mCompatModeDialog != null) {
1565                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1566                                ar.info.applicationInfo.packageName)) {
1567                            return;
1568                        }
1569                        mCompatModeDialog.dismiss();
1570                        mCompatModeDialog = null;
1571                    }
1572                    if (ar != null && false) {
1573                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1574                                ar.packageName)) {
1575                            int mode = mCompatModePackages.computeCompatModeLocked(
1576                                    ar.info.applicationInfo);
1577                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1578                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1579                                mCompatModeDialog = new CompatModeDialog(
1580                                        ActivityManagerService.this, mContext,
1581                                        ar.info.applicationInfo);
1582                                mCompatModeDialog.show();
1583                            }
1584                        }
1585                    }
1586                }
1587                break;
1588            }
1589            case DISPATCH_PROCESSES_CHANGED: {
1590                dispatchProcessesChanged();
1591                break;
1592            }
1593            case DISPATCH_PROCESS_DIED: {
1594                final int pid = msg.arg1;
1595                final int uid = msg.arg2;
1596                dispatchProcessDied(pid, uid);
1597                break;
1598            }
1599            case REPORT_MEM_USAGE_MSG: {
1600                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1601                Thread thread = new Thread() {
1602                    @Override public void run() {
1603                        final SparseArray<ProcessMemInfo> infoMap
1604                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1605                        for (int i=0, N=memInfos.size(); i<N; i++) {
1606                            ProcessMemInfo mi = memInfos.get(i);
1607                            infoMap.put(mi.pid, mi);
1608                        }
1609                        updateCpuStatsNow();
1610                        synchronized (mProcessCpuTracker) {
1611                            final int N = mProcessCpuTracker.countStats();
1612                            for (int i=0; i<N; i++) {
1613                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1614                                if (st.vsize > 0) {
1615                                    long pss = Debug.getPss(st.pid, null);
1616                                    if (pss > 0) {
1617                                        if (infoMap.indexOfKey(st.pid) < 0) {
1618                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1619                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1620                                            mi.pss = pss;
1621                                            memInfos.add(mi);
1622                                        }
1623                                    }
1624                                }
1625                            }
1626                        }
1627
1628                        long totalPss = 0;
1629                        for (int i=0, N=memInfos.size(); i<N; i++) {
1630                            ProcessMemInfo mi = memInfos.get(i);
1631                            if (mi.pss == 0) {
1632                                mi.pss = Debug.getPss(mi.pid, null);
1633                            }
1634                            totalPss += mi.pss;
1635                        }
1636                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1637                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1638                                if (lhs.oomAdj != rhs.oomAdj) {
1639                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1640                                }
1641                                if (lhs.pss != rhs.pss) {
1642                                    return lhs.pss < rhs.pss ? 1 : -1;
1643                                }
1644                                return 0;
1645                            }
1646                        });
1647
1648                        StringBuilder tag = new StringBuilder(128);
1649                        StringBuilder stack = new StringBuilder(128);
1650                        tag.append("Low on memory -- ");
1651                        appendMemBucket(tag, totalPss, "total", false);
1652                        appendMemBucket(stack, totalPss, "total", true);
1653
1654                        StringBuilder logBuilder = new StringBuilder(1024);
1655                        logBuilder.append("Low on memory:\n");
1656
1657                        boolean firstLine = true;
1658                        int lastOomAdj = Integer.MIN_VALUE;
1659                        for (int i=0, N=memInfos.size(); i<N; i++) {
1660                            ProcessMemInfo mi = memInfos.get(i);
1661
1662                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1663                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1664                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1665                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1666                                if (lastOomAdj != mi.oomAdj) {
1667                                    lastOomAdj = mi.oomAdj;
1668                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1669                                        tag.append(" / ");
1670                                    }
1671                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1672                                        if (firstLine) {
1673                                            stack.append(":");
1674                                            firstLine = false;
1675                                        }
1676                                        stack.append("\n\t at ");
1677                                    } else {
1678                                        stack.append("$");
1679                                    }
1680                                } else {
1681                                    tag.append(" ");
1682                                    stack.append("$");
1683                                }
1684                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1685                                    appendMemBucket(tag, mi.pss, mi.name, false);
1686                                }
1687                                appendMemBucket(stack, mi.pss, mi.name, true);
1688                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1689                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1690                                    stack.append("(");
1691                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1692                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1693                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1694                                            stack.append(":");
1695                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1696                                        }
1697                                    }
1698                                    stack.append(")");
1699                                }
1700                            }
1701
1702                            logBuilder.append("  ");
1703                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1704                            logBuilder.append(' ');
1705                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1706                            logBuilder.append(' ');
1707                            ProcessList.appendRamKb(logBuilder, mi.pss);
1708                            logBuilder.append(" kB: ");
1709                            logBuilder.append(mi.name);
1710                            logBuilder.append(" (");
1711                            logBuilder.append(mi.pid);
1712                            logBuilder.append(") ");
1713                            logBuilder.append(mi.adjType);
1714                            logBuilder.append('\n');
1715                            if (mi.adjReason != null) {
1716                                logBuilder.append("                      ");
1717                                logBuilder.append(mi.adjReason);
1718                                logBuilder.append('\n');
1719                            }
1720                        }
1721
1722                        logBuilder.append("           ");
1723                        ProcessList.appendRamKb(logBuilder, totalPss);
1724                        logBuilder.append(" kB: TOTAL\n");
1725
1726                        long[] infos = new long[Debug.MEMINFO_COUNT];
1727                        Debug.getMemInfo(infos);
1728                        logBuilder.append("  MemInfo: ");
1729                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1730                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1732                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1733                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1734                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1735                            logBuilder.append("  ZRAM: ");
1736                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1737                            logBuilder.append(" kB RAM, ");
1738                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1739                            logBuilder.append(" kB swap total, ");
1740                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1741                            logBuilder.append(" kB swap free\n");
1742                        }
1743                        Slog.i(TAG, logBuilder.toString());
1744
1745                        StringBuilder dropBuilder = new StringBuilder(1024);
1746                        /*
1747                        StringWriter oomSw = new StringWriter();
1748                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1749                        StringWriter catSw = new StringWriter();
1750                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1751                        String[] emptyArgs = new String[] { };
1752                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1753                        oomPw.flush();
1754                        String oomString = oomSw.toString();
1755                        */
1756                        dropBuilder.append(stack);
1757                        dropBuilder.append('\n');
1758                        dropBuilder.append('\n');
1759                        dropBuilder.append(logBuilder);
1760                        dropBuilder.append('\n');
1761                        /*
1762                        dropBuilder.append(oomString);
1763                        dropBuilder.append('\n');
1764                        */
1765                        StringWriter catSw = new StringWriter();
1766                        synchronized (ActivityManagerService.this) {
1767                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1768                            String[] emptyArgs = new String[] { };
1769                            catPw.println();
1770                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1771                            catPw.println();
1772                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1773                                    false, false, null);
1774                            catPw.println();
1775                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1776                            catPw.flush();
1777                        }
1778                        dropBuilder.append(catSw.toString());
1779                        addErrorToDropBox("lowmem", null, "system_server", null,
1780                                null, tag.toString(), dropBuilder.toString(), null, null);
1781                        //Slog.i(TAG, "Sent to dropbox:");
1782                        //Slog.i(TAG, dropBuilder.toString());
1783                        synchronized (ActivityManagerService.this) {
1784                            long now = SystemClock.uptimeMillis();
1785                            if (mLastMemUsageReportTime < now) {
1786                                mLastMemUsageReportTime = now;
1787                            }
1788                        }
1789                    }
1790                };
1791                thread.start();
1792                break;
1793            }
1794            case START_USER_SWITCH_MSG: {
1795                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1796                break;
1797            }
1798            case REPORT_USER_SWITCH_MSG: {
1799                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1800                break;
1801            }
1802            case CONTINUE_USER_SWITCH_MSG: {
1803                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1804                break;
1805            }
1806            case USER_SWITCH_TIMEOUT_MSG: {
1807                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1808                break;
1809            }
1810            case IMMERSIVE_MODE_LOCK_MSG: {
1811                final boolean nextState = (msg.arg1 != 0);
1812                if (mUpdateLock.isHeld() != nextState) {
1813                    if (DEBUG_IMMERSIVE) {
1814                        final ActivityRecord r = (ActivityRecord) msg.obj;
1815                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1816                    }
1817                    if (nextState) {
1818                        mUpdateLock.acquire();
1819                    } else {
1820                        mUpdateLock.release();
1821                    }
1822                }
1823                break;
1824            }
1825            case PERSIST_URI_GRANTS_MSG: {
1826                writeGrantedUriPermissions();
1827                break;
1828            }
1829            case REQUEST_ALL_PSS_MSG: {
1830                synchronized (ActivityManagerService.this) {
1831                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1832                }
1833                break;
1834            }
1835            case START_PROFILES_MSG: {
1836                synchronized (ActivityManagerService.this) {
1837                    startProfilesLocked();
1838                }
1839                break;
1840            }
1841            case UPDATE_TIME: {
1842                synchronized (ActivityManagerService.this) {
1843                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1844                        ProcessRecord r = mLruProcesses.get(i);
1845                        if (r.thread != null) {
1846                            try {
1847                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1848                            } catch (RemoteException ex) {
1849                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1850                            }
1851                        }
1852                    }
1853                }
1854                break;
1855            }
1856            case SYSTEM_USER_START_MSG: {
1857                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1858                        Integer.toString(msg.arg1), msg.arg1);
1859                mSystemServiceManager.startUser(msg.arg1);
1860                break;
1861            }
1862            case SYSTEM_USER_CURRENT_MSG: {
1863                mBatteryStatsService.noteEvent(
1864                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1865                        Integer.toString(msg.arg2), msg.arg2);
1866                mBatteryStatsService.noteEvent(
1867                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1868                        Integer.toString(msg.arg1), msg.arg1);
1869                mSystemServiceManager.switchUser(msg.arg1);
1870                mLockToAppRequest.clearPrompt();
1871                break;
1872            }
1873            case ENTER_ANIMATION_COMPLETE_MSG: {
1874                synchronized (ActivityManagerService.this) {
1875                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1876                    if (r != null && r.app != null && r.app.thread != null) {
1877                        try {
1878                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1879                        } catch (RemoteException e) {
1880                        }
1881                    }
1882                }
1883                break;
1884            }
1885            case FINISH_BOOTING_MSG: {
1886                if (msg.arg1 != 0) {
1887                    finishBooting();
1888                }
1889                if (msg.arg2 != 0) {
1890                    enableScreenAfterBoot();
1891                }
1892                break;
1893            }
1894            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1895                try {
1896                    Locale l = (Locale) msg.obj;
1897                    IBinder service = ServiceManager.getService("mount");
1898                    IMountService mountService = IMountService.Stub.asInterface(service);
1899                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1900                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1901                } catch (RemoteException e) {
1902                    Log.e(TAG, "Error storing locale for decryption UI", e);
1903                }
1904                break;
1905            }
1906            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1907                final int uid = msg.arg1;
1908                final byte[] firstPacket = (byte[]) msg.obj;
1909
1910                synchronized (mPidsSelfLocked) {
1911                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1912                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1913                        if (p.uid == uid) {
1914                            try {
1915                                p.thread.notifyCleartextNetwork(firstPacket);
1916                            } catch (RemoteException ignored) {
1917                            }
1918                        }
1919                    }
1920                }
1921                break;
1922            }
1923            }
1924        }
1925    };
1926
1927    static final int COLLECT_PSS_BG_MSG = 1;
1928
1929    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1930        @Override
1931        public void handleMessage(Message msg) {
1932            switch (msg.what) {
1933            case COLLECT_PSS_BG_MSG: {
1934                long start = SystemClock.uptimeMillis();
1935                MemInfoReader memInfo = null;
1936                synchronized (ActivityManagerService.this) {
1937                    if (mFullPssPending) {
1938                        mFullPssPending = false;
1939                        memInfo = new MemInfoReader();
1940                    }
1941                }
1942                if (memInfo != null) {
1943                    updateCpuStatsNow();
1944                    long nativeTotalPss = 0;
1945                    synchronized (mProcessCpuTracker) {
1946                        final int N = mProcessCpuTracker.countStats();
1947                        for (int j=0; j<N; j++) {
1948                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1949                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1950                                // This is definitely an application process; skip it.
1951                                continue;
1952                            }
1953                            synchronized (mPidsSelfLocked) {
1954                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1955                                    // This is one of our own processes; skip it.
1956                                    continue;
1957                                }
1958                            }
1959                            nativeTotalPss += Debug.getPss(st.pid, null);
1960                        }
1961                    }
1962                    memInfo.readMemInfo();
1963                    synchronized (ActivityManagerService.this) {
1964                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1965                                + (SystemClock.uptimeMillis()-start) + "ms");
1966                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1967                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1968                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1969                                        +memInfo.getSlabSizeKb(),
1970                                nativeTotalPss);
1971                    }
1972                }
1973
1974                int i=0, num=0;
1975                long[] tmp = new long[1];
1976                do {
1977                    ProcessRecord proc;
1978                    int procState;
1979                    int pid;
1980                    synchronized (ActivityManagerService.this) {
1981                        if (i >= mPendingPssProcesses.size()) {
1982                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1983                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1984                            mPendingPssProcesses.clear();
1985                            return;
1986                        }
1987                        proc = mPendingPssProcesses.get(i);
1988                        procState = proc.pssProcState;
1989                        if (proc.thread != null && procState == proc.setProcState) {
1990                            pid = proc.pid;
1991                        } else {
1992                            proc = null;
1993                            pid = 0;
1994                        }
1995                        i++;
1996                    }
1997                    if (proc != null) {
1998                        long pss = Debug.getPss(pid, tmp);
1999                        synchronized (ActivityManagerService.this) {
2000                            if (proc.thread != null && proc.setProcState == procState
2001                                    && proc.pid == pid) {
2002                                num++;
2003                                proc.lastPssTime = SystemClock.uptimeMillis();
2004                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
2005                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
2006                                        + ": " + pss + " lastPss=" + proc.lastPss
2007                                        + " state=" + ProcessList.makeProcStateString(procState));
2008                                if (proc.initialIdlePss == 0) {
2009                                    proc.initialIdlePss = pss;
2010                                }
2011                                proc.lastPss = pss;
2012                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2013                                    proc.lastCachedPss = pss;
2014                                }
2015                            }
2016                        }
2017                    }
2018                } while (true);
2019            }
2020            }
2021        }
2022    };
2023
2024    /**
2025     * Monitor for package changes and update our internal state.
2026     */
2027    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2028        @Override
2029        public void onPackageRemoved(String packageName, int uid) {
2030            // Remove all tasks with activities in the specified package from the list of recent tasks
2031            final int eventUserId = getChangingUserId();
2032            synchronized (ActivityManagerService.this) {
2033                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2034                    TaskRecord tr = mRecentTasks.get(i);
2035                    if (tr.userId != eventUserId) continue;
2036
2037                    ComponentName cn = tr.intent.getComponent();
2038                    if (cn != null && cn.getPackageName().equals(packageName)) {
2039                        // If the package name matches, remove the task and kill the process
2040                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2041                    }
2042                }
2043            }
2044        }
2045
2046        @Override
2047        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2048            onPackageModified(packageName);
2049            return true;
2050        }
2051
2052        @Override
2053        public void onPackageModified(String packageName) {
2054            final int eventUserId = getChangingUserId();
2055            final IPackageManager pm = AppGlobals.getPackageManager();
2056            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2057                    new ArrayList<Pair<Intent, Integer>>();
2058            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2059            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2060            // Copy the list of recent tasks so that we don't hold onto the lock on
2061            // ActivityManagerService for long periods while checking if components exist.
2062            synchronized (ActivityManagerService.this) {
2063                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2064                    TaskRecord tr = mRecentTasks.get(i);
2065                    if (tr.userId != eventUserId) continue;
2066
2067                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2068                }
2069            }
2070            // Check the recent tasks and filter out all tasks with components that no longer exist.
2071            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2072                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2073                ComponentName cn = p.first.getComponent();
2074                if (cn != null && cn.getPackageName().equals(packageName)) {
2075                    if (componentsKnownToExist.contains(cn)) {
2076                        // If we know that the component still exists in the package, then skip
2077                        continue;
2078                    }
2079                    try {
2080                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2081                        if (info != null) {
2082                            componentsKnownToExist.add(cn);
2083                        } else {
2084                            tasksToRemove.add(p.second);
2085                        }
2086                    } catch (RemoteException e) {
2087                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2088                    }
2089                }
2090            }
2091            // Prune all the tasks with removed components from the list of recent tasks
2092            synchronized (ActivityManagerService.this) {
2093                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2094                    // Remove the task but don't kill the process (since other components in that
2095                    // package may still be running and in the background)
2096                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2097                }
2098            }
2099        }
2100
2101        @Override
2102        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2103            // Force stop the specified packages
2104            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2105            if (packages != null) {
2106                for (String pkg : packages) {
2107                    synchronized (ActivityManagerService.this) {
2108                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2109                                userId, "finished booting")) {
2110                            return true;
2111                        }
2112                    }
2113                }
2114            }
2115            return false;
2116        }
2117    };
2118
2119    public void setSystemProcess() {
2120        try {
2121            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2122            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2123            ServiceManager.addService("meminfo", new MemBinder(this));
2124            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2125            ServiceManager.addService("dbinfo", new DbBinder(this));
2126            if (MONITOR_CPU_USAGE) {
2127                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2128            }
2129            ServiceManager.addService("permission", new PermissionController(this));
2130
2131            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2132                    "android", STOCK_PM_FLAGS);
2133            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2134
2135            synchronized (this) {
2136                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2137                app.persistent = true;
2138                app.pid = MY_PID;
2139                app.maxAdj = ProcessList.SYSTEM_ADJ;
2140                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2141                mProcessNames.put(app.processName, app.uid, app);
2142                synchronized (mPidsSelfLocked) {
2143                    mPidsSelfLocked.put(app.pid, app);
2144                }
2145                updateLruProcessLocked(app, false, null);
2146                updateOomAdjLocked();
2147            }
2148        } catch (PackageManager.NameNotFoundException e) {
2149            throw new RuntimeException(
2150                    "Unable to find android system package", e);
2151        }
2152    }
2153
2154    public void setWindowManager(WindowManagerService wm) {
2155        mWindowManager = wm;
2156        mStackSupervisor.setWindowManager(wm);
2157    }
2158
2159    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2160        mUsageStatsService = usageStatsManager;
2161    }
2162
2163    public void startObservingNativeCrashes() {
2164        final NativeCrashListener ncl = new NativeCrashListener(this);
2165        ncl.start();
2166    }
2167
2168    public IAppOpsService getAppOpsService() {
2169        return mAppOpsService;
2170    }
2171
2172    static class MemBinder extends Binder {
2173        ActivityManagerService mActivityManagerService;
2174        MemBinder(ActivityManagerService activityManagerService) {
2175            mActivityManagerService = activityManagerService;
2176        }
2177
2178        @Override
2179        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2180            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2181                    != PackageManager.PERMISSION_GRANTED) {
2182                pw.println("Permission Denial: can't dump meminfo from from pid="
2183                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2184                        + " without permission " + android.Manifest.permission.DUMP);
2185                return;
2186            }
2187
2188            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2189        }
2190    }
2191
2192    static class GraphicsBinder extends Binder {
2193        ActivityManagerService mActivityManagerService;
2194        GraphicsBinder(ActivityManagerService activityManagerService) {
2195            mActivityManagerService = activityManagerService;
2196        }
2197
2198        @Override
2199        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2200            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2201                    != PackageManager.PERMISSION_GRANTED) {
2202                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2203                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2204                        + " without permission " + android.Manifest.permission.DUMP);
2205                return;
2206            }
2207
2208            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2209        }
2210    }
2211
2212    static class DbBinder extends Binder {
2213        ActivityManagerService mActivityManagerService;
2214        DbBinder(ActivityManagerService activityManagerService) {
2215            mActivityManagerService = activityManagerService;
2216        }
2217
2218        @Override
2219        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2220            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2221                    != PackageManager.PERMISSION_GRANTED) {
2222                pw.println("Permission Denial: can't dump dbinfo from from pid="
2223                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2224                        + " without permission " + android.Manifest.permission.DUMP);
2225                return;
2226            }
2227
2228            mActivityManagerService.dumpDbInfo(fd, pw, args);
2229        }
2230    }
2231
2232    static class CpuBinder extends Binder {
2233        ActivityManagerService mActivityManagerService;
2234        CpuBinder(ActivityManagerService activityManagerService) {
2235            mActivityManagerService = activityManagerService;
2236        }
2237
2238        @Override
2239        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2240            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2241                    != PackageManager.PERMISSION_GRANTED) {
2242                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2243                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2244                        + " without permission " + android.Manifest.permission.DUMP);
2245                return;
2246            }
2247
2248            synchronized (mActivityManagerService.mProcessCpuTracker) {
2249                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2250                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2251                        SystemClock.uptimeMillis()));
2252            }
2253        }
2254    }
2255
2256    public static final class Lifecycle extends SystemService {
2257        private final ActivityManagerService mService;
2258
2259        public Lifecycle(Context context) {
2260            super(context);
2261            mService = new ActivityManagerService(context);
2262        }
2263
2264        @Override
2265        public void onStart() {
2266            mService.start();
2267        }
2268
2269        public ActivityManagerService getService() {
2270            return mService;
2271        }
2272    }
2273
2274    // Note: This method is invoked on the main thread but may need to attach various
2275    // handlers to other threads.  So take care to be explicit about the looper.
2276    public ActivityManagerService(Context systemContext) {
2277        mContext = systemContext;
2278        mFactoryTest = FactoryTest.getMode();
2279        mSystemThread = ActivityThread.currentActivityThread();
2280
2281        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2282
2283        mHandlerThread = new ServiceThread(TAG,
2284                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2285        mHandlerThread.start();
2286        mHandler = new MainHandler(mHandlerThread.getLooper());
2287
2288        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2289                "foreground", BROADCAST_FG_TIMEOUT, false);
2290        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2291                "background", BROADCAST_BG_TIMEOUT, true);
2292        mBroadcastQueues[0] = mFgBroadcastQueue;
2293        mBroadcastQueues[1] = mBgBroadcastQueue;
2294
2295        mServices = new ActiveServices(this);
2296        mProviderMap = new ProviderMap(this);
2297
2298        // TODO: Move creation of battery stats service outside of activity manager service.
2299        File dataDir = Environment.getDataDirectory();
2300        File systemDir = new File(dataDir, "system");
2301        systemDir.mkdirs();
2302        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2303        mBatteryStatsService.getActiveStatistics().readLocked();
2304        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2305        mOnBattery = DEBUG_POWER ? true
2306                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2307        mBatteryStatsService.getActiveStatistics().setCallback(this);
2308
2309        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2310
2311        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2312
2313        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2314
2315        // User 0 is the first and only user that runs at boot.
2316        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2317        mUserLru.add(Integer.valueOf(0));
2318        updateStartedUserArrayLocked();
2319
2320        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2321            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2322
2323        mConfiguration.setToDefaults();
2324        mConfiguration.setLocale(Locale.getDefault());
2325
2326        mConfigurationSeq = mConfiguration.seq = 1;
2327        mProcessCpuTracker.init();
2328
2329        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2330        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2331        mStackSupervisor = new ActivityStackSupervisor(this);
2332        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2333
2334        mProcessCpuThread = new Thread("CpuTracker") {
2335            @Override
2336            public void run() {
2337                while (true) {
2338                    try {
2339                        try {
2340                            synchronized(this) {
2341                                final long now = SystemClock.uptimeMillis();
2342                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2343                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2344                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2345                                //        + ", write delay=" + nextWriteDelay);
2346                                if (nextWriteDelay < nextCpuDelay) {
2347                                    nextCpuDelay = nextWriteDelay;
2348                                }
2349                                if (nextCpuDelay > 0) {
2350                                    mProcessCpuMutexFree.set(true);
2351                                    this.wait(nextCpuDelay);
2352                                }
2353                            }
2354                        } catch (InterruptedException e) {
2355                        }
2356                        updateCpuStatsNow();
2357                    } catch (Exception e) {
2358                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2359                    }
2360                }
2361            }
2362        };
2363
2364        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2365
2366        Watchdog.getInstance().addMonitor(this);
2367        Watchdog.getInstance().addThread(mHandler);
2368    }
2369
2370    public void setSystemServiceManager(SystemServiceManager mgr) {
2371        mSystemServiceManager = mgr;
2372    }
2373
2374    public void setInstaller(Installer installer) {
2375        mInstaller = installer;
2376    }
2377
2378    private void start() {
2379        Process.removeAllProcessGroups();
2380        mProcessCpuThread.start();
2381
2382        mBatteryStatsService.publish(mContext);
2383        mAppOpsService.publish(mContext);
2384        Slog.d("AppOps", "AppOpsService published");
2385        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2386    }
2387
2388    public void initPowerManagement() {
2389        mStackSupervisor.initPowerManagement();
2390        mBatteryStatsService.initPowerManagement();
2391    }
2392
2393    @Override
2394    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2395            throws RemoteException {
2396        if (code == SYSPROPS_TRANSACTION) {
2397            // We need to tell all apps about the system property change.
2398            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2399            synchronized(this) {
2400                final int NP = mProcessNames.getMap().size();
2401                for (int ip=0; ip<NP; ip++) {
2402                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2403                    final int NA = apps.size();
2404                    for (int ia=0; ia<NA; ia++) {
2405                        ProcessRecord app = apps.valueAt(ia);
2406                        if (app.thread != null) {
2407                            procs.add(app.thread.asBinder());
2408                        }
2409                    }
2410                }
2411            }
2412
2413            int N = procs.size();
2414            for (int i=0; i<N; i++) {
2415                Parcel data2 = Parcel.obtain();
2416                try {
2417                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2418                } catch (RemoteException e) {
2419                }
2420                data2.recycle();
2421            }
2422        }
2423        try {
2424            return super.onTransact(code, data, reply, flags);
2425        } catch (RuntimeException e) {
2426            // The activity manager only throws security exceptions, so let's
2427            // log all others.
2428            if (!(e instanceof SecurityException)) {
2429                Slog.wtf(TAG, "Activity Manager Crash", e);
2430            }
2431            throw e;
2432        }
2433    }
2434
2435    void updateCpuStats() {
2436        final long now = SystemClock.uptimeMillis();
2437        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2438            return;
2439        }
2440        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2441            synchronized (mProcessCpuThread) {
2442                mProcessCpuThread.notify();
2443            }
2444        }
2445    }
2446
2447    void updateCpuStatsNow() {
2448        synchronized (mProcessCpuTracker) {
2449            mProcessCpuMutexFree.set(false);
2450            final long now = SystemClock.uptimeMillis();
2451            boolean haveNewCpuStats = false;
2452
2453            if (MONITOR_CPU_USAGE &&
2454                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2455                mLastCpuTime.set(now);
2456                haveNewCpuStats = true;
2457                mProcessCpuTracker.update();
2458                //Slog.i(TAG, mProcessCpu.printCurrentState());
2459                //Slog.i(TAG, "Total CPU usage: "
2460                //        + mProcessCpu.getTotalCpuPercent() + "%");
2461
2462                // Slog the cpu usage if the property is set.
2463                if ("true".equals(SystemProperties.get("events.cpu"))) {
2464                    int user = mProcessCpuTracker.getLastUserTime();
2465                    int system = mProcessCpuTracker.getLastSystemTime();
2466                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2467                    int irq = mProcessCpuTracker.getLastIrqTime();
2468                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2469                    int idle = mProcessCpuTracker.getLastIdleTime();
2470
2471                    int total = user + system + iowait + irq + softIrq + idle;
2472                    if (total == 0) total = 1;
2473
2474                    EventLog.writeEvent(EventLogTags.CPU,
2475                            ((user+system+iowait+irq+softIrq) * 100) / total,
2476                            (user * 100) / total,
2477                            (system * 100) / total,
2478                            (iowait * 100) / total,
2479                            (irq * 100) / total,
2480                            (softIrq * 100) / total);
2481                }
2482            }
2483
2484            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2485            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2486            synchronized(bstats) {
2487                synchronized(mPidsSelfLocked) {
2488                    if (haveNewCpuStats) {
2489                        if (mOnBattery) {
2490                            int perc = bstats.startAddingCpuLocked();
2491                            int totalUTime = 0;
2492                            int totalSTime = 0;
2493                            final int N = mProcessCpuTracker.countStats();
2494                            for (int i=0; i<N; i++) {
2495                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2496                                if (!st.working) {
2497                                    continue;
2498                                }
2499                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2500                                int otherUTime = (st.rel_utime*perc)/100;
2501                                int otherSTime = (st.rel_stime*perc)/100;
2502                                totalUTime += otherUTime;
2503                                totalSTime += otherSTime;
2504                                if (pr != null) {
2505                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2506                                    if (ps == null || !ps.isActive()) {
2507                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2508                                                pr.info.uid, pr.processName);
2509                                    }
2510                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2511                                            st.rel_stime-otherSTime);
2512                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2513                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2514                                } else {
2515                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2516                                    if (ps == null || !ps.isActive()) {
2517                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2518                                                bstats.mapUid(st.uid), st.name);
2519                                    }
2520                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2521                                            st.rel_stime-otherSTime);
2522                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2523                                }
2524                            }
2525                            bstats.finishAddingCpuLocked(perc, totalUTime,
2526                                    totalSTime, cpuSpeedTimes);
2527                        }
2528                    }
2529                }
2530
2531                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2532                    mLastWriteTime = now;
2533                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2534                }
2535            }
2536        }
2537    }
2538
2539    @Override
2540    public void batteryNeedsCpuUpdate() {
2541        updateCpuStatsNow();
2542    }
2543
2544    @Override
2545    public void batteryPowerChanged(boolean onBattery) {
2546        // When plugging in, update the CPU stats first before changing
2547        // the plug state.
2548        updateCpuStatsNow();
2549        synchronized (this) {
2550            synchronized(mPidsSelfLocked) {
2551                mOnBattery = DEBUG_POWER ? true : onBattery;
2552            }
2553        }
2554    }
2555
2556    /**
2557     * Initialize the application bind args. These are passed to each
2558     * process when the bindApplication() IPC is sent to the process. They're
2559     * lazily setup to make sure the services are running when they're asked for.
2560     */
2561    private HashMap<String, IBinder> getCommonServicesLocked() {
2562        if (mAppBindArgs == null) {
2563            mAppBindArgs = new HashMap<String, IBinder>();
2564
2565            // Setup the application init args
2566            mAppBindArgs.put("package", ServiceManager.getService("package"));
2567            mAppBindArgs.put("window", ServiceManager.getService("window"));
2568            mAppBindArgs.put(Context.ALARM_SERVICE,
2569                    ServiceManager.getService(Context.ALARM_SERVICE));
2570        }
2571        return mAppBindArgs;
2572    }
2573
2574    final void setFocusedActivityLocked(ActivityRecord r) {
2575        if (mFocusedActivity != r) {
2576            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2577            mFocusedActivity = r;
2578            if (r.task != null && r.task.voiceInteractor != null) {
2579                startRunningVoiceLocked();
2580            } else {
2581                finishRunningVoiceLocked();
2582            }
2583            mStackSupervisor.setFocusedStack(r);
2584            if (r != null) {
2585                mWindowManager.setFocusedApp(r.appToken, true);
2586            }
2587            applyUpdateLockStateLocked(r);
2588        }
2589    }
2590
2591    final void clearFocusedActivity(ActivityRecord r) {
2592        if (mFocusedActivity == r) {
2593            mFocusedActivity = null;
2594        }
2595    }
2596
2597    @Override
2598    public void setFocusedStack(int stackId) {
2599        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2600        synchronized (ActivityManagerService.this) {
2601            ActivityStack stack = mStackSupervisor.getStack(stackId);
2602            if (stack != null) {
2603                ActivityRecord r = stack.topRunningActivityLocked(null);
2604                if (r != null) {
2605                    setFocusedActivityLocked(r);
2606                }
2607            }
2608        }
2609    }
2610
2611    @Override
2612    public void notifyActivityDrawn(IBinder token) {
2613        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2614        synchronized (this) {
2615            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2616            if (r != null) {
2617                r.task.stack.notifyActivityDrawnLocked(r);
2618            }
2619        }
2620    }
2621
2622    final void applyUpdateLockStateLocked(ActivityRecord r) {
2623        // Modifications to the UpdateLock state are done on our handler, outside
2624        // the activity manager's locks.  The new state is determined based on the
2625        // state *now* of the relevant activity record.  The object is passed to
2626        // the handler solely for logging detail, not to be consulted/modified.
2627        final boolean nextState = r != null && r.immersive;
2628        mHandler.sendMessage(
2629                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2630    }
2631
2632    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2633        Message msg = Message.obtain();
2634        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2635        msg.obj = r.task.askedCompatMode ? null : r;
2636        mHandler.sendMessage(msg);
2637    }
2638
2639    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2640            String what, Object obj, ProcessRecord srcApp) {
2641        app.lastActivityTime = now;
2642
2643        if (app.activities.size() > 0) {
2644            // Don't want to touch dependent processes that are hosting activities.
2645            return index;
2646        }
2647
2648        int lrui = mLruProcesses.lastIndexOf(app);
2649        if (lrui < 0) {
2650            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2651                    + what + " " + obj + " from " + srcApp);
2652            return index;
2653        }
2654
2655        if (lrui >= index) {
2656            // Don't want to cause this to move dependent processes *back* in the
2657            // list as if they were less frequently used.
2658            return index;
2659        }
2660
2661        if (lrui >= mLruProcessActivityStart) {
2662            // Don't want to touch dependent processes that are hosting activities.
2663            return index;
2664        }
2665
2666        mLruProcesses.remove(lrui);
2667        if (index > 0) {
2668            index--;
2669        }
2670        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2671                + " in LRU list: " + app);
2672        mLruProcesses.add(index, app);
2673        return index;
2674    }
2675
2676    final void removeLruProcessLocked(ProcessRecord app) {
2677        int lrui = mLruProcesses.lastIndexOf(app);
2678        if (lrui >= 0) {
2679            if (!app.killed) {
2680                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2681                Process.killProcessQuiet(app.pid);
2682                Process.killProcessGroup(app.info.uid, app.pid);
2683            }
2684            if (lrui <= mLruProcessActivityStart) {
2685                mLruProcessActivityStart--;
2686            }
2687            if (lrui <= mLruProcessServiceStart) {
2688                mLruProcessServiceStart--;
2689            }
2690            mLruProcesses.remove(lrui);
2691        }
2692    }
2693
2694    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2695            ProcessRecord client) {
2696        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2697                || app.treatLikeActivity;
2698        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2699        if (!activityChange && hasActivity) {
2700            // The process has activities, so we are only allowing activity-based adjustments
2701            // to move it.  It should be kept in the front of the list with other
2702            // processes that have activities, and we don't want those to change their
2703            // order except due to activity operations.
2704            return;
2705        }
2706
2707        mLruSeq++;
2708        final long now = SystemClock.uptimeMillis();
2709        app.lastActivityTime = now;
2710
2711        // First a quick reject: if the app is already at the position we will
2712        // put it, then there is nothing to do.
2713        if (hasActivity) {
2714            final int N = mLruProcesses.size();
2715            if (N > 0 && mLruProcesses.get(N-1) == app) {
2716                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2717                return;
2718            }
2719        } else {
2720            if (mLruProcessServiceStart > 0
2721                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2722                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2723                return;
2724            }
2725        }
2726
2727        int lrui = mLruProcesses.lastIndexOf(app);
2728
2729        if (app.persistent && lrui >= 0) {
2730            // We don't care about the position of persistent processes, as long as
2731            // they are in the list.
2732            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2733            return;
2734        }
2735
2736        /* In progress: compute new position first, so we can avoid doing work
2737           if the process is not actually going to move.  Not yet working.
2738        int addIndex;
2739        int nextIndex;
2740        boolean inActivity = false, inService = false;
2741        if (hasActivity) {
2742            // Process has activities, put it at the very tipsy-top.
2743            addIndex = mLruProcesses.size();
2744            nextIndex = mLruProcessServiceStart;
2745            inActivity = true;
2746        } else if (hasService) {
2747            // Process has services, put it at the top of the service list.
2748            addIndex = mLruProcessActivityStart;
2749            nextIndex = mLruProcessServiceStart;
2750            inActivity = true;
2751            inService = true;
2752        } else  {
2753            // Process not otherwise of interest, it goes to the top of the non-service area.
2754            addIndex = mLruProcessServiceStart;
2755            if (client != null) {
2756                int clientIndex = mLruProcesses.lastIndexOf(client);
2757                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2758                        + app);
2759                if (clientIndex >= 0 && addIndex > clientIndex) {
2760                    addIndex = clientIndex;
2761                }
2762            }
2763            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2764        }
2765
2766        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2767                + mLruProcessActivityStart + "): " + app);
2768        */
2769
2770        if (lrui >= 0) {
2771            if (lrui < mLruProcessActivityStart) {
2772                mLruProcessActivityStart--;
2773            }
2774            if (lrui < mLruProcessServiceStart) {
2775                mLruProcessServiceStart--;
2776            }
2777            /*
2778            if (addIndex > lrui) {
2779                addIndex--;
2780            }
2781            if (nextIndex > lrui) {
2782                nextIndex--;
2783            }
2784            */
2785            mLruProcesses.remove(lrui);
2786        }
2787
2788        /*
2789        mLruProcesses.add(addIndex, app);
2790        if (inActivity) {
2791            mLruProcessActivityStart++;
2792        }
2793        if (inService) {
2794            mLruProcessActivityStart++;
2795        }
2796        */
2797
2798        int nextIndex;
2799        if (hasActivity) {
2800            final int N = mLruProcesses.size();
2801            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2802                // Process doesn't have activities, but has clients with
2803                // activities...  move it up, but one below the top (the top
2804                // should always have a real activity).
2805                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2806                mLruProcesses.add(N-1, app);
2807                // To keep it from spamming the LRU list (by making a bunch of clients),
2808                // we will push down any other entries owned by the app.
2809                final int uid = app.info.uid;
2810                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2811                    ProcessRecord subProc = mLruProcesses.get(i);
2812                    if (subProc.info.uid == uid) {
2813                        // We want to push this one down the list.  If the process after
2814                        // it is for the same uid, however, don't do so, because we don't
2815                        // want them internally to be re-ordered.
2816                        if (mLruProcesses.get(i-1).info.uid != uid) {
2817                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2818                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2819                            ProcessRecord tmp = mLruProcesses.get(i);
2820                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2821                            mLruProcesses.set(i-1, tmp);
2822                            i--;
2823                        }
2824                    } else {
2825                        // A gap, we can stop here.
2826                        break;
2827                    }
2828                }
2829            } else {
2830                // Process has activities, put it at the very tipsy-top.
2831                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2832                mLruProcesses.add(app);
2833            }
2834            nextIndex = mLruProcessServiceStart;
2835        } else if (hasService) {
2836            // Process has services, put it at the top of the service list.
2837            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2838            mLruProcesses.add(mLruProcessActivityStart, app);
2839            nextIndex = mLruProcessServiceStart;
2840            mLruProcessActivityStart++;
2841        } else  {
2842            // Process not otherwise of interest, it goes to the top of the non-service area.
2843            int index = mLruProcessServiceStart;
2844            if (client != null) {
2845                // If there is a client, don't allow the process to be moved up higher
2846                // in the list than that client.
2847                int clientIndex = mLruProcesses.lastIndexOf(client);
2848                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2849                        + " when updating " + app);
2850                if (clientIndex <= lrui) {
2851                    // Don't allow the client index restriction to push it down farther in the
2852                    // list than it already is.
2853                    clientIndex = lrui;
2854                }
2855                if (clientIndex >= 0 && index > clientIndex) {
2856                    index = clientIndex;
2857                }
2858            }
2859            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2860            mLruProcesses.add(index, app);
2861            nextIndex = index-1;
2862            mLruProcessActivityStart++;
2863            mLruProcessServiceStart++;
2864        }
2865
2866        // If the app is currently using a content provider or service,
2867        // bump those processes as well.
2868        for (int j=app.connections.size()-1; j>=0; j--) {
2869            ConnectionRecord cr = app.connections.valueAt(j);
2870            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2871                    && cr.binding.service.app != null
2872                    && cr.binding.service.app.lruSeq != mLruSeq
2873                    && !cr.binding.service.app.persistent) {
2874                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2875                        "service connection", cr, app);
2876            }
2877        }
2878        for (int j=app.conProviders.size()-1; j>=0; j--) {
2879            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2880            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2881                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2882                        "provider reference", cpr, app);
2883            }
2884        }
2885    }
2886
2887    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2888        if (uid == Process.SYSTEM_UID) {
2889            // The system gets to run in any process.  If there are multiple
2890            // processes with the same uid, just pick the first (this
2891            // should never happen).
2892            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2893            if (procs == null) return null;
2894            final int N = procs.size();
2895            for (int i = 0; i < N; i++) {
2896                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2897            }
2898        }
2899        ProcessRecord proc = mProcessNames.get(processName, uid);
2900        if (false && proc != null && !keepIfLarge
2901                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2902                && proc.lastCachedPss >= 4000) {
2903            // Turn this condition on to cause killing to happen regularly, for testing.
2904            if (proc.baseProcessTracker != null) {
2905                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2906            }
2907            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2908        } else if (proc != null && !keepIfLarge
2909                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2910                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2911            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2912            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2913                if (proc.baseProcessTracker != null) {
2914                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2915                }
2916                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2917            }
2918        }
2919        return proc;
2920    }
2921
2922    void ensurePackageDexOpt(String packageName) {
2923        IPackageManager pm = AppGlobals.getPackageManager();
2924        try {
2925            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2926                mDidDexOpt = true;
2927            }
2928        } catch (RemoteException e) {
2929        }
2930    }
2931
2932    boolean isNextTransitionForward() {
2933        int transit = mWindowManager.getPendingAppTransition();
2934        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2935                || transit == AppTransition.TRANSIT_TASK_OPEN
2936                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2937    }
2938
2939    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2940            String processName, String abiOverride, int uid, Runnable crashHandler) {
2941        synchronized(this) {
2942            ApplicationInfo info = new ApplicationInfo();
2943            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2944            // For isolated processes, the former contains the parent's uid and the latter the
2945            // actual uid of the isolated process.
2946            // In the special case introduced by this method (which is, starting an isolated
2947            // process directly from the SystemServer without an actual parent app process) the
2948            // closest thing to a parent's uid is SYSTEM_UID.
2949            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2950            // the |isolated| logic in the ProcessRecord constructor.
2951            info.uid = Process.SYSTEM_UID;
2952            info.processName = processName;
2953            info.className = entryPoint;
2954            info.packageName = "android";
2955            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2956                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2957                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2958                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2959                    crashHandler);
2960            return proc != null ? proc.pid : 0;
2961        }
2962    }
2963
2964    final ProcessRecord startProcessLocked(String processName,
2965            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2966            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2967            boolean isolated, boolean keepIfLarge) {
2968        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2969                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2970                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2971                null /* crashHandler */);
2972    }
2973
2974    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2975            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2976            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2977            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2978        long startTime = SystemClock.elapsedRealtime();
2979        ProcessRecord app;
2980        if (!isolated) {
2981            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2982            checkTime(startTime, "startProcess: after getProcessRecord");
2983        } else {
2984            // If this is an isolated process, it can't re-use an existing process.
2985            app = null;
2986        }
2987        // We don't have to do anything more if:
2988        // (1) There is an existing application record; and
2989        // (2) The caller doesn't think it is dead, OR there is no thread
2990        //     object attached to it so we know it couldn't have crashed; and
2991        // (3) There is a pid assigned to it, so it is either starting or
2992        //     already running.
2993        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2994                + " app=" + app + " knownToBeDead=" + knownToBeDead
2995                + " thread=" + (app != null ? app.thread : null)
2996                + " pid=" + (app != null ? app.pid : -1));
2997        if (app != null && app.pid > 0) {
2998            if (!knownToBeDead || app.thread == null) {
2999                // We already have the app running, or are waiting for it to
3000                // come up (we have a pid but not yet its thread), so keep it.
3001                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
3002                // If this is a new package in the process, add the package to the list
3003                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3004                checkTime(startTime, "startProcess: done, added package to proc");
3005                return app;
3006            }
3007
3008            // An application record is attached to a previous process,
3009            // clean it up now.
3010            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
3011            checkTime(startTime, "startProcess: bad proc running, killing");
3012            Process.killProcessGroup(app.info.uid, app.pid);
3013            handleAppDiedLocked(app, true, true);
3014            checkTime(startTime, "startProcess: done killing old proc");
3015        }
3016
3017        String hostingNameStr = hostingName != null
3018                ? hostingName.flattenToShortString() : null;
3019
3020        if (!isolated) {
3021            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3022                // If we are in the background, then check to see if this process
3023                // is bad.  If so, we will just silently fail.
3024                if (mBadProcesses.get(info.processName, info.uid) != null) {
3025                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3026                            + "/" + info.processName);
3027                    return null;
3028                }
3029            } else {
3030                // When the user is explicitly starting a process, then clear its
3031                // crash count so that we won't make it bad until they see at
3032                // least one crash dialog again, and make the process good again
3033                // if it had been bad.
3034                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3035                        + "/" + info.processName);
3036                mProcessCrashTimes.remove(info.processName, info.uid);
3037                if (mBadProcesses.get(info.processName, info.uid) != null) {
3038                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3039                            UserHandle.getUserId(info.uid), info.uid,
3040                            info.processName);
3041                    mBadProcesses.remove(info.processName, info.uid);
3042                    if (app != null) {
3043                        app.bad = false;
3044                    }
3045                }
3046            }
3047        }
3048
3049        if (app == null) {
3050            checkTime(startTime, "startProcess: creating new process record");
3051            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3052            if (app == null) {
3053                Slog.w(TAG, "Failed making new process record for "
3054                        + processName + "/" + info.uid + " isolated=" + isolated);
3055                return null;
3056            }
3057            app.crashHandler = crashHandler;
3058            mProcessNames.put(processName, app.uid, app);
3059            if (isolated) {
3060                mIsolatedProcesses.put(app.uid, app);
3061            }
3062            checkTime(startTime, "startProcess: done creating new process record");
3063        } else {
3064            // If this is a new package in the process, add the package to the list
3065            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3066            checkTime(startTime, "startProcess: added package to existing proc");
3067        }
3068
3069        // If the system is not ready yet, then hold off on starting this
3070        // process until it is.
3071        if (!mProcessesReady
3072                && !isAllowedWhileBooting(info)
3073                && !allowWhileBooting) {
3074            if (!mProcessesOnHold.contains(app)) {
3075                mProcessesOnHold.add(app);
3076            }
3077            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3078            checkTime(startTime, "startProcess: returning with proc on hold");
3079            return app;
3080        }
3081
3082        checkTime(startTime, "startProcess: stepping in to startProcess");
3083        startProcessLocked(
3084                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3085        checkTime(startTime, "startProcess: done starting proc!");
3086        return (app.pid != 0) ? app : null;
3087    }
3088
3089    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3090        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3091    }
3092
3093    private final void startProcessLocked(ProcessRecord app,
3094            String hostingType, String hostingNameStr) {
3095        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3096                null /* entryPoint */, null /* entryPointArgs */);
3097    }
3098
3099    private final void startProcessLocked(ProcessRecord app, String hostingType,
3100            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3101        long startTime = SystemClock.elapsedRealtime();
3102        if (app.pid > 0 && app.pid != MY_PID) {
3103            checkTime(startTime, "startProcess: removing from pids map");
3104            synchronized (mPidsSelfLocked) {
3105                mPidsSelfLocked.remove(app.pid);
3106                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3107            }
3108            checkTime(startTime, "startProcess: done removing from pids map");
3109            app.setPid(0);
3110        }
3111
3112        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3113                "startProcessLocked removing on hold: " + app);
3114        mProcessesOnHold.remove(app);
3115
3116        checkTime(startTime, "startProcess: starting to update cpu stats");
3117        updateCpuStats();
3118        checkTime(startTime, "startProcess: done updating cpu stats");
3119
3120        try {
3121            int uid = app.uid;
3122
3123            int[] gids = null;
3124            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3125            if (!app.isolated) {
3126                int[] permGids = null;
3127                try {
3128                    checkTime(startTime, "startProcess: getting gids from package manager");
3129                    final PackageManager pm = mContext.getPackageManager();
3130                    permGids = pm.getPackageGids(app.info.packageName);
3131
3132                    if (Environment.isExternalStorageEmulated()) {
3133                        checkTime(startTime, "startProcess: checking external storage perm");
3134                        if (pm.checkPermission(
3135                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3136                                app.info.packageName) == PERMISSION_GRANTED) {
3137                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3138                        } else {
3139                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3140                        }
3141                    }
3142                } catch (PackageManager.NameNotFoundException e) {
3143                    Slog.w(TAG, "Unable to retrieve gids", e);
3144                }
3145
3146                /*
3147                 * Add shared application and profile GIDs so applications can share some
3148                 * resources like shared libraries and access user-wide resources
3149                 */
3150                if (permGids == null) {
3151                    gids = new int[2];
3152                } else {
3153                    gids = new int[permGids.length + 2];
3154                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3155                }
3156                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3157                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3158            }
3159            checkTime(startTime, "startProcess: building args");
3160            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3161                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3162                        && mTopComponent != null
3163                        && app.processName.equals(mTopComponent.getPackageName())) {
3164                    uid = 0;
3165                }
3166                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3167                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3168                    uid = 0;
3169                }
3170            }
3171            int debugFlags = 0;
3172            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3173                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3174                // Also turn on CheckJNI for debuggable apps. It's quite
3175                // awkward to turn on otherwise.
3176                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3177            }
3178            // Run the app in safe mode if its manifest requests so or the
3179            // system is booted in safe mode.
3180            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3181                mSafeMode == true) {
3182                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3183            }
3184            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3185                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3186            }
3187            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3188                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3189            }
3190            if ("1".equals(SystemProperties.get("debug.assert"))) {
3191                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3192            }
3193
3194            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3195            if (requiredAbi == null) {
3196                requiredAbi = Build.SUPPORTED_ABIS[0];
3197            }
3198
3199            String instructionSet = null;
3200            if (app.info.primaryCpuAbi != null) {
3201                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3202            }
3203
3204            // Start the process.  It will either succeed and return a result containing
3205            // the PID of the new process, or else throw a RuntimeException.
3206            boolean isActivityProcess = (entryPoint == null);
3207            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3208            checkTime(startTime, "startProcess: asking zygote to start proc");
3209            Process.ProcessStartResult startResult = Process.start(entryPoint,
3210                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3211                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3212                    app.info.dataDir, entryPointArgs);
3213            checkTime(startTime, "startProcess: returned from zygote!");
3214
3215            if (app.isolated) {
3216                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3217            }
3218            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3219            checkTime(startTime, "startProcess: done updating battery stats");
3220
3221            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3222                    UserHandle.getUserId(uid), startResult.pid, uid,
3223                    app.processName, hostingType,
3224                    hostingNameStr != null ? hostingNameStr : "");
3225
3226            if (app.persistent) {
3227                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3228            }
3229
3230            checkTime(startTime, "startProcess: building log message");
3231            StringBuilder buf = mStringBuilder;
3232            buf.setLength(0);
3233            buf.append("Start proc ");
3234            buf.append(app.processName);
3235            if (!isActivityProcess) {
3236                buf.append(" [");
3237                buf.append(entryPoint);
3238                buf.append("]");
3239            }
3240            buf.append(" for ");
3241            buf.append(hostingType);
3242            if (hostingNameStr != null) {
3243                buf.append(" ");
3244                buf.append(hostingNameStr);
3245            }
3246            buf.append(": pid=");
3247            buf.append(startResult.pid);
3248            buf.append(" uid=");
3249            buf.append(uid);
3250            buf.append(" gids={");
3251            if (gids != null) {
3252                for (int gi=0; gi<gids.length; gi++) {
3253                    if (gi != 0) buf.append(", ");
3254                    buf.append(gids[gi]);
3255
3256                }
3257            }
3258            buf.append("}");
3259            if (requiredAbi != null) {
3260                buf.append(" abi=");
3261                buf.append(requiredAbi);
3262            }
3263            Slog.i(TAG, buf.toString());
3264            app.setPid(startResult.pid);
3265            app.usingWrapper = startResult.usingWrapper;
3266            app.removed = false;
3267            app.killed = false;
3268            app.killedByAm = false;
3269            checkTime(startTime, "startProcess: starting to update pids map");
3270            synchronized (mPidsSelfLocked) {
3271                this.mPidsSelfLocked.put(startResult.pid, app);
3272                if (isActivityProcess) {
3273                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3274                    msg.obj = app;
3275                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3276                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3277                }
3278            }
3279            checkTime(startTime, "startProcess: done updating pids map");
3280        } catch (RuntimeException e) {
3281            // XXX do better error recovery.
3282            app.setPid(0);
3283            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3284            if (app.isolated) {
3285                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3286            }
3287            Slog.e(TAG, "Failure starting process " + app.processName, e);
3288        }
3289    }
3290
3291    void updateUsageStats(ActivityRecord component, boolean resumed) {
3292        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3293        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3294        if (resumed) {
3295            if (mUsageStatsService != null) {
3296                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3297                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3298            }
3299            synchronized (stats) {
3300                stats.noteActivityResumedLocked(component.app.uid);
3301            }
3302        } else {
3303            if (mUsageStatsService != null) {
3304                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3305                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3306            }
3307            synchronized (stats) {
3308                stats.noteActivityPausedLocked(component.app.uid);
3309            }
3310        }
3311    }
3312
3313    Intent getHomeIntent() {
3314        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3315        intent.setComponent(mTopComponent);
3316        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3317            intent.addCategory(Intent.CATEGORY_HOME);
3318        }
3319        return intent;
3320    }
3321
3322    boolean startHomeActivityLocked(int userId) {
3323        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3324                && mTopAction == null) {
3325            // We are running in factory test mode, but unable to find
3326            // the factory test app, so just sit around displaying the
3327            // error message and don't try to start anything.
3328            return false;
3329        }
3330        Intent intent = getHomeIntent();
3331        ActivityInfo aInfo =
3332            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3333        if (aInfo != null) {
3334            intent.setComponent(new ComponentName(
3335                    aInfo.applicationInfo.packageName, aInfo.name));
3336            // Don't do this if the home app is currently being
3337            // instrumented.
3338            aInfo = new ActivityInfo(aInfo);
3339            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3340            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3341                    aInfo.applicationInfo.uid, true);
3342            if (app == null || app.instrumentationClass == null) {
3343                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3344                mStackSupervisor.startHomeActivity(intent, aInfo);
3345            }
3346        }
3347
3348        return true;
3349    }
3350
3351    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3352        ActivityInfo ai = null;
3353        ComponentName comp = intent.getComponent();
3354        try {
3355            if (comp != null) {
3356                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3357            } else {
3358                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3359                        intent,
3360                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3361                            flags, userId);
3362
3363                if (info != null) {
3364                    ai = info.activityInfo;
3365                }
3366            }
3367        } catch (RemoteException e) {
3368            // ignore
3369        }
3370
3371        return ai;
3372    }
3373
3374    /**
3375     * Starts the "new version setup screen" if appropriate.
3376     */
3377    void startSetupActivityLocked() {
3378        // Only do this once per boot.
3379        if (mCheckedForSetup) {
3380            return;
3381        }
3382
3383        // We will show this screen if the current one is a different
3384        // version than the last one shown, and we are not running in
3385        // low-level factory test mode.
3386        final ContentResolver resolver = mContext.getContentResolver();
3387        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3388                Settings.Global.getInt(resolver,
3389                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3390            mCheckedForSetup = true;
3391
3392            // See if we should be showing the platform update setup UI.
3393            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3394            List<ResolveInfo> ris = mContext.getPackageManager()
3395                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3396
3397            // We don't allow third party apps to replace this.
3398            ResolveInfo ri = null;
3399            for (int i=0; ris != null && i<ris.size(); i++) {
3400                if ((ris.get(i).activityInfo.applicationInfo.flags
3401                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3402                    ri = ris.get(i);
3403                    break;
3404                }
3405            }
3406
3407            if (ri != null) {
3408                String vers = ri.activityInfo.metaData != null
3409                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3410                        : null;
3411                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3412                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3413                            Intent.METADATA_SETUP_VERSION);
3414                }
3415                String lastVers = Settings.Secure.getString(
3416                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3417                if (vers != null && !vers.equals(lastVers)) {
3418                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3419                    intent.setComponent(new ComponentName(
3420                            ri.activityInfo.packageName, ri.activityInfo.name));
3421                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3422                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3423                            null);
3424                }
3425            }
3426        }
3427    }
3428
3429    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3430        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3431    }
3432
3433    void enforceNotIsolatedCaller(String caller) {
3434        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3435            throw new SecurityException("Isolated process not allowed to call " + caller);
3436        }
3437    }
3438
3439    void enforceShellRestriction(String restriction, int userHandle) {
3440        if (Binder.getCallingUid() == Process.SHELL_UID) {
3441            if (userHandle < 0
3442                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3443                throw new SecurityException("Shell does not have permission to access user "
3444                        + userHandle);
3445            }
3446        }
3447    }
3448
3449    @Override
3450    public int getFrontActivityScreenCompatMode() {
3451        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3452        synchronized (this) {
3453            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3454        }
3455    }
3456
3457    @Override
3458    public void setFrontActivityScreenCompatMode(int mode) {
3459        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3460                "setFrontActivityScreenCompatMode");
3461        synchronized (this) {
3462            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3463        }
3464    }
3465
3466    @Override
3467    public int getPackageScreenCompatMode(String packageName) {
3468        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3469        synchronized (this) {
3470            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3471        }
3472    }
3473
3474    @Override
3475    public void setPackageScreenCompatMode(String packageName, int mode) {
3476        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3477                "setPackageScreenCompatMode");
3478        synchronized (this) {
3479            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3480        }
3481    }
3482
3483    @Override
3484    public boolean getPackageAskScreenCompat(String packageName) {
3485        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3486        synchronized (this) {
3487            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3488        }
3489    }
3490
3491    @Override
3492    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3493        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3494                "setPackageAskScreenCompat");
3495        synchronized (this) {
3496            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3497        }
3498    }
3499
3500    private void dispatchProcessesChanged() {
3501        int N;
3502        synchronized (this) {
3503            N = mPendingProcessChanges.size();
3504            if (mActiveProcessChanges.length < N) {
3505                mActiveProcessChanges = new ProcessChangeItem[N];
3506            }
3507            mPendingProcessChanges.toArray(mActiveProcessChanges);
3508            mAvailProcessChanges.addAll(mPendingProcessChanges);
3509            mPendingProcessChanges.clear();
3510            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3511        }
3512
3513        int i = mProcessObservers.beginBroadcast();
3514        while (i > 0) {
3515            i--;
3516            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3517            if (observer != null) {
3518                try {
3519                    for (int j=0; j<N; j++) {
3520                        ProcessChangeItem item = mActiveProcessChanges[j];
3521                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3522                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3523                                    + item.pid + " uid=" + item.uid + ": "
3524                                    + item.foregroundActivities);
3525                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3526                                    item.foregroundActivities);
3527                        }
3528                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3529                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3530                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3531                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3532                        }
3533                    }
3534                } catch (RemoteException e) {
3535                }
3536            }
3537        }
3538        mProcessObservers.finishBroadcast();
3539    }
3540
3541    private void dispatchProcessDied(int pid, int uid) {
3542        int i = mProcessObservers.beginBroadcast();
3543        while (i > 0) {
3544            i--;
3545            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3546            if (observer != null) {
3547                try {
3548                    observer.onProcessDied(pid, uid);
3549                } catch (RemoteException e) {
3550                }
3551            }
3552        }
3553        mProcessObservers.finishBroadcast();
3554    }
3555
3556    @Override
3557    public final int startActivity(IApplicationThread caller, String callingPackage,
3558            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3559            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3560        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3561            resultWho, requestCode, startFlags, profilerInfo, options,
3562            UserHandle.getCallingUserId());
3563    }
3564
3565    @Override
3566    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3567            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3568            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3569        enforceNotIsolatedCaller("startActivity");
3570        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3571                false, ALLOW_FULL_ONLY, "startActivity", null);
3572        // TODO: Switch to user app stacks here.
3573        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3574                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3575                profilerInfo, null, null, options, userId, null, null);
3576    }
3577
3578    @Override
3579    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3580            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3581            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3582
3583        // This is very dangerous -- it allows you to perform a start activity (including
3584        // permission grants) as any app that may launch one of your own activities.  So
3585        // we will only allow this to be done from activities that are part of the core framework,
3586        // and then only when they are running as the system.
3587        final ActivityRecord sourceRecord;
3588        final int targetUid;
3589        final String targetPackage;
3590        synchronized (this) {
3591            if (resultTo == null) {
3592                throw new SecurityException("Must be called from an activity");
3593            }
3594            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3595            if (sourceRecord == null) {
3596                throw new SecurityException("Called with bad activity token: " + resultTo);
3597            }
3598            if (!sourceRecord.info.packageName.equals("android")) {
3599                throw new SecurityException(
3600                        "Must be called from an activity that is declared in the android package");
3601            }
3602            if (sourceRecord.app == null) {
3603                throw new SecurityException("Called without a process attached to activity");
3604            }
3605            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3606                // This is still okay, as long as this activity is running under the
3607                // uid of the original calling activity.
3608                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3609                    throw new SecurityException(
3610                            "Calling activity in uid " + sourceRecord.app.uid
3611                                    + " must be system uid or original calling uid "
3612                                    + sourceRecord.launchedFromUid);
3613                }
3614            }
3615            targetUid = sourceRecord.launchedFromUid;
3616            targetPackage = sourceRecord.launchedFromPackage;
3617        }
3618
3619        if (userId == UserHandle.USER_NULL) {
3620            userId = UserHandle.getUserId(sourceRecord.app.uid);
3621        }
3622
3623        // TODO: Switch to user app stacks here.
3624        try {
3625            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3626                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3627                    null, null, options, userId, null, null);
3628            return ret;
3629        } catch (SecurityException e) {
3630            // XXX need to figure out how to propagate to original app.
3631            // A SecurityException here is generally actually a fault of the original
3632            // calling activity (such as a fairly granting permissions), so propagate it
3633            // back to them.
3634            /*
3635            StringBuilder msg = new StringBuilder();
3636            msg.append("While launching");
3637            msg.append(intent.toString());
3638            msg.append(": ");
3639            msg.append(e.getMessage());
3640            */
3641            throw e;
3642        }
3643    }
3644
3645    @Override
3646    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3647            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3648            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3649        enforceNotIsolatedCaller("startActivityAndWait");
3650        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3651                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3652        WaitResult res = new WaitResult();
3653        // TODO: Switch to user app stacks here.
3654        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3655                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3656                options, userId, null, null);
3657        return res;
3658    }
3659
3660    @Override
3661    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3662            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3663            int startFlags, Configuration config, Bundle options, int userId) {
3664        enforceNotIsolatedCaller("startActivityWithConfig");
3665        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3666                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3667        // TODO: Switch to user app stacks here.
3668        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3669                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3670                null, null, config, options, userId, null, null);
3671        return ret;
3672    }
3673
3674    @Override
3675    public int startActivityIntentSender(IApplicationThread caller,
3676            IntentSender intent, Intent fillInIntent, String resolvedType,
3677            IBinder resultTo, String resultWho, int requestCode,
3678            int flagsMask, int flagsValues, Bundle options) {
3679        enforceNotIsolatedCaller("startActivityIntentSender");
3680        // Refuse possible leaked file descriptors
3681        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3682            throw new IllegalArgumentException("File descriptors passed in Intent");
3683        }
3684
3685        IIntentSender sender = intent.getTarget();
3686        if (!(sender instanceof PendingIntentRecord)) {
3687            throw new IllegalArgumentException("Bad PendingIntent object");
3688        }
3689
3690        PendingIntentRecord pir = (PendingIntentRecord)sender;
3691
3692        synchronized (this) {
3693            // If this is coming from the currently resumed activity, it is
3694            // effectively saying that app switches are allowed at this point.
3695            final ActivityStack stack = getFocusedStack();
3696            if (stack.mResumedActivity != null &&
3697                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3698                mAppSwitchesAllowedTime = 0;
3699            }
3700        }
3701        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3702                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3703        return ret;
3704    }
3705
3706    @Override
3707    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3708            Intent intent, String resolvedType, IVoiceInteractionSession session,
3709            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3710            Bundle options, int userId) {
3711        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3712                != PackageManager.PERMISSION_GRANTED) {
3713            String msg = "Permission Denial: startVoiceActivity() from pid="
3714                    + Binder.getCallingPid()
3715                    + ", uid=" + Binder.getCallingUid()
3716                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3717            Slog.w(TAG, msg);
3718            throw new SecurityException(msg);
3719        }
3720        if (session == null || interactor == null) {
3721            throw new NullPointerException("null session or interactor");
3722        }
3723        userId = handleIncomingUser(callingPid, callingUid, userId,
3724                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3725        // TODO: Switch to user app stacks here.
3726        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3727                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3728                null, options, userId, null, null);
3729    }
3730
3731    @Override
3732    public boolean startNextMatchingActivity(IBinder callingActivity,
3733            Intent intent, Bundle options) {
3734        // Refuse possible leaked file descriptors
3735        if (intent != null && intent.hasFileDescriptors() == true) {
3736            throw new IllegalArgumentException("File descriptors passed in Intent");
3737        }
3738
3739        synchronized (this) {
3740            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3741            if (r == null) {
3742                ActivityOptions.abort(options);
3743                return false;
3744            }
3745            if (r.app == null || r.app.thread == null) {
3746                // The caller is not running...  d'oh!
3747                ActivityOptions.abort(options);
3748                return false;
3749            }
3750            intent = new Intent(intent);
3751            // The caller is not allowed to change the data.
3752            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3753            // And we are resetting to find the next component...
3754            intent.setComponent(null);
3755
3756            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3757
3758            ActivityInfo aInfo = null;
3759            try {
3760                List<ResolveInfo> resolves =
3761                    AppGlobals.getPackageManager().queryIntentActivities(
3762                            intent, r.resolvedType,
3763                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3764                            UserHandle.getCallingUserId());
3765
3766                // Look for the original activity in the list...
3767                final int N = resolves != null ? resolves.size() : 0;
3768                for (int i=0; i<N; i++) {
3769                    ResolveInfo rInfo = resolves.get(i);
3770                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3771                            && rInfo.activityInfo.name.equals(r.info.name)) {
3772                        // We found the current one...  the next matching is
3773                        // after it.
3774                        i++;
3775                        if (i<N) {
3776                            aInfo = resolves.get(i).activityInfo;
3777                        }
3778                        if (debug) {
3779                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3780                                    + "/" + r.info.name);
3781                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3782                                    + "/" + aInfo.name);
3783                        }
3784                        break;
3785                    }
3786                }
3787            } catch (RemoteException e) {
3788            }
3789
3790            if (aInfo == null) {
3791                // Nobody who is next!
3792                ActivityOptions.abort(options);
3793                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3794                return false;
3795            }
3796
3797            intent.setComponent(new ComponentName(
3798                    aInfo.applicationInfo.packageName, aInfo.name));
3799            intent.setFlags(intent.getFlags()&~(
3800                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3801                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3802                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3803                    Intent.FLAG_ACTIVITY_NEW_TASK));
3804
3805            // Okay now we need to start the new activity, replacing the
3806            // currently running activity.  This is a little tricky because
3807            // we want to start the new one as if the current one is finished,
3808            // but not finish the current one first so that there is no flicker.
3809            // And thus...
3810            final boolean wasFinishing = r.finishing;
3811            r.finishing = true;
3812
3813            // Propagate reply information over to the new activity.
3814            final ActivityRecord resultTo = r.resultTo;
3815            final String resultWho = r.resultWho;
3816            final int requestCode = r.requestCode;
3817            r.resultTo = null;
3818            if (resultTo != null) {
3819                resultTo.removeResultsLocked(r, resultWho, requestCode);
3820            }
3821
3822            final long origId = Binder.clearCallingIdentity();
3823            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3824                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3825                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3826                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3827            Binder.restoreCallingIdentity(origId);
3828
3829            r.finishing = wasFinishing;
3830            if (res != ActivityManager.START_SUCCESS) {
3831                return false;
3832            }
3833            return true;
3834        }
3835    }
3836
3837    @Override
3838    public final int startActivityFromRecents(int taskId, Bundle options) {
3839        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3840            String msg = "Permission Denial: startActivityFromRecents called without " +
3841                    START_TASKS_FROM_RECENTS;
3842            Slog.w(TAG, msg);
3843            throw new SecurityException(msg);
3844        }
3845        return startActivityFromRecentsInner(taskId, options);
3846    }
3847
3848    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3849        final TaskRecord task;
3850        final int callingUid;
3851        final String callingPackage;
3852        final Intent intent;
3853        final int userId;
3854        synchronized (this) {
3855            task = recentTaskForIdLocked(taskId);
3856            if (task == null) {
3857                throw new IllegalArgumentException("Task " + taskId + " not found.");
3858            }
3859            callingUid = task.mCallingUid;
3860            callingPackage = task.mCallingPackage;
3861            intent = task.intent;
3862            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3863            userId = task.userId;
3864        }
3865        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3866                options, userId, null, task);
3867    }
3868
3869    final int startActivityInPackage(int uid, String callingPackage,
3870            Intent intent, String resolvedType, IBinder resultTo,
3871            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3872            IActivityContainer container, TaskRecord inTask) {
3873
3874        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3875                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3876
3877        // TODO: Switch to user app stacks here.
3878        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3879                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3880                null, null, null, options, userId, container, inTask);
3881        return ret;
3882    }
3883
3884    @Override
3885    public final int startActivities(IApplicationThread caller, String callingPackage,
3886            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3887            int userId) {
3888        enforceNotIsolatedCaller("startActivities");
3889        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3890                false, ALLOW_FULL_ONLY, "startActivity", null);
3891        // TODO: Switch to user app stacks here.
3892        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3893                resolvedTypes, resultTo, options, userId);
3894        return ret;
3895    }
3896
3897    final int startActivitiesInPackage(int uid, String callingPackage,
3898            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3899            Bundle options, int userId) {
3900
3901        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3902                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3903        // TODO: Switch to user app stacks here.
3904        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3905                resultTo, options, userId);
3906        return ret;
3907    }
3908
3909    //explicitly remove thd old information in mRecentTasks when removing existing user.
3910    private void removeRecentTasksForUserLocked(int userId) {
3911        if(userId <= 0) {
3912            Slog.i(TAG, "Can't remove recent task on user " + userId);
3913            return;
3914        }
3915
3916        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3917            TaskRecord tr = mRecentTasks.get(i);
3918            if (tr.userId == userId) {
3919                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3920                        + " when finishing user" + userId);
3921                mRecentTasks.remove(i);
3922                tr.removedFromRecents(mTaskPersister);
3923            }
3924        }
3925
3926        // Remove tasks from persistent storage.
3927        mTaskPersister.wakeup(null, true);
3928    }
3929
3930    // Sort by taskId
3931    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3932        @Override
3933        public int compare(TaskRecord lhs, TaskRecord rhs) {
3934            return rhs.taskId - lhs.taskId;
3935        }
3936    };
3937
3938    // Extract the affiliates of the chain containing mRecentTasks[start].
3939    private int processNextAffiliateChain(int start) {
3940        final TaskRecord startTask = mRecentTasks.get(start);
3941        final int affiliateId = startTask.mAffiliatedTaskId;
3942
3943        // Quick identification of isolated tasks. I.e. those not launched behind.
3944        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3945                startTask.mNextAffiliate == null) {
3946            // There is still a slim chance that there are other tasks that point to this task
3947            // and that the chain is so messed up that this task no longer points to them but
3948            // the gain of this optimization outweighs the risk.
3949            startTask.inRecents = true;
3950            return start + 1;
3951        }
3952
3953        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3954        mTmpRecents.clear();
3955        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3956            final TaskRecord task = mRecentTasks.get(i);
3957            if (task.mAffiliatedTaskId == affiliateId) {
3958                mRecentTasks.remove(i);
3959                mTmpRecents.add(task);
3960            }
3961        }
3962
3963        // Sort them all by taskId. That is the order they were create in and that order will
3964        // always be correct.
3965        Collections.sort(mTmpRecents, mTaskRecordComparator);
3966
3967        // Go through and fix up the linked list.
3968        // The first one is the end of the chain and has no next.
3969        final TaskRecord first = mTmpRecents.get(0);
3970        first.inRecents = true;
3971        if (first.mNextAffiliate != null) {
3972            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3973            first.setNextAffiliate(null);
3974            mTaskPersister.wakeup(first, false);
3975        }
3976        // Everything in the middle is doubly linked from next to prev.
3977        final int tmpSize = mTmpRecents.size();
3978        for (int i = 0; i < tmpSize - 1; ++i) {
3979            final TaskRecord next = mTmpRecents.get(i);
3980            final TaskRecord prev = mTmpRecents.get(i + 1);
3981            if (next.mPrevAffiliate != prev) {
3982                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3983                        " setting prev=" + prev);
3984                next.setPrevAffiliate(prev);
3985                mTaskPersister.wakeup(next, false);
3986            }
3987            if (prev.mNextAffiliate != next) {
3988                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3989                        " setting next=" + next);
3990                prev.setNextAffiliate(next);
3991                mTaskPersister.wakeup(prev, false);
3992            }
3993            prev.inRecents = true;
3994        }
3995        // The last one is the beginning of the list and has no prev.
3996        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3997        if (last.mPrevAffiliate != null) {
3998            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3999            last.setPrevAffiliate(null);
4000            mTaskPersister.wakeup(last, false);
4001        }
4002
4003        // Insert the group back into mRecentTasks at start.
4004        mRecentTasks.addAll(start, mTmpRecents);
4005
4006        // Let the caller know where we left off.
4007        return start + tmpSize;
4008    }
4009
4010    /**
4011     * Update the recent tasks lists: make sure tasks should still be here (their
4012     * applications / activities still exist), update their availability, fixup ordering
4013     * of affiliations.
4014     */
4015    void cleanupRecentTasksLocked(int userId) {
4016        if (mRecentTasks == null) {
4017            // Happens when called from the packagemanager broadcast before boot.
4018            return;
4019        }
4020
4021        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4022        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4023        final IPackageManager pm = AppGlobals.getPackageManager();
4024        final ActivityInfo dummyAct = new ActivityInfo();
4025        final ApplicationInfo dummyApp = new ApplicationInfo();
4026
4027        int N = mRecentTasks.size();
4028
4029        int[] users = userId == UserHandle.USER_ALL
4030                ? getUsersLocked() : new int[] { userId };
4031        for (int user : users) {
4032            for (int i = 0; i < N; i++) {
4033                TaskRecord task = mRecentTasks.get(i);
4034                if (task.userId != user) {
4035                    // Only look at tasks for the user ID of interest.
4036                    continue;
4037                }
4038                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4039                    // This situation is broken, and we should just get rid of it now.
4040                    mRecentTasks.remove(i);
4041                    task.removedFromRecents(mTaskPersister);
4042                    i--;
4043                    N--;
4044                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4045                    continue;
4046                }
4047                // Check whether this activity is currently available.
4048                if (task.realActivity != null) {
4049                    ActivityInfo ai = availActCache.get(task.realActivity);
4050                    if (ai == null) {
4051                        try {
4052                            ai = pm.getActivityInfo(task.realActivity,
4053                                    PackageManager.GET_UNINSTALLED_PACKAGES
4054                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4055                        } catch (RemoteException e) {
4056                            // Will never happen.
4057                            continue;
4058                        }
4059                        if (ai == null) {
4060                            ai = dummyAct;
4061                        }
4062                        availActCache.put(task.realActivity, ai);
4063                    }
4064                    if (ai == dummyAct) {
4065                        // This could be either because the activity no longer exists, or the
4066                        // app is temporarily gone.  For the former we want to remove the recents
4067                        // entry; for the latter we want to mark it as unavailable.
4068                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4069                        if (app == null) {
4070                            try {
4071                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4072                                        PackageManager.GET_UNINSTALLED_PACKAGES
4073                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4074                            } catch (RemoteException e) {
4075                                // Will never happen.
4076                                continue;
4077                            }
4078                            if (app == null) {
4079                                app = dummyApp;
4080                            }
4081                            availAppCache.put(task.realActivity.getPackageName(), app);
4082                        }
4083                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4084                            // Doesn't exist any more!  Good-bye.
4085                            mRecentTasks.remove(i);
4086                            task.removedFromRecents(mTaskPersister);
4087                            i--;
4088                            N--;
4089                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4090                            continue;
4091                        } else {
4092                            // Otherwise just not available for now.
4093                            if (task.isAvailable) {
4094                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4095                                        + task);
4096                            }
4097                            task.isAvailable = false;
4098                        }
4099                    } else {
4100                        if (!ai.enabled || !ai.applicationInfo.enabled
4101                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4102                            if (task.isAvailable) {
4103                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4104                                        + task + " (enabled=" + ai.enabled + "/"
4105                                        + ai.applicationInfo.enabled +  " flags="
4106                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4107                            }
4108                            task.isAvailable = false;
4109                        } else {
4110                            if (!task.isAvailable) {
4111                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4112                                        + task);
4113                            }
4114                            task.isAvailable = true;
4115                        }
4116                    }
4117                }
4118            }
4119        }
4120
4121        // Verify the affiliate chain for each task.
4122        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4123        }
4124
4125        mTmpRecents.clear();
4126        // mRecentTasks is now in sorted, affiliated order.
4127    }
4128
4129    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4130        int N = mRecentTasks.size();
4131        TaskRecord top = task;
4132        int topIndex = taskIndex;
4133        while (top.mNextAffiliate != null && topIndex > 0) {
4134            top = top.mNextAffiliate;
4135            topIndex--;
4136        }
4137        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4138                + topIndex + " from intial " + taskIndex);
4139        // Find the end of the chain, doing a sanity check along the way.
4140        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4141        int endIndex = topIndex;
4142        TaskRecord prev = top;
4143        while (endIndex < N) {
4144            TaskRecord cur = mRecentTasks.get(endIndex);
4145            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4146                    + endIndex + " " + cur);
4147            if (cur == top) {
4148                // Verify start of the chain.
4149                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4150                    Slog.wtf(TAG, "Bad chain @" + endIndex
4151                            + ": first task has next affiliate: " + prev);
4152                    sane = false;
4153                    break;
4154                }
4155            } else {
4156                // Verify middle of the chain's next points back to the one before.
4157                if (cur.mNextAffiliate != prev
4158                        || cur.mNextAffiliateTaskId != prev.taskId) {
4159                    Slog.wtf(TAG, "Bad chain @" + endIndex
4160                            + ": middle task " + cur + " @" + endIndex
4161                            + " has bad next affiliate "
4162                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4163                            + ", expected " + prev);
4164                    sane = false;
4165                    break;
4166                }
4167            }
4168            if (cur.mPrevAffiliateTaskId == -1) {
4169                // Chain ends here.
4170                if (cur.mPrevAffiliate != null) {
4171                    Slog.wtf(TAG, "Bad chain @" + endIndex
4172                            + ": last task " + cur + " has previous affiliate "
4173                            + cur.mPrevAffiliate);
4174                    sane = false;
4175                }
4176                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4177                break;
4178            } else {
4179                // Verify middle of the chain's prev points to a valid item.
4180                if (cur.mPrevAffiliate == null) {
4181                    Slog.wtf(TAG, "Bad chain @" + endIndex
4182                            + ": task " + cur + " has previous affiliate "
4183                            + cur.mPrevAffiliate + " but should be id "
4184                            + cur.mPrevAffiliate);
4185                    sane = false;
4186                    break;
4187                }
4188            }
4189            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4190                Slog.wtf(TAG, "Bad chain @" + endIndex
4191                        + ": task " + cur + " has affiliated id "
4192                        + cur.mAffiliatedTaskId + " but should be "
4193                        + task.mAffiliatedTaskId);
4194                sane = false;
4195                break;
4196            }
4197            prev = cur;
4198            endIndex++;
4199            if (endIndex >= N) {
4200                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4201                        + ": last task " + prev);
4202                sane = false;
4203                break;
4204            }
4205        }
4206        if (sane) {
4207            if (endIndex < taskIndex) {
4208                Slog.wtf(TAG, "Bad chain @" + endIndex
4209                        + ": did not extend to task " + task + " @" + taskIndex);
4210                sane = false;
4211            }
4212        }
4213        if (sane) {
4214            // All looks good, we can just move all of the affiliated tasks
4215            // to the top.
4216            for (int i=topIndex; i<=endIndex; i++) {
4217                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4218                        + " from " + i + " to " + (i-topIndex));
4219                TaskRecord cur = mRecentTasks.remove(i);
4220                mRecentTasks.add(i-topIndex, cur);
4221            }
4222            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4223                    + " to " + endIndex);
4224            return true;
4225        }
4226
4227        // Whoops, couldn't do it.
4228        return false;
4229    }
4230
4231    final void addRecentTaskLocked(TaskRecord task) {
4232        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4233                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4234
4235        int N = mRecentTasks.size();
4236        // Quick case: check if the top-most recent task is the same.
4237        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4238            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4239            return;
4240        }
4241        // Another quick case: check if this is part of a set of affiliated
4242        // tasks that are at the top.
4243        if (isAffiliated && N > 0 && task.inRecents
4244                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4245            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4246                    + " at top when adding " + task);
4247            return;
4248        }
4249        // Another quick case: never add voice sessions.
4250        if (task.voiceSession != null) {
4251            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4252            return;
4253        }
4254
4255        boolean needAffiliationFix = false;
4256
4257        // Slightly less quick case: the task is already in recents, so all we need
4258        // to do is move it.
4259        if (task.inRecents) {
4260            int taskIndex = mRecentTasks.indexOf(task);
4261            if (taskIndex >= 0) {
4262                if (!isAffiliated) {
4263                    // Simple case: this is not an affiliated task, so we just move it to the front.
4264                    mRecentTasks.remove(taskIndex);
4265                    mRecentTasks.add(0, task);
4266                    notifyTaskPersisterLocked(task, false);
4267                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4268                            + " from " + taskIndex);
4269                    return;
4270                } else {
4271                    // More complicated: need to keep all affiliated tasks together.
4272                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4273                        // All went well.
4274                        return;
4275                    }
4276
4277                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4278                    // everything and then go through our general path of adding a new task.
4279                    needAffiliationFix = true;
4280                }
4281            } else {
4282                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4283                needAffiliationFix = true;
4284            }
4285        }
4286
4287        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4288        trimRecentsForTask(task, true);
4289
4290        N = mRecentTasks.size();
4291        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4292            final TaskRecord tr = mRecentTasks.remove(N - 1);
4293            tr.removedFromRecents(mTaskPersister);
4294            N--;
4295        }
4296        task.inRecents = true;
4297        if (!isAffiliated || needAffiliationFix) {
4298            // If this is a simple non-affiliated task, or we had some failure trying to
4299            // handle it as part of an affilated task, then just place it at the top.
4300            mRecentTasks.add(0, task);
4301        } else if (isAffiliated) {
4302            // If this is a new affiliated task, then move all of the affiliated tasks
4303            // to the front and insert this new one.
4304            TaskRecord other = task.mNextAffiliate;
4305            if (other == null) {
4306                other = task.mPrevAffiliate;
4307            }
4308            if (other != null) {
4309                int otherIndex = mRecentTasks.indexOf(other);
4310                if (otherIndex >= 0) {
4311                    // Insert new task at appropriate location.
4312                    int taskIndex;
4313                    if (other == task.mNextAffiliate) {
4314                        // We found the index of our next affiliation, which is who is
4315                        // before us in the list, so add after that point.
4316                        taskIndex = otherIndex+1;
4317                    } else {
4318                        // We found the index of our previous affiliation, which is who is
4319                        // after us in the list, so add at their position.
4320                        taskIndex = otherIndex;
4321                    }
4322                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4323                            + taskIndex + ": " + task);
4324                    mRecentTasks.add(taskIndex, task);
4325
4326                    // Now move everything to the front.
4327                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4328                        // All went well.
4329                        return;
4330                    }
4331
4332                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4333                    // everything and then go through our general path of adding a new task.
4334                    needAffiliationFix = true;
4335                } else {
4336                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4337                            + other);
4338                    needAffiliationFix = true;
4339                }
4340            } else {
4341                if (DEBUG_RECENTS) Slog.d(TAG,
4342                        "addRecent: adding affiliated task without next/prev:" + task);
4343                needAffiliationFix = true;
4344            }
4345        }
4346        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4347
4348        if (needAffiliationFix) {
4349            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4350            cleanupRecentTasksLocked(task.userId);
4351        }
4352    }
4353
4354    /**
4355     * If needed, remove oldest existing entries in recents that are for the same kind
4356     * of task as the given one.
4357     */
4358    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4359        int N = mRecentTasks.size();
4360        final Intent intent = task.intent;
4361        final boolean document = intent != null && intent.isDocument();
4362
4363        int maxRecents = task.maxRecents - 1;
4364        for (int i=0; i<N; i++) {
4365            final TaskRecord tr = mRecentTasks.get(i);
4366            if (task != tr) {
4367                if (task.userId != tr.userId) {
4368                    continue;
4369                }
4370                if (i > MAX_RECENT_BITMAPS) {
4371                    tr.freeLastThumbnail();
4372                }
4373                final Intent trIntent = tr.intent;
4374                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4375                    (intent == null || !intent.filterEquals(trIntent))) {
4376                    continue;
4377                }
4378                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4379                if (document && trIsDocument) {
4380                    // These are the same document activity (not necessarily the same doc).
4381                    if (maxRecents > 0) {
4382                        --maxRecents;
4383                        continue;
4384                    }
4385                    // Hit the maximum number of documents for this task. Fall through
4386                    // and remove this document from recents.
4387                } else if (document || trIsDocument) {
4388                    // Only one of these is a document. Not the droid we're looking for.
4389                    continue;
4390                }
4391            }
4392
4393            if (!doTrim) {
4394                // If the caller is not actually asking for a trim, just tell them we reached
4395                // a point where the trim would happen.
4396                return i;
4397            }
4398
4399            // Either task and tr are the same or, their affinities match or their intents match
4400            // and neither of them is a document, or they are documents using the same activity
4401            // and their maxRecents has been reached.
4402            tr.disposeThumbnail();
4403            mRecentTasks.remove(i);
4404            if (task != tr) {
4405                tr.removedFromRecents(mTaskPersister);
4406            }
4407            i--;
4408            N--;
4409            if (task.intent == null) {
4410                // If the new recent task we are adding is not fully
4411                // specified, then replace it with the existing recent task.
4412                task = tr;
4413            }
4414            notifyTaskPersisterLocked(tr, false);
4415        }
4416
4417        return -1;
4418    }
4419
4420    @Override
4421    public void reportActivityFullyDrawn(IBinder token) {
4422        synchronized (this) {
4423            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4424            if (r == null) {
4425                return;
4426            }
4427            r.reportFullyDrawnLocked();
4428        }
4429    }
4430
4431    @Override
4432    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4433        synchronized (this) {
4434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4435            if (r == null) {
4436                return;
4437            }
4438            final long origId = Binder.clearCallingIdentity();
4439            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4440            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4441                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4442            if (config != null) {
4443                r.frozenBeforeDestroy = true;
4444                if (!updateConfigurationLocked(config, r, false, false)) {
4445                    mStackSupervisor.resumeTopActivitiesLocked();
4446                }
4447            }
4448            Binder.restoreCallingIdentity(origId);
4449        }
4450    }
4451
4452    @Override
4453    public int getRequestedOrientation(IBinder token) {
4454        synchronized (this) {
4455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4456            if (r == null) {
4457                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4458            }
4459            return mWindowManager.getAppOrientation(r.appToken);
4460        }
4461    }
4462
4463    /**
4464     * This is the internal entry point for handling Activity.finish().
4465     *
4466     * @param token The Binder token referencing the Activity we want to finish.
4467     * @param resultCode Result code, if any, from this Activity.
4468     * @param resultData Result data (Intent), if any, from this Activity.
4469     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4470     *            the root Activity in the task.
4471     *
4472     * @return Returns true if the activity successfully finished, or false if it is still running.
4473     */
4474    @Override
4475    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4476            boolean finishTask) {
4477        // Refuse possible leaked file descriptors
4478        if (resultData != null && resultData.hasFileDescriptors() == true) {
4479            throw new IllegalArgumentException("File descriptors passed in Intent");
4480        }
4481
4482        synchronized(this) {
4483            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4484            if (r == null) {
4485                return true;
4486            }
4487            // Keep track of the root activity of the task before we finish it
4488            TaskRecord tr = r.task;
4489            ActivityRecord rootR = tr.getRootActivity();
4490            // Do not allow task to finish in Lock Task mode.
4491            if (tr == mStackSupervisor.mLockTaskModeTask) {
4492                if (rootR == r) {
4493                    mStackSupervisor.showLockTaskToast();
4494                    return false;
4495                }
4496            }
4497            if (mController != null) {
4498                // Find the first activity that is not finishing.
4499                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4500                if (next != null) {
4501                    // ask watcher if this is allowed
4502                    boolean resumeOK = true;
4503                    try {
4504                        resumeOK = mController.activityResuming(next.packageName);
4505                    } catch (RemoteException e) {
4506                        mController = null;
4507                        Watchdog.getInstance().setActivityController(null);
4508                    }
4509
4510                    if (!resumeOK) {
4511                        return false;
4512                    }
4513                }
4514            }
4515            final long origId = Binder.clearCallingIdentity();
4516            try {
4517                boolean res;
4518                if (finishTask && r == rootR) {
4519                    // If requested, remove the task that is associated to this activity only if it
4520                    // was the root activity in the task.  The result code and data is ignored because
4521                    // we don't support returning them across task boundaries.
4522                    res = removeTaskByIdLocked(tr.taskId, 0);
4523                } else {
4524                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4525                            resultData, "app-request", true);
4526                }
4527                return res;
4528            } finally {
4529                Binder.restoreCallingIdentity(origId);
4530            }
4531        }
4532    }
4533
4534    @Override
4535    public final void finishHeavyWeightApp() {
4536        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4537                != PackageManager.PERMISSION_GRANTED) {
4538            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4539                    + Binder.getCallingPid()
4540                    + ", uid=" + Binder.getCallingUid()
4541                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4542            Slog.w(TAG, msg);
4543            throw new SecurityException(msg);
4544        }
4545
4546        synchronized(this) {
4547            if (mHeavyWeightProcess == null) {
4548                return;
4549            }
4550
4551            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4552                    mHeavyWeightProcess.activities);
4553            for (int i=0; i<activities.size(); i++) {
4554                ActivityRecord r = activities.get(i);
4555                if (!r.finishing) {
4556                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4557                            null, "finish-heavy", true);
4558                }
4559            }
4560
4561            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4562                    mHeavyWeightProcess.userId, 0));
4563            mHeavyWeightProcess = null;
4564        }
4565    }
4566
4567    @Override
4568    public void crashApplication(int uid, int initialPid, String packageName,
4569            String message) {
4570        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4571                != PackageManager.PERMISSION_GRANTED) {
4572            String msg = "Permission Denial: crashApplication() from pid="
4573                    + Binder.getCallingPid()
4574                    + ", uid=" + Binder.getCallingUid()
4575                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4576            Slog.w(TAG, msg);
4577            throw new SecurityException(msg);
4578        }
4579
4580        synchronized(this) {
4581            ProcessRecord proc = null;
4582
4583            // Figure out which process to kill.  We don't trust that initialPid
4584            // still has any relation to current pids, so must scan through the
4585            // list.
4586            synchronized (mPidsSelfLocked) {
4587                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4588                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4589                    if (p.uid != uid) {
4590                        continue;
4591                    }
4592                    if (p.pid == initialPid) {
4593                        proc = p;
4594                        break;
4595                    }
4596                    if (p.pkgList.containsKey(packageName)) {
4597                        proc = p;
4598                    }
4599                }
4600            }
4601
4602            if (proc == null) {
4603                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4604                        + " initialPid=" + initialPid
4605                        + " packageName=" + packageName);
4606                return;
4607            }
4608
4609            if (proc.thread != null) {
4610                if (proc.pid == Process.myPid()) {
4611                    Log.w(TAG, "crashApplication: trying to crash self!");
4612                    return;
4613                }
4614                long ident = Binder.clearCallingIdentity();
4615                try {
4616                    proc.thread.scheduleCrash(message);
4617                } catch (RemoteException e) {
4618                }
4619                Binder.restoreCallingIdentity(ident);
4620            }
4621        }
4622    }
4623
4624    @Override
4625    public final void finishSubActivity(IBinder token, String resultWho,
4626            int requestCode) {
4627        synchronized(this) {
4628            final long origId = Binder.clearCallingIdentity();
4629            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4630            if (r != null) {
4631                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4632            }
4633            Binder.restoreCallingIdentity(origId);
4634        }
4635    }
4636
4637    @Override
4638    public boolean finishActivityAffinity(IBinder token) {
4639        synchronized(this) {
4640            final long origId = Binder.clearCallingIdentity();
4641            try {
4642                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4643
4644                ActivityRecord rootR = r.task.getRootActivity();
4645                // Do not allow task to finish in Lock Task mode.
4646                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4647                    if (rootR == r) {
4648                        mStackSupervisor.showLockTaskToast();
4649                        return false;
4650                    }
4651                }
4652                boolean res = false;
4653                if (r != null) {
4654                    res = r.task.stack.finishActivityAffinityLocked(r);
4655                }
4656                return res;
4657            } finally {
4658                Binder.restoreCallingIdentity(origId);
4659            }
4660        }
4661    }
4662
4663    @Override
4664    public void finishVoiceTask(IVoiceInteractionSession session) {
4665        synchronized(this) {
4666            final long origId = Binder.clearCallingIdentity();
4667            try {
4668                mStackSupervisor.finishVoiceTask(session);
4669            } finally {
4670                Binder.restoreCallingIdentity(origId);
4671            }
4672        }
4673
4674    }
4675
4676    @Override
4677    public boolean releaseActivityInstance(IBinder token) {
4678        synchronized(this) {
4679            final long origId = Binder.clearCallingIdentity();
4680            try {
4681                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4682                if (r.task == null || r.task.stack == null) {
4683                    return false;
4684                }
4685                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4686            } finally {
4687                Binder.restoreCallingIdentity(origId);
4688            }
4689        }
4690    }
4691
4692    @Override
4693    public void releaseSomeActivities(IApplicationThread appInt) {
4694        synchronized(this) {
4695            final long origId = Binder.clearCallingIdentity();
4696            try {
4697                ProcessRecord app = getRecordForAppLocked(appInt);
4698                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4699            } finally {
4700                Binder.restoreCallingIdentity(origId);
4701            }
4702        }
4703    }
4704
4705    @Override
4706    public boolean willActivityBeVisible(IBinder token) {
4707        synchronized(this) {
4708            ActivityStack stack = ActivityRecord.getStackLocked(token);
4709            if (stack != null) {
4710                return stack.willActivityBeVisibleLocked(token);
4711            }
4712            return false;
4713        }
4714    }
4715
4716    @Override
4717    public void overridePendingTransition(IBinder token, String packageName,
4718            int enterAnim, int exitAnim) {
4719        synchronized(this) {
4720            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4721            if (self == null) {
4722                return;
4723            }
4724
4725            final long origId = Binder.clearCallingIdentity();
4726
4727            if (self.state == ActivityState.RESUMED
4728                    || self.state == ActivityState.PAUSING) {
4729                mWindowManager.overridePendingAppTransition(packageName,
4730                        enterAnim, exitAnim, null);
4731            }
4732
4733            Binder.restoreCallingIdentity(origId);
4734        }
4735    }
4736
4737    /**
4738     * Main function for removing an existing process from the activity manager
4739     * as a result of that process going away.  Clears out all connections
4740     * to the process.
4741     */
4742    private final void handleAppDiedLocked(ProcessRecord app,
4743            boolean restarting, boolean allowRestart) {
4744        int pid = app.pid;
4745        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4746        if (!kept && !restarting) {
4747            removeLruProcessLocked(app);
4748            if (pid > 0) {
4749                ProcessList.remove(pid);
4750            }
4751        }
4752
4753        if (mProfileProc == app) {
4754            clearProfilerLocked();
4755        }
4756
4757        // Remove this application's activities from active lists.
4758        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4759
4760        app.activities.clear();
4761
4762        if (app.instrumentationClass != null) {
4763            Slog.w(TAG, "Crash of app " + app.processName
4764                  + " running instrumentation " + app.instrumentationClass);
4765            Bundle info = new Bundle();
4766            info.putString("shortMsg", "Process crashed.");
4767            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4768        }
4769
4770        if (!restarting) {
4771            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4772                // If there was nothing to resume, and we are not already
4773                // restarting this process, but there is a visible activity that
4774                // is hosted by the process...  then make sure all visible
4775                // activities are running, taking care of restarting this
4776                // process.
4777                if (hasVisibleActivities) {
4778                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4779                }
4780            }
4781        }
4782    }
4783
4784    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4785        IBinder threadBinder = thread.asBinder();
4786        // Find the application record.
4787        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4788            ProcessRecord rec = mLruProcesses.get(i);
4789            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4790                return i;
4791            }
4792        }
4793        return -1;
4794    }
4795
4796    final ProcessRecord getRecordForAppLocked(
4797            IApplicationThread thread) {
4798        if (thread == null) {
4799            return null;
4800        }
4801
4802        int appIndex = getLRURecordIndexForAppLocked(thread);
4803        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4804    }
4805
4806    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4807        // If there are no longer any background processes running,
4808        // and the app that died was not running instrumentation,
4809        // then tell everyone we are now low on memory.
4810        boolean haveBg = false;
4811        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4812            ProcessRecord rec = mLruProcesses.get(i);
4813            if (rec.thread != null
4814                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4815                haveBg = true;
4816                break;
4817            }
4818        }
4819
4820        if (!haveBg) {
4821            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4822            if (doReport) {
4823                long now = SystemClock.uptimeMillis();
4824                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4825                    doReport = false;
4826                } else {
4827                    mLastMemUsageReportTime = now;
4828                }
4829            }
4830            final ArrayList<ProcessMemInfo> memInfos
4831                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4832            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4833            long now = SystemClock.uptimeMillis();
4834            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4835                ProcessRecord rec = mLruProcesses.get(i);
4836                if (rec == dyingProc || rec.thread == null) {
4837                    continue;
4838                }
4839                if (doReport) {
4840                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4841                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4842                }
4843                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4844                    // The low memory report is overriding any current
4845                    // state for a GC request.  Make sure to do
4846                    // heavy/important/visible/foreground processes first.
4847                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4848                        rec.lastRequestedGc = 0;
4849                    } else {
4850                        rec.lastRequestedGc = rec.lastLowMemory;
4851                    }
4852                    rec.reportLowMemory = true;
4853                    rec.lastLowMemory = now;
4854                    mProcessesToGc.remove(rec);
4855                    addProcessToGcListLocked(rec);
4856                }
4857            }
4858            if (doReport) {
4859                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4860                mHandler.sendMessage(msg);
4861            }
4862            scheduleAppGcsLocked();
4863        }
4864    }
4865
4866    final void appDiedLocked(ProcessRecord app) {
4867       appDiedLocked(app, app.pid, app.thread);
4868    }
4869
4870    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4871        // First check if this ProcessRecord is actually active for the pid.
4872        synchronized (mPidsSelfLocked) {
4873            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4874            if (curProc != app) {
4875                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4876                return;
4877            }
4878        }
4879
4880        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4881        synchronized (stats) {
4882            stats.noteProcessDiedLocked(app.info.uid, pid);
4883        }
4884
4885        if (!app.killed) {
4886            Process.killProcessQuiet(pid);
4887            Process.killProcessGroup(app.info.uid, pid);
4888            app.killed = true;
4889        }
4890
4891        // Clean up already done if the process has been re-started.
4892        if (app.pid == pid && app.thread != null &&
4893                app.thread.asBinder() == thread.asBinder()) {
4894            boolean doLowMem = app.instrumentationClass == null;
4895            boolean doOomAdj = doLowMem;
4896            if (!app.killedByAm) {
4897                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4898                        + ") has died");
4899                mAllowLowerMemLevel = true;
4900            } else {
4901                // Note that we always want to do oom adj to update our state with the
4902                // new number of procs.
4903                mAllowLowerMemLevel = false;
4904                doLowMem = false;
4905            }
4906            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4907            if (DEBUG_CLEANUP) Slog.v(
4908                TAG, "Dying app: " + app + ", pid: " + pid
4909                + ", thread: " + thread.asBinder());
4910            handleAppDiedLocked(app, false, true);
4911
4912            if (doOomAdj) {
4913                updateOomAdjLocked();
4914            }
4915            if (doLowMem) {
4916                doLowMemReportIfNeededLocked(app);
4917            }
4918        } else if (app.pid != pid) {
4919            // A new process has already been started.
4920            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4921                    + ") has died and restarted (pid " + app.pid + ").");
4922            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4923        } else if (DEBUG_PROCESSES) {
4924            Slog.d(TAG, "Received spurious death notification for thread "
4925                    + thread.asBinder());
4926        }
4927    }
4928
4929    /**
4930     * If a stack trace dump file is configured, dump process stack traces.
4931     * @param clearTraces causes the dump file to be erased prior to the new
4932     *    traces being written, if true; when false, the new traces will be
4933     *    appended to any existing file content.
4934     * @param firstPids of dalvik VM processes to dump stack traces for first
4935     * @param lastPids of dalvik VM processes to dump stack traces for last
4936     * @param nativeProcs optional list of native process names to dump stack crawls
4937     * @return file containing stack traces, or null if no dump file is configured
4938     */
4939    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4940            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4941        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4942        if (tracesPath == null || tracesPath.length() == 0) {
4943            return null;
4944        }
4945
4946        File tracesFile = new File(tracesPath);
4947        try {
4948            File tracesDir = tracesFile.getParentFile();
4949            if (!tracesDir.exists()) {
4950                tracesDir.mkdirs();
4951                if (!SELinux.restorecon(tracesDir)) {
4952                    return null;
4953                }
4954            }
4955            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4956
4957            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4958            tracesFile.createNewFile();
4959            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4960        } catch (IOException e) {
4961            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4962            return null;
4963        }
4964
4965        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4966        return tracesFile;
4967    }
4968
4969    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4970            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4971        // Use a FileObserver to detect when traces finish writing.
4972        // The order of traces is considered important to maintain for legibility.
4973        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4974            @Override
4975            public synchronized void onEvent(int event, String path) { notify(); }
4976        };
4977
4978        try {
4979            observer.startWatching();
4980
4981            // First collect all of the stacks of the most important pids.
4982            if (firstPids != null) {
4983                try {
4984                    int num = firstPids.size();
4985                    for (int i = 0; i < num; i++) {
4986                        synchronized (observer) {
4987                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4988                            observer.wait(200);  // Wait for write-close, give up after 200msec
4989                        }
4990                    }
4991                } catch (InterruptedException e) {
4992                    Slog.wtf(TAG, e);
4993                }
4994            }
4995
4996            // Next collect the stacks of the native pids
4997            if (nativeProcs != null) {
4998                int[] pids = Process.getPidsForCommands(nativeProcs);
4999                if (pids != null) {
5000                    for (int pid : pids) {
5001                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5002                    }
5003                }
5004            }
5005
5006            // Lastly, measure CPU usage.
5007            if (processCpuTracker != null) {
5008                processCpuTracker.init();
5009                System.gc();
5010                processCpuTracker.update();
5011                try {
5012                    synchronized (processCpuTracker) {
5013                        processCpuTracker.wait(500); // measure over 1/2 second.
5014                    }
5015                } catch (InterruptedException e) {
5016                }
5017                processCpuTracker.update();
5018
5019                // We'll take the stack crawls of just the top apps using CPU.
5020                final int N = processCpuTracker.countWorkingStats();
5021                int numProcs = 0;
5022                for (int i=0; i<N && numProcs<5; i++) {
5023                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5024                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5025                        numProcs++;
5026                        try {
5027                            synchronized (observer) {
5028                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5029                                observer.wait(200);  // Wait for write-close, give up after 200msec
5030                            }
5031                        } catch (InterruptedException e) {
5032                            Slog.wtf(TAG, e);
5033                        }
5034
5035                    }
5036                }
5037            }
5038        } finally {
5039            observer.stopWatching();
5040        }
5041    }
5042
5043    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5044        if (true || IS_USER_BUILD) {
5045            return;
5046        }
5047        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5048        if (tracesPath == null || tracesPath.length() == 0) {
5049            return;
5050        }
5051
5052        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5053        StrictMode.allowThreadDiskWrites();
5054        try {
5055            final File tracesFile = new File(tracesPath);
5056            final File tracesDir = tracesFile.getParentFile();
5057            final File tracesTmp = new File(tracesDir, "__tmp__");
5058            try {
5059                if (!tracesDir.exists()) {
5060                    tracesDir.mkdirs();
5061                    if (!SELinux.restorecon(tracesDir.getPath())) {
5062                        return;
5063                    }
5064                }
5065                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5066
5067                if (tracesFile.exists()) {
5068                    tracesTmp.delete();
5069                    tracesFile.renameTo(tracesTmp);
5070                }
5071                StringBuilder sb = new StringBuilder();
5072                Time tobj = new Time();
5073                tobj.set(System.currentTimeMillis());
5074                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5075                sb.append(": ");
5076                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5077                sb.append(" since ");
5078                sb.append(msg);
5079                FileOutputStream fos = new FileOutputStream(tracesFile);
5080                fos.write(sb.toString().getBytes());
5081                if (app == null) {
5082                    fos.write("\n*** No application process!".getBytes());
5083                }
5084                fos.close();
5085                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5086            } catch (IOException e) {
5087                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5088                return;
5089            }
5090
5091            if (app != null) {
5092                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5093                firstPids.add(app.pid);
5094                dumpStackTraces(tracesPath, firstPids, null, null, null);
5095            }
5096
5097            File lastTracesFile = null;
5098            File curTracesFile = null;
5099            for (int i=9; i>=0; i--) {
5100                String name = String.format(Locale.US, "slow%02d.txt", i);
5101                curTracesFile = new File(tracesDir, name);
5102                if (curTracesFile.exists()) {
5103                    if (lastTracesFile != null) {
5104                        curTracesFile.renameTo(lastTracesFile);
5105                    } else {
5106                        curTracesFile.delete();
5107                    }
5108                }
5109                lastTracesFile = curTracesFile;
5110            }
5111            tracesFile.renameTo(curTracesFile);
5112            if (tracesTmp.exists()) {
5113                tracesTmp.renameTo(tracesFile);
5114            }
5115        } finally {
5116            StrictMode.setThreadPolicy(oldPolicy);
5117        }
5118    }
5119
5120    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5121            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5122        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5123        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5124
5125        if (mController != null) {
5126            try {
5127                // 0 == continue, -1 = kill process immediately
5128                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5129                if (res < 0 && app.pid != MY_PID) {
5130                    app.kill("anr", true);
5131                }
5132            } catch (RemoteException e) {
5133                mController = null;
5134                Watchdog.getInstance().setActivityController(null);
5135            }
5136        }
5137
5138        long anrTime = SystemClock.uptimeMillis();
5139        if (MONITOR_CPU_USAGE) {
5140            updateCpuStatsNow();
5141        }
5142
5143        synchronized (this) {
5144            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5145            if (mShuttingDown) {
5146                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5147                return;
5148            } else if (app.notResponding) {
5149                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5150                return;
5151            } else if (app.crashing) {
5152                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5153                return;
5154            }
5155
5156            // In case we come through here for the same app before completing
5157            // this one, mark as anring now so we will bail out.
5158            app.notResponding = true;
5159
5160            // Log the ANR to the event log.
5161            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5162                    app.processName, app.info.flags, annotation);
5163
5164            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5165            firstPids.add(app.pid);
5166
5167            int parentPid = app.pid;
5168            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5169            if (parentPid != app.pid) firstPids.add(parentPid);
5170
5171            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5172
5173            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5174                ProcessRecord r = mLruProcesses.get(i);
5175                if (r != null && r.thread != null) {
5176                    int pid = r.pid;
5177                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5178                        if (r.persistent) {
5179                            firstPids.add(pid);
5180                        } else {
5181                            lastPids.put(pid, Boolean.TRUE);
5182                        }
5183                    }
5184                }
5185            }
5186        }
5187
5188        // Log the ANR to the main log.
5189        StringBuilder info = new StringBuilder();
5190        info.setLength(0);
5191        info.append("ANR in ").append(app.processName);
5192        if (activity != null && activity.shortComponentName != null) {
5193            info.append(" (").append(activity.shortComponentName).append(")");
5194        }
5195        info.append("\n");
5196        info.append("PID: ").append(app.pid).append("\n");
5197        if (annotation != null) {
5198            info.append("Reason: ").append(annotation).append("\n");
5199        }
5200        if (parent != null && parent != activity) {
5201            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5202        }
5203
5204        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5205
5206        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5207                NATIVE_STACKS_OF_INTEREST);
5208
5209        String cpuInfo = null;
5210        if (MONITOR_CPU_USAGE) {
5211            updateCpuStatsNow();
5212            synchronized (mProcessCpuTracker) {
5213                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5214            }
5215            info.append(processCpuTracker.printCurrentLoad());
5216            info.append(cpuInfo);
5217        }
5218
5219        info.append(processCpuTracker.printCurrentState(anrTime));
5220
5221        Slog.e(TAG, info.toString());
5222        if (tracesFile == null) {
5223            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5224            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5225        }
5226
5227        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5228                cpuInfo, tracesFile, null);
5229
5230        if (mController != null) {
5231            try {
5232                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5233                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5234                if (res != 0) {
5235                    if (res < 0 && app.pid != MY_PID) {
5236                        app.kill("anr", true);
5237                    } else {
5238                        synchronized (this) {
5239                            mServices.scheduleServiceTimeoutLocked(app);
5240                        }
5241                    }
5242                    return;
5243                }
5244            } catch (RemoteException e) {
5245                mController = null;
5246                Watchdog.getInstance().setActivityController(null);
5247            }
5248        }
5249
5250        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5251        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5252                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5253
5254        synchronized (this) {
5255            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5256                app.kill("bg anr", true);
5257                return;
5258            }
5259
5260            // Set the app's notResponding state, and look up the errorReportReceiver
5261            makeAppNotRespondingLocked(app,
5262                    activity != null ? activity.shortComponentName : null,
5263                    annotation != null ? "ANR " + annotation : "ANR",
5264                    info.toString());
5265
5266            // Bring up the infamous App Not Responding dialog
5267            Message msg = Message.obtain();
5268            HashMap<String, Object> map = new HashMap<String, Object>();
5269            msg.what = SHOW_NOT_RESPONDING_MSG;
5270            msg.obj = map;
5271            msg.arg1 = aboveSystem ? 1 : 0;
5272            map.put("app", app);
5273            if (activity != null) {
5274                map.put("activity", activity);
5275            }
5276
5277            mHandler.sendMessage(msg);
5278        }
5279    }
5280
5281    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5282        if (!mLaunchWarningShown) {
5283            mLaunchWarningShown = true;
5284            mHandler.post(new Runnable() {
5285                @Override
5286                public void run() {
5287                    synchronized (ActivityManagerService.this) {
5288                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5289                        d.show();
5290                        mHandler.postDelayed(new Runnable() {
5291                            @Override
5292                            public void run() {
5293                                synchronized (ActivityManagerService.this) {
5294                                    d.dismiss();
5295                                    mLaunchWarningShown = false;
5296                                }
5297                            }
5298                        }, 4000);
5299                    }
5300                }
5301            });
5302        }
5303    }
5304
5305    @Override
5306    public boolean clearApplicationUserData(final String packageName,
5307            final IPackageDataObserver observer, int userId) {
5308        enforceNotIsolatedCaller("clearApplicationUserData");
5309        int uid = Binder.getCallingUid();
5310        int pid = Binder.getCallingPid();
5311        userId = handleIncomingUser(pid, uid,
5312                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5313        long callingId = Binder.clearCallingIdentity();
5314        try {
5315            IPackageManager pm = AppGlobals.getPackageManager();
5316            int pkgUid = -1;
5317            synchronized(this) {
5318                try {
5319                    pkgUid = pm.getPackageUid(packageName, userId);
5320                } catch (RemoteException e) {
5321                }
5322                if (pkgUid == -1) {
5323                    Slog.w(TAG, "Invalid packageName: " + packageName);
5324                    if (observer != null) {
5325                        try {
5326                            observer.onRemoveCompleted(packageName, false);
5327                        } catch (RemoteException e) {
5328                            Slog.i(TAG, "Observer no longer exists.");
5329                        }
5330                    }
5331                    return false;
5332                }
5333                if (uid == pkgUid || checkComponentPermission(
5334                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5335                        pid, uid, -1, true)
5336                        == PackageManager.PERMISSION_GRANTED) {
5337                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5338                } else {
5339                    throw new SecurityException("PID " + pid + " does not have permission "
5340                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5341                                    + " of package " + packageName);
5342                }
5343
5344                // Remove all tasks match the cleared application package and user
5345                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5346                    final TaskRecord tr = mRecentTasks.get(i);
5347                    final String taskPackageName =
5348                            tr.getBaseIntent().getComponent().getPackageName();
5349                    if (tr.userId != userId) continue;
5350                    if (!taskPackageName.equals(packageName)) continue;
5351                    removeTaskByIdLocked(tr.taskId, 0);
5352                }
5353            }
5354
5355            try {
5356                // Clear application user data
5357                pm.clearApplicationUserData(packageName, observer, userId);
5358
5359                synchronized(this) {
5360                    // Remove all permissions granted from/to this package
5361                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5362                }
5363
5364                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5365                        Uri.fromParts("package", packageName, null));
5366                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5367                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5368                        null, null, 0, null, null, null, false, false, userId);
5369            } catch (RemoteException e) {
5370            }
5371        } finally {
5372            Binder.restoreCallingIdentity(callingId);
5373        }
5374        return true;
5375    }
5376
5377    @Override
5378    public void killBackgroundProcesses(final String packageName, int userId) {
5379        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5380                != PackageManager.PERMISSION_GRANTED &&
5381                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5382                        != PackageManager.PERMISSION_GRANTED) {
5383            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5384                    + Binder.getCallingPid()
5385                    + ", uid=" + Binder.getCallingUid()
5386                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5387            Slog.w(TAG, msg);
5388            throw new SecurityException(msg);
5389        }
5390
5391        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5392                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5393        long callingId = Binder.clearCallingIdentity();
5394        try {
5395            IPackageManager pm = AppGlobals.getPackageManager();
5396            synchronized(this) {
5397                int appId = -1;
5398                try {
5399                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5400                } catch (RemoteException e) {
5401                }
5402                if (appId == -1) {
5403                    Slog.w(TAG, "Invalid packageName: " + packageName);
5404                    return;
5405                }
5406                killPackageProcessesLocked(packageName, appId, userId,
5407                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5408            }
5409        } finally {
5410            Binder.restoreCallingIdentity(callingId);
5411        }
5412    }
5413
5414    @Override
5415    public void killAllBackgroundProcesses() {
5416        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5417                != PackageManager.PERMISSION_GRANTED) {
5418            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5419                    + Binder.getCallingPid()
5420                    + ", uid=" + Binder.getCallingUid()
5421                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5422            Slog.w(TAG, msg);
5423            throw new SecurityException(msg);
5424        }
5425
5426        long callingId = Binder.clearCallingIdentity();
5427        try {
5428            synchronized(this) {
5429                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5430                final int NP = mProcessNames.getMap().size();
5431                for (int ip=0; ip<NP; ip++) {
5432                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5433                    final int NA = apps.size();
5434                    for (int ia=0; ia<NA; ia++) {
5435                        ProcessRecord app = apps.valueAt(ia);
5436                        if (app.persistent) {
5437                            // we don't kill persistent processes
5438                            continue;
5439                        }
5440                        if (app.removed) {
5441                            procs.add(app);
5442                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5443                            app.removed = true;
5444                            procs.add(app);
5445                        }
5446                    }
5447                }
5448
5449                int N = procs.size();
5450                for (int i=0; i<N; i++) {
5451                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5452                }
5453                mAllowLowerMemLevel = true;
5454                updateOomAdjLocked();
5455                doLowMemReportIfNeededLocked(null);
5456            }
5457        } finally {
5458            Binder.restoreCallingIdentity(callingId);
5459        }
5460    }
5461
5462    @Override
5463    public void forceStopPackage(final String packageName, int userId) {
5464        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5465                != PackageManager.PERMISSION_GRANTED) {
5466            String msg = "Permission Denial: forceStopPackage() from pid="
5467                    + Binder.getCallingPid()
5468                    + ", uid=" + Binder.getCallingUid()
5469                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5470            Slog.w(TAG, msg);
5471            throw new SecurityException(msg);
5472        }
5473        final int callingPid = Binder.getCallingPid();
5474        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5475                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5476        long callingId = Binder.clearCallingIdentity();
5477        try {
5478            IPackageManager pm = AppGlobals.getPackageManager();
5479            synchronized(this) {
5480                int[] users = userId == UserHandle.USER_ALL
5481                        ? getUsersLocked() : new int[] { userId };
5482                for (int user : users) {
5483                    int pkgUid = -1;
5484                    try {
5485                        pkgUid = pm.getPackageUid(packageName, user);
5486                    } catch (RemoteException e) {
5487                    }
5488                    if (pkgUid == -1) {
5489                        Slog.w(TAG, "Invalid packageName: " + packageName);
5490                        continue;
5491                    }
5492                    try {
5493                        pm.setPackageStoppedState(packageName, true, user);
5494                    } catch (RemoteException e) {
5495                    } catch (IllegalArgumentException e) {
5496                        Slog.w(TAG, "Failed trying to unstop package "
5497                                + packageName + ": " + e);
5498                    }
5499                    if (isUserRunningLocked(user, false)) {
5500                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5501                    }
5502                }
5503            }
5504        } finally {
5505            Binder.restoreCallingIdentity(callingId);
5506        }
5507    }
5508
5509    @Override
5510    public void addPackageDependency(String packageName) {
5511        synchronized (this) {
5512            int callingPid = Binder.getCallingPid();
5513            if (callingPid == Process.myPid()) {
5514                //  Yeah, um, no.
5515                Slog.w(TAG, "Can't addPackageDependency on system process");
5516                return;
5517            }
5518            ProcessRecord proc;
5519            synchronized (mPidsSelfLocked) {
5520                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5521            }
5522            if (proc != null) {
5523                if (proc.pkgDeps == null) {
5524                    proc.pkgDeps = new ArraySet<String>(1);
5525                }
5526                proc.pkgDeps.add(packageName);
5527            }
5528        }
5529    }
5530
5531    /*
5532     * The pkg name and app id have to be specified.
5533     */
5534    @Override
5535    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5536        if (pkg == null) {
5537            return;
5538        }
5539        // Make sure the uid is valid.
5540        if (appid < 0) {
5541            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5542            return;
5543        }
5544        int callerUid = Binder.getCallingUid();
5545        // Only the system server can kill an application
5546        if (callerUid == Process.SYSTEM_UID) {
5547            // Post an aysnc message to kill the application
5548            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5549            msg.arg1 = appid;
5550            msg.arg2 = 0;
5551            Bundle bundle = new Bundle();
5552            bundle.putString("pkg", pkg);
5553            bundle.putString("reason", reason);
5554            msg.obj = bundle;
5555            mHandler.sendMessage(msg);
5556        } else {
5557            throw new SecurityException(callerUid + " cannot kill pkg: " +
5558                    pkg);
5559        }
5560    }
5561
5562    @Override
5563    public void closeSystemDialogs(String reason) {
5564        enforceNotIsolatedCaller("closeSystemDialogs");
5565
5566        final int pid = Binder.getCallingPid();
5567        final int uid = Binder.getCallingUid();
5568        final long origId = Binder.clearCallingIdentity();
5569        try {
5570            synchronized (this) {
5571                // Only allow this from foreground processes, so that background
5572                // applications can't abuse it to prevent system UI from being shown.
5573                if (uid >= Process.FIRST_APPLICATION_UID) {
5574                    ProcessRecord proc;
5575                    synchronized (mPidsSelfLocked) {
5576                        proc = mPidsSelfLocked.get(pid);
5577                    }
5578                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5579                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5580                                + " from background process " + proc);
5581                        return;
5582                    }
5583                }
5584                closeSystemDialogsLocked(reason);
5585            }
5586        } finally {
5587            Binder.restoreCallingIdentity(origId);
5588        }
5589    }
5590
5591    void closeSystemDialogsLocked(String reason) {
5592        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5593        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5594                | Intent.FLAG_RECEIVER_FOREGROUND);
5595        if (reason != null) {
5596            intent.putExtra("reason", reason);
5597        }
5598        mWindowManager.closeSystemDialogs(reason);
5599
5600        mStackSupervisor.closeSystemDialogsLocked();
5601
5602        broadcastIntentLocked(null, null, intent, null,
5603                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5604                Process.SYSTEM_UID, UserHandle.USER_ALL);
5605    }
5606
5607    @Override
5608    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5609        enforceNotIsolatedCaller("getProcessMemoryInfo");
5610        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5611        for (int i=pids.length-1; i>=0; i--) {
5612            ProcessRecord proc;
5613            int oomAdj;
5614            synchronized (this) {
5615                synchronized (mPidsSelfLocked) {
5616                    proc = mPidsSelfLocked.get(pids[i]);
5617                    oomAdj = proc != null ? proc.setAdj : 0;
5618                }
5619            }
5620            infos[i] = new Debug.MemoryInfo();
5621            Debug.getMemoryInfo(pids[i], infos[i]);
5622            if (proc != null) {
5623                synchronized (this) {
5624                    if (proc.thread != null && proc.setAdj == oomAdj) {
5625                        // Record this for posterity if the process has been stable.
5626                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5627                                infos[i].getTotalUss(), false, proc.pkgList);
5628                    }
5629                }
5630            }
5631        }
5632        return infos;
5633    }
5634
5635    @Override
5636    public long[] getProcessPss(int[] pids) {
5637        enforceNotIsolatedCaller("getProcessPss");
5638        long[] pss = new long[pids.length];
5639        for (int i=pids.length-1; i>=0; i--) {
5640            ProcessRecord proc;
5641            int oomAdj;
5642            synchronized (this) {
5643                synchronized (mPidsSelfLocked) {
5644                    proc = mPidsSelfLocked.get(pids[i]);
5645                    oomAdj = proc != null ? proc.setAdj : 0;
5646                }
5647            }
5648            long[] tmpUss = new long[1];
5649            pss[i] = Debug.getPss(pids[i], tmpUss);
5650            if (proc != null) {
5651                synchronized (this) {
5652                    if (proc.thread != null && proc.setAdj == oomAdj) {
5653                        // Record this for posterity if the process has been stable.
5654                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5655                    }
5656                }
5657            }
5658        }
5659        return pss;
5660    }
5661
5662    @Override
5663    public void killApplicationProcess(String processName, int uid) {
5664        if (processName == null) {
5665            return;
5666        }
5667
5668        int callerUid = Binder.getCallingUid();
5669        // Only the system server can kill an application
5670        if (callerUid == Process.SYSTEM_UID) {
5671            synchronized (this) {
5672                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5673                if (app != null && app.thread != null) {
5674                    try {
5675                        app.thread.scheduleSuicide();
5676                    } catch (RemoteException e) {
5677                        // If the other end already died, then our work here is done.
5678                    }
5679                } else {
5680                    Slog.w(TAG, "Process/uid not found attempting kill of "
5681                            + processName + " / " + uid);
5682                }
5683            }
5684        } else {
5685            throw new SecurityException(callerUid + " cannot kill app process: " +
5686                    processName);
5687        }
5688    }
5689
5690    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5691        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5692                false, true, false, false, UserHandle.getUserId(uid), reason);
5693        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5694                Uri.fromParts("package", packageName, null));
5695        if (!mProcessesReady) {
5696            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5697                    | Intent.FLAG_RECEIVER_FOREGROUND);
5698        }
5699        intent.putExtra(Intent.EXTRA_UID, uid);
5700        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5701        broadcastIntentLocked(null, null, intent,
5702                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5703                false, false,
5704                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5705    }
5706
5707    private void forceStopUserLocked(int userId, String reason) {
5708        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5709        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5710        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5711                | Intent.FLAG_RECEIVER_FOREGROUND);
5712        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5713        broadcastIntentLocked(null, null, intent,
5714                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5715                false, false,
5716                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5717    }
5718
5719    private final boolean killPackageProcessesLocked(String packageName, int appId,
5720            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5721            boolean doit, boolean evenPersistent, String reason) {
5722        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5723
5724        // Remove all processes this package may have touched: all with the
5725        // same UID (except for the system or root user), and all whose name
5726        // matches the package name.
5727        final int NP = mProcessNames.getMap().size();
5728        for (int ip=0; ip<NP; ip++) {
5729            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5730            final int NA = apps.size();
5731            for (int ia=0; ia<NA; ia++) {
5732                ProcessRecord app = apps.valueAt(ia);
5733                if (app.persistent && !evenPersistent) {
5734                    // we don't kill persistent processes
5735                    continue;
5736                }
5737                if (app.removed) {
5738                    if (doit) {
5739                        procs.add(app);
5740                    }
5741                    continue;
5742                }
5743
5744                // Skip process if it doesn't meet our oom adj requirement.
5745                if (app.setAdj < minOomAdj) {
5746                    continue;
5747                }
5748
5749                // If no package is specified, we call all processes under the
5750                // give user id.
5751                if (packageName == null) {
5752                    if (app.userId != userId) {
5753                        continue;
5754                    }
5755                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5756                        continue;
5757                    }
5758                // Package has been specified, we want to hit all processes
5759                // that match it.  We need to qualify this by the processes
5760                // that are running under the specified app and user ID.
5761                } else {
5762                    final boolean isDep = app.pkgDeps != null
5763                            && app.pkgDeps.contains(packageName);
5764                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5765                        continue;
5766                    }
5767                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5768                        continue;
5769                    }
5770                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5771                        continue;
5772                    }
5773                }
5774
5775                // Process has passed all conditions, kill it!
5776                if (!doit) {
5777                    return true;
5778                }
5779                app.removed = true;
5780                procs.add(app);
5781            }
5782        }
5783
5784        int N = procs.size();
5785        for (int i=0; i<N; i++) {
5786            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5787        }
5788        updateOomAdjLocked();
5789        return N > 0;
5790    }
5791
5792    private final boolean forceStopPackageLocked(String name, int appId,
5793            boolean callerWillRestart, boolean purgeCache, boolean doit,
5794            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5795        int i;
5796        int N;
5797
5798        if (userId == UserHandle.USER_ALL && name == null) {
5799            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5800        }
5801
5802        if (appId < 0 && name != null) {
5803            try {
5804                appId = UserHandle.getAppId(
5805                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5806            } catch (RemoteException e) {
5807            }
5808        }
5809
5810        if (doit) {
5811            if (name != null) {
5812                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5813                        + " user=" + userId + ": " + reason);
5814            } else {
5815                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5816            }
5817
5818            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5819            for (int ip=pmap.size()-1; ip>=0; ip--) {
5820                SparseArray<Long> ba = pmap.valueAt(ip);
5821                for (i=ba.size()-1; i>=0; i--) {
5822                    boolean remove = false;
5823                    final int entUid = ba.keyAt(i);
5824                    if (name != null) {
5825                        if (userId == UserHandle.USER_ALL) {
5826                            if (UserHandle.getAppId(entUid) == appId) {
5827                                remove = true;
5828                            }
5829                        } else {
5830                            if (entUid == UserHandle.getUid(userId, appId)) {
5831                                remove = true;
5832                            }
5833                        }
5834                    } else if (UserHandle.getUserId(entUid) == userId) {
5835                        remove = true;
5836                    }
5837                    if (remove) {
5838                        ba.removeAt(i);
5839                    }
5840                }
5841                if (ba.size() == 0) {
5842                    pmap.removeAt(ip);
5843                }
5844            }
5845        }
5846
5847        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5848                -100, callerWillRestart, true, doit, evenPersistent,
5849                name == null ? ("stop user " + userId) : ("stop " + name));
5850
5851        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5852            if (!doit) {
5853                return true;
5854            }
5855            didSomething = true;
5856        }
5857
5858        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5859            if (!doit) {
5860                return true;
5861            }
5862            didSomething = true;
5863        }
5864
5865        if (name == null) {
5866            // Remove all sticky broadcasts from this user.
5867            mStickyBroadcasts.remove(userId);
5868        }
5869
5870        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5871        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5872                userId, providers)) {
5873            if (!doit) {
5874                return true;
5875            }
5876            didSomething = true;
5877        }
5878        N = providers.size();
5879        for (i=0; i<N; i++) {
5880            removeDyingProviderLocked(null, providers.get(i), true);
5881        }
5882
5883        // Remove transient permissions granted from/to this package/user
5884        removeUriPermissionsForPackageLocked(name, userId, false);
5885
5886        if (name == null || uninstalling) {
5887            // Remove pending intents.  For now we only do this when force
5888            // stopping users, because we have some problems when doing this
5889            // for packages -- app widgets are not currently cleaned up for
5890            // such packages, so they can be left with bad pending intents.
5891            if (mIntentSenderRecords.size() > 0) {
5892                Iterator<WeakReference<PendingIntentRecord>> it
5893                        = mIntentSenderRecords.values().iterator();
5894                while (it.hasNext()) {
5895                    WeakReference<PendingIntentRecord> wpir = it.next();
5896                    if (wpir == null) {
5897                        it.remove();
5898                        continue;
5899                    }
5900                    PendingIntentRecord pir = wpir.get();
5901                    if (pir == null) {
5902                        it.remove();
5903                        continue;
5904                    }
5905                    if (name == null) {
5906                        // Stopping user, remove all objects for the user.
5907                        if (pir.key.userId != userId) {
5908                            // Not the same user, skip it.
5909                            continue;
5910                        }
5911                    } else {
5912                        if (UserHandle.getAppId(pir.uid) != appId) {
5913                            // Different app id, skip it.
5914                            continue;
5915                        }
5916                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5917                            // Different user, skip it.
5918                            continue;
5919                        }
5920                        if (!pir.key.packageName.equals(name)) {
5921                            // Different package, skip it.
5922                            continue;
5923                        }
5924                    }
5925                    if (!doit) {
5926                        return true;
5927                    }
5928                    didSomething = true;
5929                    it.remove();
5930                    pir.canceled = true;
5931                    if (pir.key.activity != null) {
5932                        pir.key.activity.pendingResults.remove(pir.ref);
5933                    }
5934                }
5935            }
5936        }
5937
5938        if (doit) {
5939            if (purgeCache && name != null) {
5940                AttributeCache ac = AttributeCache.instance();
5941                if (ac != null) {
5942                    ac.removePackage(name);
5943                }
5944            }
5945            if (mBooted) {
5946                mStackSupervisor.resumeTopActivitiesLocked();
5947                mStackSupervisor.scheduleIdleLocked();
5948            }
5949        }
5950
5951        return didSomething;
5952    }
5953
5954    private final boolean removeProcessLocked(ProcessRecord app,
5955            boolean callerWillRestart, boolean allowRestart, String reason) {
5956        final String name = app.processName;
5957        final int uid = app.uid;
5958        if (DEBUG_PROCESSES) Slog.d(
5959            TAG, "Force removing proc " + app.toShortString() + " (" + name
5960            + "/" + uid + ")");
5961
5962        mProcessNames.remove(name, uid);
5963        mIsolatedProcesses.remove(app.uid);
5964        if (mHeavyWeightProcess == app) {
5965            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5966                    mHeavyWeightProcess.userId, 0));
5967            mHeavyWeightProcess = null;
5968        }
5969        boolean needRestart = false;
5970        if (app.pid > 0 && app.pid != MY_PID) {
5971            int pid = app.pid;
5972            synchronized (mPidsSelfLocked) {
5973                mPidsSelfLocked.remove(pid);
5974                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5975            }
5976            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5977            if (app.isolated) {
5978                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5979            }
5980            app.kill(reason, true);
5981            handleAppDiedLocked(app, true, allowRestart);
5982            removeLruProcessLocked(app);
5983
5984            if (app.persistent && !app.isolated) {
5985                if (!callerWillRestart) {
5986                    addAppLocked(app.info, false, null /* ABI override */);
5987                } else {
5988                    needRestart = true;
5989                }
5990            }
5991        } else {
5992            mRemovedProcesses.add(app);
5993        }
5994
5995        return needRestart;
5996    }
5997
5998    private final void processStartTimedOutLocked(ProcessRecord app) {
5999        final int pid = app.pid;
6000        boolean gone = false;
6001        synchronized (mPidsSelfLocked) {
6002            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6003            if (knownApp != null && knownApp.thread == null) {
6004                mPidsSelfLocked.remove(pid);
6005                gone = true;
6006            }
6007        }
6008
6009        if (gone) {
6010            Slog.w(TAG, "Process " + app + " failed to attach");
6011            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6012                    pid, app.uid, app.processName);
6013            mProcessNames.remove(app.processName, app.uid);
6014            mIsolatedProcesses.remove(app.uid);
6015            if (mHeavyWeightProcess == app) {
6016                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6017                        mHeavyWeightProcess.userId, 0));
6018                mHeavyWeightProcess = null;
6019            }
6020            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6021            if (app.isolated) {
6022                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6023            }
6024            // Take care of any launching providers waiting for this process.
6025            checkAppInLaunchingProvidersLocked(app, true);
6026            // Take care of any services that are waiting for the process.
6027            mServices.processStartTimedOutLocked(app);
6028            app.kill("start timeout", true);
6029            removeLruProcessLocked(app);
6030            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6031                Slog.w(TAG, "Unattached app died before backup, skipping");
6032                try {
6033                    IBackupManager bm = IBackupManager.Stub.asInterface(
6034                            ServiceManager.getService(Context.BACKUP_SERVICE));
6035                    bm.agentDisconnected(app.info.packageName);
6036                } catch (RemoteException e) {
6037                    // Can't happen; the backup manager is local
6038                }
6039            }
6040            if (isPendingBroadcastProcessLocked(pid)) {
6041                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6042                skipPendingBroadcastLocked(pid);
6043            }
6044        } else {
6045            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6046        }
6047    }
6048
6049    private final boolean attachApplicationLocked(IApplicationThread thread,
6050            int pid) {
6051
6052        // Find the application record that is being attached...  either via
6053        // the pid if we are running in multiple processes, or just pull the
6054        // next app record if we are emulating process with anonymous threads.
6055        ProcessRecord app;
6056        if (pid != MY_PID && pid >= 0) {
6057            synchronized (mPidsSelfLocked) {
6058                app = mPidsSelfLocked.get(pid);
6059            }
6060        } else {
6061            app = null;
6062        }
6063
6064        if (app == null) {
6065            Slog.w(TAG, "No pending application record for pid " + pid
6066                    + " (IApplicationThread " + thread + "); dropping process");
6067            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6068            if (pid > 0 && pid != MY_PID) {
6069                Process.killProcessQuiet(pid);
6070                //TODO: Process.killProcessGroup(app.info.uid, pid);
6071            } else {
6072                try {
6073                    thread.scheduleExit();
6074                } catch (Exception e) {
6075                    // Ignore exceptions.
6076                }
6077            }
6078            return false;
6079        }
6080
6081        // If this application record is still attached to a previous
6082        // process, clean it up now.
6083        if (app.thread != null) {
6084            handleAppDiedLocked(app, true, true);
6085        }
6086
6087        // Tell the process all about itself.
6088
6089        if (localLOGV) Slog.v(
6090                TAG, "Binding process pid " + pid + " to record " + app);
6091
6092        final String processName = app.processName;
6093        try {
6094            AppDeathRecipient adr = new AppDeathRecipient(
6095                    app, pid, thread);
6096            thread.asBinder().linkToDeath(adr, 0);
6097            app.deathRecipient = adr;
6098        } catch (RemoteException e) {
6099            app.resetPackageList(mProcessStats);
6100            startProcessLocked(app, "link fail", processName);
6101            return false;
6102        }
6103
6104        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6105
6106        app.makeActive(thread, mProcessStats);
6107        app.curAdj = app.setAdj = -100;
6108        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6109        app.forcingToForeground = null;
6110        updateProcessForegroundLocked(app, false, false);
6111        app.hasShownUi = false;
6112        app.debugging = false;
6113        app.cached = false;
6114        app.killedByAm = false;
6115
6116        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6117
6118        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6119        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6120
6121        if (!normalMode) {
6122            Slog.i(TAG, "Launching preboot mode app: " + app);
6123        }
6124
6125        if (localLOGV) Slog.v(
6126            TAG, "New app record " + app
6127            + " thread=" + thread.asBinder() + " pid=" + pid);
6128        try {
6129            int testMode = IApplicationThread.DEBUG_OFF;
6130            if (mDebugApp != null && mDebugApp.equals(processName)) {
6131                testMode = mWaitForDebugger
6132                    ? IApplicationThread.DEBUG_WAIT
6133                    : IApplicationThread.DEBUG_ON;
6134                app.debugging = true;
6135                if (mDebugTransient) {
6136                    mDebugApp = mOrigDebugApp;
6137                    mWaitForDebugger = mOrigWaitForDebugger;
6138                }
6139            }
6140            String profileFile = app.instrumentationProfileFile;
6141            ParcelFileDescriptor profileFd = null;
6142            int samplingInterval = 0;
6143            boolean profileAutoStop = false;
6144            if (mProfileApp != null && mProfileApp.equals(processName)) {
6145                mProfileProc = app;
6146                profileFile = mProfileFile;
6147                profileFd = mProfileFd;
6148                samplingInterval = mSamplingInterval;
6149                profileAutoStop = mAutoStopProfiler;
6150            }
6151            boolean enableOpenGlTrace = false;
6152            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6153                enableOpenGlTrace = true;
6154                mOpenGlTraceApp = null;
6155            }
6156
6157            // If the app is being launched for restore or full backup, set it up specially
6158            boolean isRestrictedBackupMode = false;
6159            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6160                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6161                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6162                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6163            }
6164
6165            ensurePackageDexOpt(app.instrumentationInfo != null
6166                    ? app.instrumentationInfo.packageName
6167                    : app.info.packageName);
6168            if (app.instrumentationClass != null) {
6169                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6170            }
6171            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6172                    + processName + " with config " + mConfiguration);
6173            ApplicationInfo appInfo = app.instrumentationInfo != null
6174                    ? app.instrumentationInfo : app.info;
6175            app.compat = compatibilityInfoForPackageLocked(appInfo);
6176            if (profileFd != null) {
6177                profileFd = profileFd.dup();
6178            }
6179            ProfilerInfo profilerInfo = profileFile == null ? null
6180                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6181            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6182                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6183                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6184                    isRestrictedBackupMode || !normalMode, app.persistent,
6185                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6186                    mCoreSettingsObserver.getCoreSettingsLocked());
6187            updateLruProcessLocked(app, false, null);
6188            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6189        } catch (Exception e) {
6190            // todo: Yikes!  What should we do?  For now we will try to
6191            // start another process, but that could easily get us in
6192            // an infinite loop of restarting processes...
6193            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6194
6195            app.resetPackageList(mProcessStats);
6196            app.unlinkDeathRecipient();
6197            startProcessLocked(app, "bind fail", processName);
6198            return false;
6199        }
6200
6201        // Remove this record from the list of starting applications.
6202        mPersistentStartingProcesses.remove(app);
6203        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6204                "Attach application locked removing on hold: " + app);
6205        mProcessesOnHold.remove(app);
6206
6207        boolean badApp = false;
6208        boolean didSomething = false;
6209
6210        // See if the top visible activity is waiting to run in this process...
6211        if (normalMode) {
6212            try {
6213                if (mStackSupervisor.attachApplicationLocked(app)) {
6214                    didSomething = true;
6215                }
6216            } catch (Exception e) {
6217                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6218                badApp = true;
6219            }
6220        }
6221
6222        // Find any services that should be running in this process...
6223        if (!badApp) {
6224            try {
6225                didSomething |= mServices.attachApplicationLocked(app, processName);
6226            } catch (Exception e) {
6227                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6228                badApp = true;
6229            }
6230        }
6231
6232        // Check if a next-broadcast receiver is in this process...
6233        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6234            try {
6235                didSomething |= sendPendingBroadcastsLocked(app);
6236            } catch (Exception e) {
6237                // If the app died trying to launch the receiver we declare it 'bad'
6238                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6239                badApp = true;
6240            }
6241        }
6242
6243        // Check whether the next backup agent is in this process...
6244        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6245            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6246            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6247            try {
6248                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6249                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6250                        mBackupTarget.backupMode);
6251            } catch (Exception e) {
6252                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6253                badApp = true;
6254            }
6255        }
6256
6257        if (badApp) {
6258            app.kill("error during init", true);
6259            handleAppDiedLocked(app, false, true);
6260            return false;
6261        }
6262
6263        if (!didSomething) {
6264            updateOomAdjLocked();
6265        }
6266
6267        return true;
6268    }
6269
6270    @Override
6271    public final void attachApplication(IApplicationThread thread) {
6272        synchronized (this) {
6273            int callingPid = Binder.getCallingPid();
6274            final long origId = Binder.clearCallingIdentity();
6275            attachApplicationLocked(thread, callingPid);
6276            Binder.restoreCallingIdentity(origId);
6277        }
6278    }
6279
6280    @Override
6281    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6282        final long origId = Binder.clearCallingIdentity();
6283        synchronized (this) {
6284            ActivityStack stack = ActivityRecord.getStackLocked(token);
6285            if (stack != null) {
6286                ActivityRecord r =
6287                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6288                if (stopProfiling) {
6289                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6290                        try {
6291                            mProfileFd.close();
6292                        } catch (IOException e) {
6293                        }
6294                        clearProfilerLocked();
6295                    }
6296                }
6297            }
6298        }
6299        Binder.restoreCallingIdentity(origId);
6300    }
6301
6302    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6303        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6304                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6305    }
6306
6307    void enableScreenAfterBoot() {
6308        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6309                SystemClock.uptimeMillis());
6310        mWindowManager.enableScreenAfterBoot();
6311
6312        synchronized (this) {
6313            updateEventDispatchingLocked();
6314        }
6315    }
6316
6317    @Override
6318    public void showBootMessage(final CharSequence msg, final boolean always) {
6319        enforceNotIsolatedCaller("showBootMessage");
6320        mWindowManager.showBootMessage(msg, always);
6321    }
6322
6323    @Override
6324    public void keyguardWaitingForActivityDrawn() {
6325        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6326        final long token = Binder.clearCallingIdentity();
6327        try {
6328            synchronized (this) {
6329                if (DEBUG_LOCKSCREEN) logLockScreen("");
6330                mWindowManager.keyguardWaitingForActivityDrawn();
6331                if (mLockScreenShown) {
6332                    mLockScreenShown = false;
6333                    comeOutOfSleepIfNeededLocked();
6334                }
6335            }
6336        } finally {
6337            Binder.restoreCallingIdentity(token);
6338        }
6339    }
6340
6341    final void finishBooting() {
6342        synchronized (this) {
6343            if (!mBootAnimationComplete) {
6344                mCallFinishBooting = true;
6345                return;
6346            }
6347            mCallFinishBooting = false;
6348        }
6349
6350        ArraySet<String> completedIsas = new ArraySet<String>();
6351        for (String abi : Build.SUPPORTED_ABIS) {
6352            Process.establishZygoteConnectionForAbi(abi);
6353            final String instructionSet = VMRuntime.getInstructionSet(abi);
6354            if (!completedIsas.contains(instructionSet)) {
6355                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6356                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6357                }
6358                completedIsas.add(instructionSet);
6359            }
6360        }
6361
6362        // Register receivers to handle package update events
6363        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6364
6365        // Let system services know.
6366        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6367
6368        synchronized (this) {
6369            // Ensure that any processes we had put on hold are now started
6370            // up.
6371            final int NP = mProcessesOnHold.size();
6372            if (NP > 0) {
6373                ArrayList<ProcessRecord> procs =
6374                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6375                for (int ip=0; ip<NP; ip++) {
6376                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6377                            + procs.get(ip));
6378                    startProcessLocked(procs.get(ip), "on-hold", null);
6379                }
6380            }
6381
6382            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6383                // Start looking for apps that are abusing wake locks.
6384                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6385                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6386                // Tell anyone interested that we are done booting!
6387                SystemProperties.set("sys.boot_completed", "1");
6388
6389                // And trigger dev.bootcomplete if we are not showing encryption progress
6390                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6391                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6392                    SystemProperties.set("dev.bootcomplete", "1");
6393                }
6394                for (int i=0; i<mStartedUsers.size(); i++) {
6395                    UserStartedState uss = mStartedUsers.valueAt(i);
6396                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6397                        uss.mState = UserStartedState.STATE_RUNNING;
6398                        final int userId = mStartedUsers.keyAt(i);
6399                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6400                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6401                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6402                        broadcastIntentLocked(null, null, intent, null,
6403                                new IIntentReceiver.Stub() {
6404                                    @Override
6405                                    public void performReceive(Intent intent, int resultCode,
6406                                            String data, Bundle extras, boolean ordered,
6407                                            boolean sticky, int sendingUser) {
6408                                        synchronized (ActivityManagerService.this) {
6409                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6410                                                    true, false);
6411                                        }
6412                                    }
6413                                },
6414                                0, null, null,
6415                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6416                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6417                                userId);
6418                    }
6419                }
6420                scheduleStartProfilesLocked();
6421            }
6422        }
6423    }
6424
6425    @Override
6426    public void bootAnimationComplete() {
6427        final boolean callFinishBooting;
6428        synchronized (this) {
6429            callFinishBooting = mCallFinishBooting;
6430            mBootAnimationComplete = true;
6431        }
6432        if (callFinishBooting) {
6433            finishBooting();
6434        }
6435    }
6436
6437    final void ensureBootCompleted() {
6438        boolean booting;
6439        boolean enableScreen;
6440        synchronized (this) {
6441            booting = mBooting;
6442            mBooting = false;
6443            enableScreen = !mBooted;
6444            mBooted = true;
6445        }
6446
6447        if (booting) {
6448            finishBooting();
6449        }
6450
6451        if (enableScreen) {
6452            enableScreenAfterBoot();
6453        }
6454    }
6455
6456    @Override
6457    public final void activityResumed(IBinder token) {
6458        final long origId = Binder.clearCallingIdentity();
6459        synchronized(this) {
6460            ActivityStack stack = ActivityRecord.getStackLocked(token);
6461            if (stack != null) {
6462                ActivityRecord.activityResumedLocked(token);
6463            }
6464        }
6465        Binder.restoreCallingIdentity(origId);
6466    }
6467
6468    @Override
6469    public final void activityPaused(IBinder token) {
6470        final long origId = Binder.clearCallingIdentity();
6471        synchronized(this) {
6472            ActivityStack stack = ActivityRecord.getStackLocked(token);
6473            if (stack != null) {
6474                stack.activityPausedLocked(token, false);
6475            }
6476        }
6477        Binder.restoreCallingIdentity(origId);
6478    }
6479
6480    @Override
6481    public final void activityStopped(IBinder token, Bundle icicle,
6482            PersistableBundle persistentState, CharSequence description) {
6483        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6484
6485        // Refuse possible leaked file descriptors
6486        if (icicle != null && icicle.hasFileDescriptors()) {
6487            throw new IllegalArgumentException("File descriptors passed in Bundle");
6488        }
6489
6490        final long origId = Binder.clearCallingIdentity();
6491
6492        synchronized (this) {
6493            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6494            if (r != null) {
6495                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6496            }
6497        }
6498
6499        trimApplications();
6500
6501        Binder.restoreCallingIdentity(origId);
6502    }
6503
6504    @Override
6505    public final void activityDestroyed(IBinder token) {
6506        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6507        synchronized (this) {
6508            ActivityStack stack = ActivityRecord.getStackLocked(token);
6509            if (stack != null) {
6510                stack.activityDestroyedLocked(token);
6511            }
6512        }
6513    }
6514
6515    @Override
6516    public final void backgroundResourcesReleased(IBinder token) {
6517        final long origId = Binder.clearCallingIdentity();
6518        try {
6519            synchronized (this) {
6520                ActivityStack stack = ActivityRecord.getStackLocked(token);
6521                if (stack != null) {
6522                    stack.backgroundResourcesReleased(token);
6523                }
6524            }
6525        } finally {
6526            Binder.restoreCallingIdentity(origId);
6527        }
6528    }
6529
6530    @Override
6531    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6532        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6533    }
6534
6535    @Override
6536    public final void notifyEnterAnimationComplete(IBinder token) {
6537        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6538    }
6539
6540    @Override
6541    public String getCallingPackage(IBinder token) {
6542        synchronized (this) {
6543            ActivityRecord r = getCallingRecordLocked(token);
6544            return r != null ? r.info.packageName : null;
6545        }
6546    }
6547
6548    @Override
6549    public ComponentName getCallingActivity(IBinder token) {
6550        synchronized (this) {
6551            ActivityRecord r = getCallingRecordLocked(token);
6552            return r != null ? r.intent.getComponent() : null;
6553        }
6554    }
6555
6556    private ActivityRecord getCallingRecordLocked(IBinder token) {
6557        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6558        if (r == null) {
6559            return null;
6560        }
6561        return r.resultTo;
6562    }
6563
6564    @Override
6565    public ComponentName getActivityClassForToken(IBinder token) {
6566        synchronized(this) {
6567            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6568            if (r == null) {
6569                return null;
6570            }
6571            return r.intent.getComponent();
6572        }
6573    }
6574
6575    @Override
6576    public String getPackageForToken(IBinder token) {
6577        synchronized(this) {
6578            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6579            if (r == null) {
6580                return null;
6581            }
6582            return r.packageName;
6583        }
6584    }
6585
6586    @Override
6587    public IIntentSender getIntentSender(int type,
6588            String packageName, IBinder token, String resultWho,
6589            int requestCode, Intent[] intents, String[] resolvedTypes,
6590            int flags, Bundle options, int userId) {
6591        enforceNotIsolatedCaller("getIntentSender");
6592        // Refuse possible leaked file descriptors
6593        if (intents != null) {
6594            if (intents.length < 1) {
6595                throw new IllegalArgumentException("Intents array length must be >= 1");
6596            }
6597            for (int i=0; i<intents.length; i++) {
6598                Intent intent = intents[i];
6599                if (intent != null) {
6600                    if (intent.hasFileDescriptors()) {
6601                        throw new IllegalArgumentException("File descriptors passed in Intent");
6602                    }
6603                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6604                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6605                        throw new IllegalArgumentException(
6606                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6607                    }
6608                    intents[i] = new Intent(intent);
6609                }
6610            }
6611            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6612                throw new IllegalArgumentException(
6613                        "Intent array length does not match resolvedTypes length");
6614            }
6615        }
6616        if (options != null) {
6617            if (options.hasFileDescriptors()) {
6618                throw new IllegalArgumentException("File descriptors passed in options");
6619            }
6620        }
6621
6622        synchronized(this) {
6623            int callingUid = Binder.getCallingUid();
6624            int origUserId = userId;
6625            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6626                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6627                    ALLOW_NON_FULL, "getIntentSender", null);
6628            if (origUserId == UserHandle.USER_CURRENT) {
6629                // We don't want to evaluate this until the pending intent is
6630                // actually executed.  However, we do want to always do the
6631                // security checking for it above.
6632                userId = UserHandle.USER_CURRENT;
6633            }
6634            try {
6635                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6636                    int uid = AppGlobals.getPackageManager()
6637                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6638                    if (!UserHandle.isSameApp(callingUid, uid)) {
6639                        String msg = "Permission Denial: getIntentSender() from pid="
6640                            + Binder.getCallingPid()
6641                            + ", uid=" + Binder.getCallingUid()
6642                            + ", (need uid=" + uid + ")"
6643                            + " is not allowed to send as package " + packageName;
6644                        Slog.w(TAG, msg);
6645                        throw new SecurityException(msg);
6646                    }
6647                }
6648
6649                return getIntentSenderLocked(type, packageName, callingUid, userId,
6650                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6651
6652            } catch (RemoteException e) {
6653                throw new SecurityException(e);
6654            }
6655        }
6656    }
6657
6658    IIntentSender getIntentSenderLocked(int type, String packageName,
6659            int callingUid, int userId, IBinder token, String resultWho,
6660            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6661            Bundle options) {
6662        if (DEBUG_MU)
6663            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6664        ActivityRecord activity = null;
6665        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6666            activity = ActivityRecord.isInStackLocked(token);
6667            if (activity == null) {
6668                return null;
6669            }
6670            if (activity.finishing) {
6671                return null;
6672            }
6673        }
6674
6675        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6676        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6677        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6678        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6679                |PendingIntent.FLAG_UPDATE_CURRENT);
6680
6681        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6682                type, packageName, activity, resultWho,
6683                requestCode, intents, resolvedTypes, flags, options, userId);
6684        WeakReference<PendingIntentRecord> ref;
6685        ref = mIntentSenderRecords.get(key);
6686        PendingIntentRecord rec = ref != null ? ref.get() : null;
6687        if (rec != null) {
6688            if (!cancelCurrent) {
6689                if (updateCurrent) {
6690                    if (rec.key.requestIntent != null) {
6691                        rec.key.requestIntent.replaceExtras(intents != null ?
6692                                intents[intents.length - 1] : null);
6693                    }
6694                    if (intents != null) {
6695                        intents[intents.length-1] = rec.key.requestIntent;
6696                        rec.key.allIntents = intents;
6697                        rec.key.allResolvedTypes = resolvedTypes;
6698                    } else {
6699                        rec.key.allIntents = null;
6700                        rec.key.allResolvedTypes = null;
6701                    }
6702                }
6703                return rec;
6704            }
6705            rec.canceled = true;
6706            mIntentSenderRecords.remove(key);
6707        }
6708        if (noCreate) {
6709            return rec;
6710        }
6711        rec = new PendingIntentRecord(this, key, callingUid);
6712        mIntentSenderRecords.put(key, rec.ref);
6713        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6714            if (activity.pendingResults == null) {
6715                activity.pendingResults
6716                        = new HashSet<WeakReference<PendingIntentRecord>>();
6717            }
6718            activity.pendingResults.add(rec.ref);
6719        }
6720        return rec;
6721    }
6722
6723    @Override
6724    public void cancelIntentSender(IIntentSender sender) {
6725        if (!(sender instanceof PendingIntentRecord)) {
6726            return;
6727        }
6728        synchronized(this) {
6729            PendingIntentRecord rec = (PendingIntentRecord)sender;
6730            try {
6731                int uid = AppGlobals.getPackageManager()
6732                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6733                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6734                    String msg = "Permission Denial: cancelIntentSender() from pid="
6735                        + Binder.getCallingPid()
6736                        + ", uid=" + Binder.getCallingUid()
6737                        + " is not allowed to cancel packges "
6738                        + rec.key.packageName;
6739                    Slog.w(TAG, msg);
6740                    throw new SecurityException(msg);
6741                }
6742            } catch (RemoteException e) {
6743                throw new SecurityException(e);
6744            }
6745            cancelIntentSenderLocked(rec, true);
6746        }
6747    }
6748
6749    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6750        rec.canceled = true;
6751        mIntentSenderRecords.remove(rec.key);
6752        if (cleanActivity && rec.key.activity != null) {
6753            rec.key.activity.pendingResults.remove(rec.ref);
6754        }
6755    }
6756
6757    @Override
6758    public String getPackageForIntentSender(IIntentSender pendingResult) {
6759        if (!(pendingResult instanceof PendingIntentRecord)) {
6760            return null;
6761        }
6762        try {
6763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6764            return res.key.packageName;
6765        } catch (ClassCastException e) {
6766        }
6767        return null;
6768    }
6769
6770    @Override
6771    public int getUidForIntentSender(IIntentSender sender) {
6772        if (sender instanceof PendingIntentRecord) {
6773            try {
6774                PendingIntentRecord res = (PendingIntentRecord)sender;
6775                return res.uid;
6776            } catch (ClassCastException e) {
6777            }
6778        }
6779        return -1;
6780    }
6781
6782    @Override
6783    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6784        if (!(pendingResult instanceof PendingIntentRecord)) {
6785            return false;
6786        }
6787        try {
6788            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6789            if (res.key.allIntents == null) {
6790                return false;
6791            }
6792            for (int i=0; i<res.key.allIntents.length; i++) {
6793                Intent intent = res.key.allIntents[i];
6794                if (intent.getPackage() != null && intent.getComponent() != null) {
6795                    return false;
6796                }
6797            }
6798            return true;
6799        } catch (ClassCastException e) {
6800        }
6801        return false;
6802    }
6803
6804    @Override
6805    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6806        if (!(pendingResult instanceof PendingIntentRecord)) {
6807            return false;
6808        }
6809        try {
6810            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6811            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6812                return true;
6813            }
6814            return false;
6815        } catch (ClassCastException e) {
6816        }
6817        return false;
6818    }
6819
6820    @Override
6821    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6822        if (!(pendingResult instanceof PendingIntentRecord)) {
6823            return null;
6824        }
6825        try {
6826            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6827            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6828        } catch (ClassCastException e) {
6829        }
6830        return null;
6831    }
6832
6833    @Override
6834    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6835        if (!(pendingResult instanceof PendingIntentRecord)) {
6836            return null;
6837        }
6838        try {
6839            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6840            Intent intent = res.key.requestIntent;
6841            if (intent != null) {
6842                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6843                        || res.lastTagPrefix.equals(prefix))) {
6844                    return res.lastTag;
6845                }
6846                res.lastTagPrefix = prefix;
6847                StringBuilder sb = new StringBuilder(128);
6848                if (prefix != null) {
6849                    sb.append(prefix);
6850                }
6851                if (intent.getAction() != null) {
6852                    sb.append(intent.getAction());
6853                } else if (intent.getComponent() != null) {
6854                    intent.getComponent().appendShortString(sb);
6855                } else {
6856                    sb.append("?");
6857                }
6858                return res.lastTag = sb.toString();
6859            }
6860        } catch (ClassCastException e) {
6861        }
6862        return null;
6863    }
6864
6865    @Override
6866    public void setProcessLimit(int max) {
6867        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6868                "setProcessLimit()");
6869        synchronized (this) {
6870            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6871            mProcessLimitOverride = max;
6872        }
6873        trimApplications();
6874    }
6875
6876    @Override
6877    public int getProcessLimit() {
6878        synchronized (this) {
6879            return mProcessLimitOverride;
6880        }
6881    }
6882
6883    void foregroundTokenDied(ForegroundToken token) {
6884        synchronized (ActivityManagerService.this) {
6885            synchronized (mPidsSelfLocked) {
6886                ForegroundToken cur
6887                    = mForegroundProcesses.get(token.pid);
6888                if (cur != token) {
6889                    return;
6890                }
6891                mForegroundProcesses.remove(token.pid);
6892                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6893                if (pr == null) {
6894                    return;
6895                }
6896                pr.forcingToForeground = null;
6897                updateProcessForegroundLocked(pr, false, false);
6898            }
6899            updateOomAdjLocked();
6900        }
6901    }
6902
6903    @Override
6904    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6905        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6906                "setProcessForeground()");
6907        synchronized(this) {
6908            boolean changed = false;
6909
6910            synchronized (mPidsSelfLocked) {
6911                ProcessRecord pr = mPidsSelfLocked.get(pid);
6912                if (pr == null && isForeground) {
6913                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6914                    return;
6915                }
6916                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6917                if (oldToken != null) {
6918                    oldToken.token.unlinkToDeath(oldToken, 0);
6919                    mForegroundProcesses.remove(pid);
6920                    if (pr != null) {
6921                        pr.forcingToForeground = null;
6922                    }
6923                    changed = true;
6924                }
6925                if (isForeground && token != null) {
6926                    ForegroundToken newToken = new ForegroundToken() {
6927                        @Override
6928                        public void binderDied() {
6929                            foregroundTokenDied(this);
6930                        }
6931                    };
6932                    newToken.pid = pid;
6933                    newToken.token = token;
6934                    try {
6935                        token.linkToDeath(newToken, 0);
6936                        mForegroundProcesses.put(pid, newToken);
6937                        pr.forcingToForeground = token;
6938                        changed = true;
6939                    } catch (RemoteException e) {
6940                        // If the process died while doing this, we will later
6941                        // do the cleanup with the process death link.
6942                    }
6943                }
6944            }
6945
6946            if (changed) {
6947                updateOomAdjLocked();
6948            }
6949        }
6950    }
6951
6952    // =========================================================
6953    // PERMISSIONS
6954    // =========================================================
6955
6956    static class PermissionController extends IPermissionController.Stub {
6957        ActivityManagerService mActivityManagerService;
6958        PermissionController(ActivityManagerService activityManagerService) {
6959            mActivityManagerService = activityManagerService;
6960        }
6961
6962        @Override
6963        public boolean checkPermission(String permission, int pid, int uid) {
6964            return mActivityManagerService.checkPermission(permission, pid,
6965                    uid) == PackageManager.PERMISSION_GRANTED;
6966        }
6967    }
6968
6969    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6970        @Override
6971        public int checkComponentPermission(String permission, int pid, int uid,
6972                int owningUid, boolean exported) {
6973            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6974                    owningUid, exported);
6975        }
6976
6977        @Override
6978        public Object getAMSLock() {
6979            return ActivityManagerService.this;
6980        }
6981    }
6982
6983    /**
6984     * This can be called with or without the global lock held.
6985     */
6986    int checkComponentPermission(String permission, int pid, int uid,
6987            int owningUid, boolean exported) {
6988        // We might be performing an operation on behalf of an indirect binder
6989        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6990        // client identity accordingly before proceeding.
6991        Identity tlsIdentity = sCallerIdentity.get();
6992        if (tlsIdentity != null) {
6993            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6994                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6995            uid = tlsIdentity.uid;
6996            pid = tlsIdentity.pid;
6997        }
6998
6999        if (pid == MY_PID) {
7000            return PackageManager.PERMISSION_GRANTED;
7001        }
7002
7003        return ActivityManager.checkComponentPermission(permission, uid,
7004                owningUid, exported);
7005    }
7006
7007    /**
7008     * As the only public entry point for permissions checking, this method
7009     * can enforce the semantic that requesting a check on a null global
7010     * permission is automatically denied.  (Internally a null permission
7011     * string is used when calling {@link #checkComponentPermission} in cases
7012     * when only uid-based security is needed.)
7013     *
7014     * This can be called with or without the global lock held.
7015     */
7016    @Override
7017    public int checkPermission(String permission, int pid, int uid) {
7018        if (permission == null) {
7019            return PackageManager.PERMISSION_DENIED;
7020        }
7021        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
7022    }
7023
7024    /**
7025     * Binder IPC calls go through the public entry point.
7026     * This can be called with or without the global lock held.
7027     */
7028    int checkCallingPermission(String permission) {
7029        return checkPermission(permission,
7030                Binder.getCallingPid(),
7031                UserHandle.getAppId(Binder.getCallingUid()));
7032    }
7033
7034    /**
7035     * This can be called with or without the global lock held.
7036     */
7037    void enforceCallingPermission(String permission, String func) {
7038        if (checkCallingPermission(permission)
7039                == PackageManager.PERMISSION_GRANTED) {
7040            return;
7041        }
7042
7043        String msg = "Permission Denial: " + func + " from pid="
7044                + Binder.getCallingPid()
7045                + ", uid=" + Binder.getCallingUid()
7046                + " requires " + permission;
7047        Slog.w(TAG, msg);
7048        throw new SecurityException(msg);
7049    }
7050
7051    /**
7052     * Determine if UID is holding permissions required to access {@link Uri} in
7053     * the given {@link ProviderInfo}. Final permission checking is always done
7054     * in {@link ContentProvider}.
7055     */
7056    private final boolean checkHoldingPermissionsLocked(
7057            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7058        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7059                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7060        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7061            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7062                    != PERMISSION_GRANTED) {
7063                return false;
7064            }
7065        }
7066        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7067    }
7068
7069    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7070            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7071        if (pi.applicationInfo.uid == uid) {
7072            return true;
7073        } else if (!pi.exported) {
7074            return false;
7075        }
7076
7077        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7078        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7079        try {
7080            // check if target holds top-level <provider> permissions
7081            if (!readMet && pi.readPermission != null && considerUidPermissions
7082                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7083                readMet = true;
7084            }
7085            if (!writeMet && pi.writePermission != null && considerUidPermissions
7086                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7087                writeMet = true;
7088            }
7089
7090            // track if unprotected read/write is allowed; any denied
7091            // <path-permission> below removes this ability
7092            boolean allowDefaultRead = pi.readPermission == null;
7093            boolean allowDefaultWrite = pi.writePermission == null;
7094
7095            // check if target holds any <path-permission> that match uri
7096            final PathPermission[] pps = pi.pathPermissions;
7097            if (pps != null) {
7098                final String path = grantUri.uri.getPath();
7099                int i = pps.length;
7100                while (i > 0 && (!readMet || !writeMet)) {
7101                    i--;
7102                    PathPermission pp = pps[i];
7103                    if (pp.match(path)) {
7104                        if (!readMet) {
7105                            final String pprperm = pp.getReadPermission();
7106                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7107                                    + pprperm + " for " + pp.getPath()
7108                                    + ": match=" + pp.match(path)
7109                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7110                            if (pprperm != null) {
7111                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7112                                        == PERMISSION_GRANTED) {
7113                                    readMet = true;
7114                                } else {
7115                                    allowDefaultRead = false;
7116                                }
7117                            }
7118                        }
7119                        if (!writeMet) {
7120                            final String ppwperm = pp.getWritePermission();
7121                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7122                                    + ppwperm + " for " + pp.getPath()
7123                                    + ": match=" + pp.match(path)
7124                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7125                            if (ppwperm != null) {
7126                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7127                                        == PERMISSION_GRANTED) {
7128                                    writeMet = true;
7129                                } else {
7130                                    allowDefaultWrite = false;
7131                                }
7132                            }
7133                        }
7134                    }
7135                }
7136            }
7137
7138            // grant unprotected <provider> read/write, if not blocked by
7139            // <path-permission> above
7140            if (allowDefaultRead) readMet = true;
7141            if (allowDefaultWrite) writeMet = true;
7142
7143        } catch (RemoteException e) {
7144            return false;
7145        }
7146
7147        return readMet && writeMet;
7148    }
7149
7150    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7151        ProviderInfo pi = null;
7152        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7153        if (cpr != null) {
7154            pi = cpr.info;
7155        } else {
7156            try {
7157                pi = AppGlobals.getPackageManager().resolveContentProvider(
7158                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7159            } catch (RemoteException ex) {
7160            }
7161        }
7162        return pi;
7163    }
7164
7165    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7166        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7167        if (targetUris != null) {
7168            return targetUris.get(grantUri);
7169        }
7170        return null;
7171    }
7172
7173    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7174            String targetPkg, int targetUid, GrantUri grantUri) {
7175        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7176        if (targetUris == null) {
7177            targetUris = Maps.newArrayMap();
7178            mGrantedUriPermissions.put(targetUid, targetUris);
7179        }
7180
7181        UriPermission perm = targetUris.get(grantUri);
7182        if (perm == null) {
7183            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7184            targetUris.put(grantUri, perm);
7185        }
7186
7187        return perm;
7188    }
7189
7190    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7191            final int modeFlags) {
7192        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7193        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7194                : UriPermission.STRENGTH_OWNED;
7195
7196        // Root gets to do everything.
7197        if (uid == 0) {
7198            return true;
7199        }
7200
7201        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7202        if (perms == null) return false;
7203
7204        // First look for exact match
7205        final UriPermission exactPerm = perms.get(grantUri);
7206        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7207            return true;
7208        }
7209
7210        // No exact match, look for prefixes
7211        final int N = perms.size();
7212        for (int i = 0; i < N; i++) {
7213            final UriPermission perm = perms.valueAt(i);
7214            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7215                    && perm.getStrength(modeFlags) >= minStrength) {
7216                return true;
7217            }
7218        }
7219
7220        return false;
7221    }
7222
7223    /**
7224     * @param uri This uri must NOT contain an embedded userId.
7225     * @param userId The userId in which the uri is to be resolved.
7226     */
7227    @Override
7228    public int checkUriPermission(Uri uri, int pid, int uid,
7229            final int modeFlags, int userId) {
7230        enforceNotIsolatedCaller("checkUriPermission");
7231
7232        // Another redirected-binder-call permissions check as in
7233        // {@link checkComponentPermission}.
7234        Identity tlsIdentity = sCallerIdentity.get();
7235        if (tlsIdentity != null) {
7236            uid = tlsIdentity.uid;
7237            pid = tlsIdentity.pid;
7238        }
7239
7240        // Our own process gets to do everything.
7241        if (pid == MY_PID) {
7242            return PackageManager.PERMISSION_GRANTED;
7243        }
7244        synchronized (this) {
7245            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7246                    ? PackageManager.PERMISSION_GRANTED
7247                    : PackageManager.PERMISSION_DENIED;
7248        }
7249    }
7250
7251    /**
7252     * Check if the targetPkg can be granted permission to access uri by
7253     * the callingUid using the given modeFlags.  Throws a security exception
7254     * if callingUid is not allowed to do this.  Returns the uid of the target
7255     * if the URI permission grant should be performed; returns -1 if it is not
7256     * needed (for example targetPkg already has permission to access the URI).
7257     * If you already know the uid of the target, you can supply it in
7258     * lastTargetUid else set that to -1.
7259     */
7260    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7261            final int modeFlags, int lastTargetUid) {
7262        if (!Intent.isAccessUriMode(modeFlags)) {
7263            return -1;
7264        }
7265
7266        if (targetPkg != null) {
7267            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7268                    "Checking grant " + targetPkg + " permission to " + grantUri);
7269        }
7270
7271        final IPackageManager pm = AppGlobals.getPackageManager();
7272
7273        // If this is not a content: uri, we can't do anything with it.
7274        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7275            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7276                    "Can't grant URI permission for non-content URI: " + grantUri);
7277            return -1;
7278        }
7279
7280        final String authority = grantUri.uri.getAuthority();
7281        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7282        if (pi == null) {
7283            Slog.w(TAG, "No content provider found for permission check: " +
7284                    grantUri.uri.toSafeString());
7285            return -1;
7286        }
7287
7288        int targetUid = lastTargetUid;
7289        if (targetUid < 0 && targetPkg != null) {
7290            try {
7291                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7292                if (targetUid < 0) {
7293                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7294                            "Can't grant URI permission no uid for: " + targetPkg);
7295                    return -1;
7296                }
7297            } catch (RemoteException ex) {
7298                return -1;
7299            }
7300        }
7301
7302        if (targetUid >= 0) {
7303            // First...  does the target actually need this permission?
7304            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7305                // No need to grant the target this permission.
7306                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7307                        "Target " + targetPkg + " already has full permission to " + grantUri);
7308                return -1;
7309            }
7310        } else {
7311            // First...  there is no target package, so can anyone access it?
7312            boolean allowed = pi.exported;
7313            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7314                if (pi.readPermission != null) {
7315                    allowed = false;
7316                }
7317            }
7318            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7319                if (pi.writePermission != null) {
7320                    allowed = false;
7321                }
7322            }
7323            if (allowed) {
7324                return -1;
7325            }
7326        }
7327
7328        /* There is a special cross user grant if:
7329         * - The target is on another user.
7330         * - Apps on the current user can access the uri without any uid permissions.
7331         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7332         * grant uri permissions.
7333         */
7334        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7335                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7336                modeFlags, false /*without considering the uid permissions*/);
7337
7338        // Second...  is the provider allowing granting of URI permissions?
7339        if (!specialCrossUserGrant) {
7340            if (!pi.grantUriPermissions) {
7341                throw new SecurityException("Provider " + pi.packageName
7342                        + "/" + pi.name
7343                        + " does not allow granting of Uri permissions (uri "
7344                        + grantUri + ")");
7345            }
7346            if (pi.uriPermissionPatterns != null) {
7347                final int N = pi.uriPermissionPatterns.length;
7348                boolean allowed = false;
7349                for (int i=0; i<N; i++) {
7350                    if (pi.uriPermissionPatterns[i] != null
7351                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7352                        allowed = true;
7353                        break;
7354                    }
7355                }
7356                if (!allowed) {
7357                    throw new SecurityException("Provider " + pi.packageName
7358                            + "/" + pi.name
7359                            + " does not allow granting of permission to path of Uri "
7360                            + grantUri);
7361                }
7362            }
7363        }
7364
7365        // Third...  does the caller itself have permission to access
7366        // this uri?
7367        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7368            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7369                // Require they hold a strong enough Uri permission
7370                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7371                    throw new SecurityException("Uid " + callingUid
7372                            + " does not have permission to uri " + grantUri);
7373                }
7374            }
7375        }
7376        return targetUid;
7377    }
7378
7379    /**
7380     * @param uri This uri must NOT contain an embedded userId.
7381     * @param userId The userId in which the uri is to be resolved.
7382     */
7383    @Override
7384    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7385            final int modeFlags, int userId) {
7386        enforceNotIsolatedCaller("checkGrantUriPermission");
7387        synchronized(this) {
7388            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7389                    new GrantUri(userId, uri, false), modeFlags, -1);
7390        }
7391    }
7392
7393    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7394            final int modeFlags, UriPermissionOwner owner) {
7395        if (!Intent.isAccessUriMode(modeFlags)) {
7396            return;
7397        }
7398
7399        // So here we are: the caller has the assumed permission
7400        // to the uri, and the target doesn't.  Let's now give this to
7401        // the target.
7402
7403        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7404                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7405
7406        final String authority = grantUri.uri.getAuthority();
7407        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7408        if (pi == null) {
7409            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7410            return;
7411        }
7412
7413        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7414            grantUri.prefix = true;
7415        }
7416        final UriPermission perm = findOrCreateUriPermissionLocked(
7417                pi.packageName, targetPkg, targetUid, grantUri);
7418        perm.grantModes(modeFlags, owner);
7419    }
7420
7421    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7422            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7423        if (targetPkg == null) {
7424            throw new NullPointerException("targetPkg");
7425        }
7426        int targetUid;
7427        final IPackageManager pm = AppGlobals.getPackageManager();
7428        try {
7429            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7430        } catch (RemoteException ex) {
7431            return;
7432        }
7433
7434        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7435                targetUid);
7436        if (targetUid < 0) {
7437            return;
7438        }
7439
7440        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7441                owner);
7442    }
7443
7444    static class NeededUriGrants extends ArrayList<GrantUri> {
7445        final String targetPkg;
7446        final int targetUid;
7447        final int flags;
7448
7449        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7450            this.targetPkg = targetPkg;
7451            this.targetUid = targetUid;
7452            this.flags = flags;
7453        }
7454    }
7455
7456    /**
7457     * Like checkGrantUriPermissionLocked, but takes an Intent.
7458     */
7459    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7460            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7461        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7462                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7463                + " clip=" + (intent != null ? intent.getClipData() : null)
7464                + " from " + intent + "; flags=0x"
7465                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7466
7467        if (targetPkg == null) {
7468            throw new NullPointerException("targetPkg");
7469        }
7470
7471        if (intent == null) {
7472            return null;
7473        }
7474        Uri data = intent.getData();
7475        ClipData clip = intent.getClipData();
7476        if (data == null && clip == null) {
7477            return null;
7478        }
7479        // Default userId for uris in the intent (if they don't specify it themselves)
7480        int contentUserHint = intent.getContentUserHint();
7481        if (contentUserHint == UserHandle.USER_CURRENT) {
7482            contentUserHint = UserHandle.getUserId(callingUid);
7483        }
7484        final IPackageManager pm = AppGlobals.getPackageManager();
7485        int targetUid;
7486        if (needed != null) {
7487            targetUid = needed.targetUid;
7488        } else {
7489            try {
7490                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7491            } catch (RemoteException ex) {
7492                return null;
7493            }
7494            if (targetUid < 0) {
7495                if (DEBUG_URI_PERMISSION) {
7496                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7497                            + " on user " + targetUserId);
7498                }
7499                return null;
7500            }
7501        }
7502        if (data != null) {
7503            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7504            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7505                    targetUid);
7506            if (targetUid > 0) {
7507                if (needed == null) {
7508                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7509                }
7510                needed.add(grantUri);
7511            }
7512        }
7513        if (clip != null) {
7514            for (int i=0; i<clip.getItemCount(); i++) {
7515                Uri uri = clip.getItemAt(i).getUri();
7516                if (uri != null) {
7517                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7518                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7519                            targetUid);
7520                    if (targetUid > 0) {
7521                        if (needed == null) {
7522                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7523                        }
7524                        needed.add(grantUri);
7525                    }
7526                } else {
7527                    Intent clipIntent = clip.getItemAt(i).getIntent();
7528                    if (clipIntent != null) {
7529                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7530                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7531                        if (newNeeded != null) {
7532                            needed = newNeeded;
7533                        }
7534                    }
7535                }
7536            }
7537        }
7538
7539        return needed;
7540    }
7541
7542    /**
7543     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7544     */
7545    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7546            UriPermissionOwner owner) {
7547        if (needed != null) {
7548            for (int i=0; i<needed.size(); i++) {
7549                GrantUri grantUri = needed.get(i);
7550                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7551                        grantUri, needed.flags, owner);
7552            }
7553        }
7554    }
7555
7556    void grantUriPermissionFromIntentLocked(int callingUid,
7557            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7558        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7559                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7560        if (needed == null) {
7561            return;
7562        }
7563
7564        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7565    }
7566
7567    /**
7568     * @param uri This uri must NOT contain an embedded userId.
7569     * @param userId The userId in which the uri is to be resolved.
7570     */
7571    @Override
7572    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7573            final int modeFlags, int userId) {
7574        enforceNotIsolatedCaller("grantUriPermission");
7575        GrantUri grantUri = new GrantUri(userId, uri, false);
7576        synchronized(this) {
7577            final ProcessRecord r = getRecordForAppLocked(caller);
7578            if (r == null) {
7579                throw new SecurityException("Unable to find app for caller "
7580                        + caller
7581                        + " when granting permission to uri " + grantUri);
7582            }
7583            if (targetPkg == null) {
7584                throw new IllegalArgumentException("null target");
7585            }
7586            if (grantUri == null) {
7587                throw new IllegalArgumentException("null uri");
7588            }
7589
7590            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7591                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7592                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7593                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7594
7595            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7596                    UserHandle.getUserId(r.uid));
7597        }
7598    }
7599
7600    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7601        if (perm.modeFlags == 0) {
7602            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7603                    perm.targetUid);
7604            if (perms != null) {
7605                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7606                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7607
7608                perms.remove(perm.uri);
7609                if (perms.isEmpty()) {
7610                    mGrantedUriPermissions.remove(perm.targetUid);
7611                }
7612            }
7613        }
7614    }
7615
7616    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7617        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7618
7619        final IPackageManager pm = AppGlobals.getPackageManager();
7620        final String authority = grantUri.uri.getAuthority();
7621        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7622        if (pi == null) {
7623            Slog.w(TAG, "No content provider found for permission revoke: "
7624                    + grantUri.toSafeString());
7625            return;
7626        }
7627
7628        // Does the caller have this permission on the URI?
7629        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7630            // If they don't have direct access to the URI, then revoke any
7631            // ownerless URI permissions that have been granted to them.
7632            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7633            if (perms != null) {
7634                boolean persistChanged = false;
7635                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7636                    final UriPermission perm = it.next();
7637                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7638                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7639                        if (DEBUG_URI_PERMISSION)
7640                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7641                                    " permission to " + perm.uri);
7642                        persistChanged |= perm.revokeModes(
7643                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7644                        if (perm.modeFlags == 0) {
7645                            it.remove();
7646                        }
7647                    }
7648                }
7649                if (perms.isEmpty()) {
7650                    mGrantedUriPermissions.remove(callingUid);
7651                }
7652                if (persistChanged) {
7653                    schedulePersistUriGrants();
7654                }
7655            }
7656            return;
7657        }
7658
7659        boolean persistChanged = false;
7660
7661        // Go through all of the permissions and remove any that match.
7662        int N = mGrantedUriPermissions.size();
7663        for (int i = 0; i < N; i++) {
7664            final int targetUid = mGrantedUriPermissions.keyAt(i);
7665            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7666
7667            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7668                final UriPermission perm = it.next();
7669                if (perm.uri.sourceUserId == grantUri.sourceUserId
7670                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7671                    if (DEBUG_URI_PERMISSION)
7672                        Slog.v(TAG,
7673                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7674                    persistChanged |= perm.revokeModes(
7675                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7676                    if (perm.modeFlags == 0) {
7677                        it.remove();
7678                    }
7679                }
7680            }
7681
7682            if (perms.isEmpty()) {
7683                mGrantedUriPermissions.remove(targetUid);
7684                N--;
7685                i--;
7686            }
7687        }
7688
7689        if (persistChanged) {
7690            schedulePersistUriGrants();
7691        }
7692    }
7693
7694    /**
7695     * @param uri This uri must NOT contain an embedded userId.
7696     * @param userId The userId in which the uri is to be resolved.
7697     */
7698    @Override
7699    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7700            int userId) {
7701        enforceNotIsolatedCaller("revokeUriPermission");
7702        synchronized(this) {
7703            final ProcessRecord r = getRecordForAppLocked(caller);
7704            if (r == null) {
7705                throw new SecurityException("Unable to find app for caller "
7706                        + caller
7707                        + " when revoking permission to uri " + uri);
7708            }
7709            if (uri == null) {
7710                Slog.w(TAG, "revokeUriPermission: null uri");
7711                return;
7712            }
7713
7714            if (!Intent.isAccessUriMode(modeFlags)) {
7715                return;
7716            }
7717
7718            final IPackageManager pm = AppGlobals.getPackageManager();
7719            final String authority = uri.getAuthority();
7720            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7721            if (pi == null) {
7722                Slog.w(TAG, "No content provider found for permission revoke: "
7723                        + uri.toSafeString());
7724                return;
7725            }
7726
7727            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7728        }
7729    }
7730
7731    /**
7732     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7733     * given package.
7734     *
7735     * @param packageName Package name to match, or {@code null} to apply to all
7736     *            packages.
7737     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7738     *            to all users.
7739     * @param persistable If persistable grants should be removed.
7740     */
7741    private void removeUriPermissionsForPackageLocked(
7742            String packageName, int userHandle, boolean persistable) {
7743        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7744            throw new IllegalArgumentException("Must narrow by either package or user");
7745        }
7746
7747        boolean persistChanged = false;
7748
7749        int N = mGrantedUriPermissions.size();
7750        for (int i = 0; i < N; i++) {
7751            final int targetUid = mGrantedUriPermissions.keyAt(i);
7752            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7753
7754            // Only inspect grants matching user
7755            if (userHandle == UserHandle.USER_ALL
7756                    || userHandle == UserHandle.getUserId(targetUid)) {
7757                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7758                    final UriPermission perm = it.next();
7759
7760                    // Only inspect grants matching package
7761                    if (packageName == null || perm.sourcePkg.equals(packageName)
7762                            || perm.targetPkg.equals(packageName)) {
7763                        persistChanged |= perm.revokeModes(persistable
7764                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7765
7766                        // Only remove when no modes remain; any persisted grants
7767                        // will keep this alive.
7768                        if (perm.modeFlags == 0) {
7769                            it.remove();
7770                        }
7771                    }
7772                }
7773
7774                if (perms.isEmpty()) {
7775                    mGrantedUriPermissions.remove(targetUid);
7776                    N--;
7777                    i--;
7778                }
7779            }
7780        }
7781
7782        if (persistChanged) {
7783            schedulePersistUriGrants();
7784        }
7785    }
7786
7787    @Override
7788    public IBinder newUriPermissionOwner(String name) {
7789        enforceNotIsolatedCaller("newUriPermissionOwner");
7790        synchronized(this) {
7791            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7792            return owner.getExternalTokenLocked();
7793        }
7794    }
7795
7796    /**
7797     * @param uri This uri must NOT contain an embedded userId.
7798     * @param sourceUserId The userId in which the uri is to be resolved.
7799     * @param targetUserId The userId of the app that receives the grant.
7800     */
7801    @Override
7802    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7803            final int modeFlags, int sourceUserId, int targetUserId) {
7804        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7805                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7806        synchronized(this) {
7807            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7808            if (owner == null) {
7809                throw new IllegalArgumentException("Unknown owner: " + token);
7810            }
7811            if (fromUid != Binder.getCallingUid()) {
7812                if (Binder.getCallingUid() != Process.myUid()) {
7813                    // Only system code can grant URI permissions on behalf
7814                    // of other users.
7815                    throw new SecurityException("nice try");
7816                }
7817            }
7818            if (targetPkg == null) {
7819                throw new IllegalArgumentException("null target");
7820            }
7821            if (uri == null) {
7822                throw new IllegalArgumentException("null uri");
7823            }
7824
7825            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7826                    modeFlags, owner, targetUserId);
7827        }
7828    }
7829
7830    /**
7831     * @param uri This uri must NOT contain an embedded userId.
7832     * @param userId The userId in which the uri is to be resolved.
7833     */
7834    @Override
7835    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7836        synchronized(this) {
7837            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7838            if (owner == null) {
7839                throw new IllegalArgumentException("Unknown owner: " + token);
7840            }
7841
7842            if (uri == null) {
7843                owner.removeUriPermissionsLocked(mode);
7844            } else {
7845                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7846            }
7847        }
7848    }
7849
7850    private void schedulePersistUriGrants() {
7851        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7852            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7853                    10 * DateUtils.SECOND_IN_MILLIS);
7854        }
7855    }
7856
7857    private void writeGrantedUriPermissions() {
7858        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7859
7860        // Snapshot permissions so we can persist without lock
7861        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7862        synchronized (this) {
7863            final int size = mGrantedUriPermissions.size();
7864            for (int i = 0; i < size; i++) {
7865                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7866                for (UriPermission perm : perms.values()) {
7867                    if (perm.persistedModeFlags != 0) {
7868                        persist.add(perm.snapshot());
7869                    }
7870                }
7871            }
7872        }
7873
7874        FileOutputStream fos = null;
7875        try {
7876            fos = mGrantFile.startWrite();
7877
7878            XmlSerializer out = new FastXmlSerializer();
7879            out.setOutput(fos, "utf-8");
7880            out.startDocument(null, true);
7881            out.startTag(null, TAG_URI_GRANTS);
7882            for (UriPermission.Snapshot perm : persist) {
7883                out.startTag(null, TAG_URI_GRANT);
7884                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7885                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7886                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7887                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7888                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7889                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7890                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7891                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7892                out.endTag(null, TAG_URI_GRANT);
7893            }
7894            out.endTag(null, TAG_URI_GRANTS);
7895            out.endDocument();
7896
7897            mGrantFile.finishWrite(fos);
7898        } catch (IOException e) {
7899            if (fos != null) {
7900                mGrantFile.failWrite(fos);
7901            }
7902        }
7903    }
7904
7905    private void readGrantedUriPermissionsLocked() {
7906        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7907
7908        final long now = System.currentTimeMillis();
7909
7910        FileInputStream fis = null;
7911        try {
7912            fis = mGrantFile.openRead();
7913            final XmlPullParser in = Xml.newPullParser();
7914            in.setInput(fis, null);
7915
7916            int type;
7917            while ((type = in.next()) != END_DOCUMENT) {
7918                final String tag = in.getName();
7919                if (type == START_TAG) {
7920                    if (TAG_URI_GRANT.equals(tag)) {
7921                        final int sourceUserId;
7922                        final int targetUserId;
7923                        final int userHandle = readIntAttribute(in,
7924                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7925                        if (userHandle != UserHandle.USER_NULL) {
7926                            // For backwards compatibility.
7927                            sourceUserId = userHandle;
7928                            targetUserId = userHandle;
7929                        } else {
7930                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7931                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7932                        }
7933                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7934                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7935                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7936                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7937                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7938                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7939
7940                        // Sanity check that provider still belongs to source package
7941                        final ProviderInfo pi = getProviderInfoLocked(
7942                                uri.getAuthority(), sourceUserId);
7943                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7944                            int targetUid = -1;
7945                            try {
7946                                targetUid = AppGlobals.getPackageManager()
7947                                        .getPackageUid(targetPkg, targetUserId);
7948                            } catch (RemoteException e) {
7949                            }
7950                            if (targetUid != -1) {
7951                                final UriPermission perm = findOrCreateUriPermissionLocked(
7952                                        sourcePkg, targetPkg, targetUid,
7953                                        new GrantUri(sourceUserId, uri, prefix));
7954                                perm.initPersistedModes(modeFlags, createdTime);
7955                            }
7956                        } else {
7957                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7958                                    + " but instead found " + pi);
7959                        }
7960                    }
7961                }
7962            }
7963        } catch (FileNotFoundException e) {
7964            // Missing grants is okay
7965        } catch (IOException e) {
7966            Slog.wtf(TAG, "Failed reading Uri grants", e);
7967        } catch (XmlPullParserException e) {
7968            Slog.wtf(TAG, "Failed reading Uri grants", e);
7969        } finally {
7970            IoUtils.closeQuietly(fis);
7971        }
7972    }
7973
7974    /**
7975     * @param uri This uri must NOT contain an embedded userId.
7976     * @param userId The userId in which the uri is to be resolved.
7977     */
7978    @Override
7979    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7980        enforceNotIsolatedCaller("takePersistableUriPermission");
7981
7982        Preconditions.checkFlagsArgument(modeFlags,
7983                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7984
7985        synchronized (this) {
7986            final int callingUid = Binder.getCallingUid();
7987            boolean persistChanged = false;
7988            GrantUri grantUri = new GrantUri(userId, uri, false);
7989
7990            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7991                    new GrantUri(userId, uri, false));
7992            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7993                    new GrantUri(userId, uri, true));
7994
7995            final boolean exactValid = (exactPerm != null)
7996                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7997            final boolean prefixValid = (prefixPerm != null)
7998                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7999
8000            if (!(exactValid || prefixValid)) {
8001                throw new SecurityException("No persistable permission grants found for UID "
8002                        + callingUid + " and Uri " + grantUri.toSafeString());
8003            }
8004
8005            if (exactValid) {
8006                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8007            }
8008            if (prefixValid) {
8009                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8010            }
8011
8012            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8013
8014            if (persistChanged) {
8015                schedulePersistUriGrants();
8016            }
8017        }
8018    }
8019
8020    /**
8021     * @param uri This uri must NOT contain an embedded userId.
8022     * @param userId The userId in which the uri is to be resolved.
8023     */
8024    @Override
8025    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8026        enforceNotIsolatedCaller("releasePersistableUriPermission");
8027
8028        Preconditions.checkFlagsArgument(modeFlags,
8029                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8030
8031        synchronized (this) {
8032            final int callingUid = Binder.getCallingUid();
8033            boolean persistChanged = false;
8034
8035            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8036                    new GrantUri(userId, uri, false));
8037            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8038                    new GrantUri(userId, uri, true));
8039            if (exactPerm == null && prefixPerm == null) {
8040                throw new SecurityException("No permission grants found for UID " + callingUid
8041                        + " and Uri " + uri.toSafeString());
8042            }
8043
8044            if (exactPerm != null) {
8045                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8046                removeUriPermissionIfNeededLocked(exactPerm);
8047            }
8048            if (prefixPerm != null) {
8049                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8050                removeUriPermissionIfNeededLocked(prefixPerm);
8051            }
8052
8053            if (persistChanged) {
8054                schedulePersistUriGrants();
8055            }
8056        }
8057    }
8058
8059    /**
8060     * Prune any older {@link UriPermission} for the given UID until outstanding
8061     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8062     *
8063     * @return if any mutations occured that require persisting.
8064     */
8065    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8066        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8067        if (perms == null) return false;
8068        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8069
8070        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8071        for (UriPermission perm : perms.values()) {
8072            if (perm.persistedModeFlags != 0) {
8073                persisted.add(perm);
8074            }
8075        }
8076
8077        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8078        if (trimCount <= 0) return false;
8079
8080        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8081        for (int i = 0; i < trimCount; i++) {
8082            final UriPermission perm = persisted.get(i);
8083
8084            if (DEBUG_URI_PERMISSION) {
8085                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8086            }
8087
8088            perm.releasePersistableModes(~0);
8089            removeUriPermissionIfNeededLocked(perm);
8090        }
8091
8092        return true;
8093    }
8094
8095    @Override
8096    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8097            String packageName, boolean incoming) {
8098        enforceNotIsolatedCaller("getPersistedUriPermissions");
8099        Preconditions.checkNotNull(packageName, "packageName");
8100
8101        final int callingUid = Binder.getCallingUid();
8102        final IPackageManager pm = AppGlobals.getPackageManager();
8103        try {
8104            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8105            if (packageUid != callingUid) {
8106                throw new SecurityException(
8107                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8108            }
8109        } catch (RemoteException e) {
8110            throw new SecurityException("Failed to verify package name ownership");
8111        }
8112
8113        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8114        synchronized (this) {
8115            if (incoming) {
8116                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8117                        callingUid);
8118                if (perms == null) {
8119                    Slog.w(TAG, "No permission grants found for " + packageName);
8120                } else {
8121                    for (UriPermission perm : perms.values()) {
8122                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8123                            result.add(perm.buildPersistedPublicApiObject());
8124                        }
8125                    }
8126                }
8127            } else {
8128                final int size = mGrantedUriPermissions.size();
8129                for (int i = 0; i < size; i++) {
8130                    final ArrayMap<GrantUri, UriPermission> perms =
8131                            mGrantedUriPermissions.valueAt(i);
8132                    for (UriPermission perm : perms.values()) {
8133                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8134                            result.add(perm.buildPersistedPublicApiObject());
8135                        }
8136                    }
8137                }
8138            }
8139        }
8140        return new ParceledListSlice<android.content.UriPermission>(result);
8141    }
8142
8143    @Override
8144    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8145        synchronized (this) {
8146            ProcessRecord app =
8147                who != null ? getRecordForAppLocked(who) : null;
8148            if (app == null) return;
8149
8150            Message msg = Message.obtain();
8151            msg.what = WAIT_FOR_DEBUGGER_MSG;
8152            msg.obj = app;
8153            msg.arg1 = waiting ? 1 : 0;
8154            mHandler.sendMessage(msg);
8155        }
8156    }
8157
8158    @Override
8159    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8160        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8161        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8162        outInfo.availMem = Process.getFreeMemory();
8163        outInfo.totalMem = Process.getTotalMemory();
8164        outInfo.threshold = homeAppMem;
8165        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8166        outInfo.hiddenAppThreshold = cachedAppMem;
8167        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8168                ProcessList.SERVICE_ADJ);
8169        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8170                ProcessList.VISIBLE_APP_ADJ);
8171        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8172                ProcessList.FOREGROUND_APP_ADJ);
8173    }
8174
8175    // =========================================================
8176    // TASK MANAGEMENT
8177    // =========================================================
8178
8179    @Override
8180    public List<IAppTask> getAppTasks(String callingPackage) {
8181        int callingUid = Binder.getCallingUid();
8182        long ident = Binder.clearCallingIdentity();
8183
8184        synchronized(this) {
8185            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8186            try {
8187                if (localLOGV) Slog.v(TAG, "getAppTasks");
8188
8189                final int N = mRecentTasks.size();
8190                for (int i = 0; i < N; i++) {
8191                    TaskRecord tr = mRecentTasks.get(i);
8192                    // Skip tasks that do not match the caller.  We don't need to verify
8193                    // callingPackage, because we are also limiting to callingUid and know
8194                    // that will limit to the correct security sandbox.
8195                    if (tr.effectiveUid != callingUid) {
8196                        continue;
8197                    }
8198                    Intent intent = tr.getBaseIntent();
8199                    if (intent == null ||
8200                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8201                        continue;
8202                    }
8203                    ActivityManager.RecentTaskInfo taskInfo =
8204                            createRecentTaskInfoFromTaskRecord(tr);
8205                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8206                    list.add(taskImpl);
8207                }
8208            } finally {
8209                Binder.restoreCallingIdentity(ident);
8210            }
8211            return list;
8212        }
8213    }
8214
8215    @Override
8216    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8217        final int callingUid = Binder.getCallingUid();
8218        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8219
8220        synchronized(this) {
8221            if (localLOGV) Slog.v(
8222                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8223
8224            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8225                    callingUid);
8226
8227            // TODO: Improve with MRU list from all ActivityStacks.
8228            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8229        }
8230
8231        return list;
8232    }
8233
8234    TaskRecord getMostRecentTask() {
8235        return mRecentTasks.get(0);
8236    }
8237
8238    /**
8239     * Creates a new RecentTaskInfo from a TaskRecord.
8240     */
8241    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8242        // Update the task description to reflect any changes in the task stack
8243        tr.updateTaskDescription();
8244
8245        // Compose the recent task info
8246        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8247        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8248        rti.persistentId = tr.taskId;
8249        rti.baseIntent = new Intent(tr.getBaseIntent());
8250        rti.origActivity = tr.origActivity;
8251        rti.description = tr.lastDescription;
8252        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8253        rti.userId = tr.userId;
8254        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8255        rti.firstActiveTime = tr.firstActiveTime;
8256        rti.lastActiveTime = tr.lastActiveTime;
8257        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8258        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8259        return rti;
8260    }
8261
8262    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8263        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8264                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8265        if (!allowed) {
8266            if (checkPermission(android.Manifest.permission.GET_TASKS,
8267                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8268                // Temporary compatibility: some existing apps on the system image may
8269                // still be requesting the old permission and not switched to the new
8270                // one; if so, we'll still allow them full access.  This means we need
8271                // to see if they are holding the old permission and are a system app.
8272                try {
8273                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8274                        allowed = true;
8275                        Slog.w(TAG, caller + ": caller " + callingUid
8276                                + " is using old GET_TASKS but privileged; allowing");
8277                    }
8278                } catch (RemoteException e) {
8279                }
8280            }
8281        }
8282        if (!allowed) {
8283            Slog.w(TAG, caller + ": caller " + callingUid
8284                    + " does not hold GET_TASKS; limiting output");
8285        }
8286        return allowed;
8287    }
8288
8289    @Override
8290    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8291        final int callingUid = Binder.getCallingUid();
8292        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8293                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8294
8295        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8296        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8297        synchronized (this) {
8298            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8299                    callingUid);
8300            final boolean detailed = checkCallingPermission(
8301                    android.Manifest.permission.GET_DETAILED_TASKS)
8302                    == PackageManager.PERMISSION_GRANTED;
8303
8304            final int N = mRecentTasks.size();
8305            ArrayList<ActivityManager.RecentTaskInfo> res
8306                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8307                            maxNum < N ? maxNum : N);
8308
8309            final Set<Integer> includedUsers;
8310            if (includeProfiles) {
8311                includedUsers = getProfileIdsLocked(userId);
8312            } else {
8313                includedUsers = new HashSet<Integer>();
8314            }
8315            includedUsers.add(Integer.valueOf(userId));
8316
8317            for (int i=0; i<N && maxNum > 0; i++) {
8318                TaskRecord tr = mRecentTasks.get(i);
8319                // Only add calling user or related users recent tasks
8320                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8321                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8322                    continue;
8323                }
8324
8325                // Return the entry if desired by the caller.  We always return
8326                // the first entry, because callers always expect this to be the
8327                // foreground app.  We may filter others if the caller has
8328                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8329                // we should exclude the entry.
8330
8331                if (i == 0
8332                        || withExcluded
8333                        || (tr.intent == null)
8334                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8335                                == 0)) {
8336                    if (!allowed) {
8337                        // If the caller doesn't have the GET_TASKS permission, then only
8338                        // allow them to see a small subset of tasks -- their own and home.
8339                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8340                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8341                            continue;
8342                        }
8343                    }
8344                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8345                        if (tr.stack != null && tr.stack.isHomeStack()) {
8346                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8347                            continue;
8348                        }
8349                    }
8350                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8351                        // Don't include auto remove tasks that are finished or finishing.
8352                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8353                                + tr);
8354                        continue;
8355                    }
8356                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8357                            && !tr.isAvailable) {
8358                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8359                        continue;
8360                    }
8361
8362                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8363                    if (!detailed) {
8364                        rti.baseIntent.replaceExtras((Bundle)null);
8365                    }
8366
8367                    res.add(rti);
8368                    maxNum--;
8369                }
8370            }
8371            return res;
8372        }
8373    }
8374
8375    private TaskRecord recentTaskForIdLocked(int id) {
8376        final int N = mRecentTasks.size();
8377            for (int i=0; i<N; i++) {
8378                TaskRecord tr = mRecentTasks.get(i);
8379                if (tr.taskId == id) {
8380                    return tr;
8381                }
8382            }
8383            return null;
8384    }
8385
8386    @Override
8387    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8388        synchronized (this) {
8389            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8390                    "getTaskThumbnail()");
8391            TaskRecord tr = recentTaskForIdLocked(id);
8392            if (tr != null) {
8393                return tr.getTaskThumbnailLocked();
8394            }
8395        }
8396        return null;
8397    }
8398
8399    @Override
8400    public int addAppTask(IBinder activityToken, Intent intent,
8401            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8402        final int callingUid = Binder.getCallingUid();
8403        final long callingIdent = Binder.clearCallingIdentity();
8404
8405        try {
8406            synchronized (this) {
8407                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8408                if (r == null) {
8409                    throw new IllegalArgumentException("Activity does not exist; token="
8410                            + activityToken);
8411                }
8412                ComponentName comp = intent.getComponent();
8413                if (comp == null) {
8414                    throw new IllegalArgumentException("Intent " + intent
8415                            + " must specify explicit component");
8416                }
8417                if (thumbnail.getWidth() != mThumbnailWidth
8418                        || thumbnail.getHeight() != mThumbnailHeight) {
8419                    throw new IllegalArgumentException("Bad thumbnail size: got "
8420                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8421                            + mThumbnailWidth + "x" + mThumbnailHeight);
8422                }
8423                if (intent.getSelector() != null) {
8424                    intent.setSelector(null);
8425                }
8426                if (intent.getSourceBounds() != null) {
8427                    intent.setSourceBounds(null);
8428                }
8429                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8430                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8431                        // The caller has added this as an auto-remove task...  that makes no
8432                        // sense, so turn off auto-remove.
8433                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8434                    }
8435                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8436                    // Must be a new task.
8437                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8438                }
8439                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8440                    mLastAddedTaskActivity = null;
8441                }
8442                ActivityInfo ainfo = mLastAddedTaskActivity;
8443                if (ainfo == null) {
8444                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8445                            comp, 0, UserHandle.getUserId(callingUid));
8446                    if (ainfo.applicationInfo.uid != callingUid) {
8447                        throw new SecurityException(
8448                                "Can't add task for another application: target uid="
8449                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8450                    }
8451                }
8452
8453                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8454                        intent, description);
8455
8456                int trimIdx = trimRecentsForTask(task, false);
8457                if (trimIdx >= 0) {
8458                    // If this would have caused a trim, then we'll abort because that
8459                    // means it would be added at the end of the list but then just removed.
8460                    return -1;
8461                }
8462
8463                final int N = mRecentTasks.size();
8464                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8465                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8466                    tr.removedFromRecents(mTaskPersister);
8467                }
8468
8469                task.inRecents = true;
8470                mRecentTasks.add(task);
8471                r.task.stack.addTask(task, false, false);
8472
8473                task.setLastThumbnail(thumbnail);
8474                task.freeLastThumbnail();
8475
8476                return task.taskId;
8477            }
8478        } finally {
8479            Binder.restoreCallingIdentity(callingIdent);
8480        }
8481    }
8482
8483    @Override
8484    public Point getAppTaskThumbnailSize() {
8485        synchronized (this) {
8486            return new Point(mThumbnailWidth,  mThumbnailHeight);
8487        }
8488    }
8489
8490    @Override
8491    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8492        synchronized (this) {
8493            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8494            if (r != null) {
8495                r.setTaskDescription(td);
8496                r.task.updateTaskDescription();
8497            }
8498        }
8499    }
8500
8501    @Override
8502    public Bitmap getTaskDescriptionIcon(String filename) {
8503        if (!FileUtils.isValidExtFilename(filename)
8504                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8505            throw new IllegalArgumentException("Bad filename: " + filename);
8506        }
8507        return mTaskPersister.getTaskDescriptionIcon(filename);
8508    }
8509
8510    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8511        mRecentTasks.remove(tr);
8512        tr.removedFromRecents(mTaskPersister);
8513        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8514        Intent baseIntent = new Intent(
8515                tr.intent != null ? tr.intent : tr.affinityIntent);
8516        ComponentName component = baseIntent.getComponent();
8517        if (component == null) {
8518            Slog.w(TAG, "Now component for base intent of task: " + tr);
8519            return;
8520        }
8521
8522        // Find any running services associated with this app.
8523        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8524
8525        if (killProcesses) {
8526            // Find any running processes associated with this app.
8527            final String pkg = component.getPackageName();
8528            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8529            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8530            for (int i=0; i<pmap.size(); i++) {
8531                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8532                for (int j=0; j<uids.size(); j++) {
8533                    ProcessRecord proc = uids.valueAt(j);
8534                    if (proc.userId != tr.userId) {
8535                        continue;
8536                    }
8537                    if (!proc.pkgList.containsKey(pkg)) {
8538                        continue;
8539                    }
8540                    procs.add(proc);
8541                }
8542            }
8543
8544            // Kill the running processes.
8545            for (int i=0; i<procs.size(); i++) {
8546                ProcessRecord pr = procs.get(i);
8547                if (pr == mHomeProcess) {
8548                    // Don't kill the home process along with tasks from the same package.
8549                    continue;
8550                }
8551                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8552                    pr.kill("remove task", true);
8553                } else {
8554                    pr.waitingToKill = "remove task";
8555                }
8556            }
8557        }
8558    }
8559
8560    /**
8561     * Removes the task with the specified task id.
8562     *
8563     * @param taskId Identifier of the task to be removed.
8564     * @param flags Additional operational flags.  May be 0 or
8565     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8566     * @return Returns true if the given task was found and removed.
8567     */
8568    private boolean removeTaskByIdLocked(int taskId, int flags) {
8569        TaskRecord tr = recentTaskForIdLocked(taskId);
8570        if (tr != null) {
8571            tr.removeTaskActivitiesLocked();
8572            cleanUpRemovedTaskLocked(tr, flags);
8573            if (tr.isPersistable) {
8574                notifyTaskPersisterLocked(null, true);
8575            }
8576            return true;
8577        }
8578        return false;
8579    }
8580
8581    @Override
8582    public boolean removeTask(int taskId, int flags) {
8583        synchronized (this) {
8584            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8585                    "removeTask()");
8586            long ident = Binder.clearCallingIdentity();
8587            try {
8588                return removeTaskByIdLocked(taskId, flags);
8589            } finally {
8590                Binder.restoreCallingIdentity(ident);
8591            }
8592        }
8593    }
8594
8595    /**
8596     * TODO: Add mController hook
8597     */
8598    @Override
8599    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8600        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8601                "moveTaskToFront()");
8602
8603        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8604        synchronized(this) {
8605            moveTaskToFrontLocked(taskId, flags, options);
8606        }
8607    }
8608
8609    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8610        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8611                Binder.getCallingUid(), -1, -1, "Task to front")) {
8612            ActivityOptions.abort(options);
8613            return;
8614        }
8615        final long origId = Binder.clearCallingIdentity();
8616        try {
8617            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8618            if (task == null) {
8619                return;
8620            }
8621            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8622                mStackSupervisor.showLockTaskToast();
8623                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8624                return;
8625            }
8626            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8627            if (prev != null && prev.isRecentsActivity()) {
8628                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8629            }
8630            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8631        } finally {
8632            Binder.restoreCallingIdentity(origId);
8633        }
8634        ActivityOptions.abort(options);
8635    }
8636
8637    @Override
8638    public void moveTaskToBack(int taskId) {
8639        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8640                "moveTaskToBack()");
8641
8642        synchronized(this) {
8643            TaskRecord tr = recentTaskForIdLocked(taskId);
8644            if (tr != null) {
8645                if (tr == mStackSupervisor.mLockTaskModeTask) {
8646                    mStackSupervisor.showLockTaskToast();
8647                    return;
8648                }
8649                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8650                ActivityStack stack = tr.stack;
8651                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8652                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8653                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8654                        return;
8655                    }
8656                }
8657                final long origId = Binder.clearCallingIdentity();
8658                try {
8659                    stack.moveTaskToBackLocked(taskId, null);
8660                } finally {
8661                    Binder.restoreCallingIdentity(origId);
8662                }
8663            }
8664        }
8665    }
8666
8667    /**
8668     * Moves an activity, and all of the other activities within the same task, to the bottom
8669     * of the history stack.  The activity's order within the task is unchanged.
8670     *
8671     * @param token A reference to the activity we wish to move
8672     * @param nonRoot If false then this only works if the activity is the root
8673     *                of a task; if true it will work for any activity in a task.
8674     * @return Returns true if the move completed, false if not.
8675     */
8676    @Override
8677    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8678        enforceNotIsolatedCaller("moveActivityTaskToBack");
8679        synchronized(this) {
8680            final long origId = Binder.clearCallingIdentity();
8681            try {
8682                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8683                if (taskId >= 0) {
8684                    if ((mStackSupervisor.mLockTaskModeTask != null)
8685                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8686                        mStackSupervisor.showLockTaskToast();
8687                        return false;
8688                    }
8689                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8690                }
8691            } finally {
8692                Binder.restoreCallingIdentity(origId);
8693            }
8694        }
8695        return false;
8696    }
8697
8698    @Override
8699    public void moveTaskBackwards(int task) {
8700        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8701                "moveTaskBackwards()");
8702
8703        synchronized(this) {
8704            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8705                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8706                return;
8707            }
8708            final long origId = Binder.clearCallingIdentity();
8709            moveTaskBackwardsLocked(task);
8710            Binder.restoreCallingIdentity(origId);
8711        }
8712    }
8713
8714    private final void moveTaskBackwardsLocked(int task) {
8715        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8716    }
8717
8718    @Override
8719    public IBinder getHomeActivityToken() throws RemoteException {
8720        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8721                "getHomeActivityToken()");
8722        synchronized (this) {
8723            return mStackSupervisor.getHomeActivityToken();
8724        }
8725    }
8726
8727    @Override
8728    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8729            IActivityContainerCallback callback) throws RemoteException {
8730        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8731                "createActivityContainer()");
8732        synchronized (this) {
8733            if (parentActivityToken == null) {
8734                throw new IllegalArgumentException("parent token must not be null");
8735            }
8736            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8737            if (r == null) {
8738                return null;
8739            }
8740            if (callback == null) {
8741                throw new IllegalArgumentException("callback must not be null");
8742            }
8743            return mStackSupervisor.createActivityContainer(r, callback);
8744        }
8745    }
8746
8747    @Override
8748    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8749        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8750                "deleteActivityContainer()");
8751        synchronized (this) {
8752            mStackSupervisor.deleteActivityContainer(container);
8753        }
8754    }
8755
8756    @Override
8757    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8758            throws RemoteException {
8759        synchronized (this) {
8760            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8761            if (stack != null) {
8762                return stack.mActivityContainer;
8763            }
8764            return null;
8765        }
8766    }
8767
8768    @Override
8769    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "moveTaskToStack()");
8772        if (stackId == HOME_STACK_ID) {
8773            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8774                    new RuntimeException("here").fillInStackTrace());
8775        }
8776        synchronized (this) {
8777            long ident = Binder.clearCallingIdentity();
8778            try {
8779                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8780                        + stackId + " toTop=" + toTop);
8781                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8782            } finally {
8783                Binder.restoreCallingIdentity(ident);
8784            }
8785        }
8786    }
8787
8788    @Override
8789    public void resizeStack(int stackBoxId, Rect bounds) {
8790        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8791                "resizeStackBox()");
8792        long ident = Binder.clearCallingIdentity();
8793        try {
8794            mWindowManager.resizeStack(stackBoxId, bounds);
8795        } finally {
8796            Binder.restoreCallingIdentity(ident);
8797        }
8798    }
8799
8800    @Override
8801    public List<StackInfo> getAllStackInfos() {
8802        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8803                "getAllStackInfos()");
8804        long ident = Binder.clearCallingIdentity();
8805        try {
8806            synchronized (this) {
8807                return mStackSupervisor.getAllStackInfosLocked();
8808            }
8809        } finally {
8810            Binder.restoreCallingIdentity(ident);
8811        }
8812    }
8813
8814    @Override
8815    public StackInfo getStackInfo(int stackId) {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "getStackInfo()");
8818        long ident = Binder.clearCallingIdentity();
8819        try {
8820            synchronized (this) {
8821                return mStackSupervisor.getStackInfoLocked(stackId);
8822            }
8823        } finally {
8824            Binder.restoreCallingIdentity(ident);
8825        }
8826    }
8827
8828    @Override
8829    public boolean isInHomeStack(int taskId) {
8830        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8831                "getStackInfo()");
8832        long ident = Binder.clearCallingIdentity();
8833        try {
8834            synchronized (this) {
8835                TaskRecord tr = recentTaskForIdLocked(taskId);
8836                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8837            }
8838        } finally {
8839            Binder.restoreCallingIdentity(ident);
8840        }
8841    }
8842
8843    @Override
8844    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8845        synchronized(this) {
8846            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8847        }
8848    }
8849
8850    private boolean isLockTaskAuthorized(String pkg) {
8851        final DevicePolicyManager dpm = (DevicePolicyManager)
8852                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8853        try {
8854            int uid = mContext.getPackageManager().getPackageUid(pkg,
8855                    Binder.getCallingUserHandle().getIdentifier());
8856            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8857        } catch (NameNotFoundException e) {
8858            return false;
8859        }
8860    }
8861
8862    void startLockTaskMode(TaskRecord task) {
8863        final String pkg;
8864        synchronized (this) {
8865            pkg = task.intent.getComponent().getPackageName();
8866        }
8867        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8868        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8869            final TaskRecord taskRecord = task;
8870            mHandler.post(new Runnable() {
8871                @Override
8872                public void run() {
8873                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8874                }
8875            });
8876            return;
8877        }
8878        long ident = Binder.clearCallingIdentity();
8879        try {
8880            synchronized (this) {
8881                // Since we lost lock on task, make sure it is still there.
8882                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8883                if (task != null) {
8884                    if (!isSystemInitiated
8885                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8886                        throw new IllegalArgumentException("Invalid task, not in foreground");
8887                    }
8888                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8889                }
8890            }
8891        } finally {
8892            Binder.restoreCallingIdentity(ident);
8893        }
8894    }
8895
8896    @Override
8897    public void startLockTaskMode(int taskId) {
8898        final TaskRecord task;
8899        long ident = Binder.clearCallingIdentity();
8900        try {
8901            synchronized (this) {
8902                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8903            }
8904        } finally {
8905            Binder.restoreCallingIdentity(ident);
8906        }
8907        if (task != null) {
8908            startLockTaskMode(task);
8909        }
8910    }
8911
8912    @Override
8913    public void startLockTaskMode(IBinder token) {
8914        final TaskRecord task;
8915        long ident = Binder.clearCallingIdentity();
8916        try {
8917            synchronized (this) {
8918                final ActivityRecord r = ActivityRecord.forToken(token);
8919                if (r == null) {
8920                    return;
8921                }
8922                task = r.task;
8923            }
8924        } finally {
8925            Binder.restoreCallingIdentity(ident);
8926        }
8927        if (task != null) {
8928            startLockTaskMode(task);
8929        }
8930    }
8931
8932    @Override
8933    public void startLockTaskModeOnCurrent() throws RemoteException {
8934        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8935                "startLockTaskModeOnCurrent");
8936        ActivityRecord r = null;
8937        synchronized (this) {
8938            r = mStackSupervisor.topRunningActivityLocked();
8939        }
8940        startLockTaskMode(r.task);
8941    }
8942
8943    @Override
8944    public void stopLockTaskMode() {
8945        // Verify that the user matches the package of the intent for the TaskRecord
8946        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8947        // and stopLockTaskMode.
8948        final int callingUid = Binder.getCallingUid();
8949        if (callingUid != Process.SYSTEM_UID) {
8950            try {
8951                String pkg =
8952                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8953                int uid = mContext.getPackageManager().getPackageUid(pkg,
8954                        Binder.getCallingUserHandle().getIdentifier());
8955                if (uid != callingUid) {
8956                    throw new SecurityException("Invalid uid, expected " + uid);
8957                }
8958            } catch (NameNotFoundException e) {
8959                Log.d(TAG, "stopLockTaskMode " + e);
8960                return;
8961            }
8962        }
8963        long ident = Binder.clearCallingIdentity();
8964        try {
8965            Log.d(TAG, "stopLockTaskMode");
8966            // Stop lock task
8967            synchronized (this) {
8968                mStackSupervisor.setLockTaskModeLocked(null, false);
8969            }
8970        } finally {
8971            Binder.restoreCallingIdentity(ident);
8972        }
8973    }
8974
8975    @Override
8976    public void stopLockTaskModeOnCurrent() throws RemoteException {
8977        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8978                "stopLockTaskModeOnCurrent");
8979        long ident = Binder.clearCallingIdentity();
8980        try {
8981            stopLockTaskMode();
8982        } finally {
8983            Binder.restoreCallingIdentity(ident);
8984        }
8985    }
8986
8987    @Override
8988    public boolean isInLockTaskMode() {
8989        synchronized (this) {
8990            return mStackSupervisor.isInLockTaskMode();
8991        }
8992    }
8993
8994    // =========================================================
8995    // CONTENT PROVIDERS
8996    // =========================================================
8997
8998    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8999        List<ProviderInfo> providers = null;
9000        try {
9001            providers = AppGlobals.getPackageManager().
9002                queryContentProviders(app.processName, app.uid,
9003                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9004        } catch (RemoteException ex) {
9005        }
9006        if (DEBUG_MU)
9007            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9008        int userId = app.userId;
9009        if (providers != null) {
9010            int N = providers.size();
9011            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9012            for (int i=0; i<N; i++) {
9013                ProviderInfo cpi =
9014                    (ProviderInfo)providers.get(i);
9015                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9016                        cpi.name, cpi.flags);
9017                if (singleton && UserHandle.getUserId(app.uid) != 0) {
9018                    // This is a singleton provider, but a user besides the
9019                    // default user is asking to initialize a process it runs
9020                    // in...  well, no, it doesn't actually run in this process,
9021                    // it runs in the process of the default user.  Get rid of it.
9022                    providers.remove(i);
9023                    N--;
9024                    i--;
9025                    continue;
9026                }
9027
9028                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9029                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9030                if (cpr == null) {
9031                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9032                    mProviderMap.putProviderByClass(comp, cpr);
9033                }
9034                if (DEBUG_MU)
9035                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9036                app.pubProviders.put(cpi.name, cpr);
9037                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9038                    // Don't add this if it is a platform component that is marked
9039                    // to run in multiple processes, because this is actually
9040                    // part of the framework so doesn't make sense to track as a
9041                    // separate apk in the process.
9042                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9043                            mProcessStats);
9044                }
9045                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9046            }
9047        }
9048        return providers;
9049    }
9050
9051    /**
9052     * Check if {@link ProcessRecord} has a possible chance at accessing the
9053     * given {@link ProviderInfo}. Final permission checking is always done
9054     * in {@link ContentProvider}.
9055     */
9056    private final String checkContentProviderPermissionLocked(
9057            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9058        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9059        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9060        boolean checkedGrants = false;
9061        if (checkUser) {
9062            // Looking for cross-user grants before enforcing the typical cross-users permissions
9063            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9064            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9065                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9066                    return null;
9067                }
9068                checkedGrants = true;
9069            }
9070            userId = handleIncomingUser(callingPid, callingUid, userId,
9071                    false, ALLOW_NON_FULL,
9072                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9073            if (userId != tmpTargetUserId) {
9074                // When we actually went to determine the final targer user ID, this ended
9075                // up different than our initial check for the authority.  This is because
9076                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9077                // SELF.  So we need to re-check the grants again.
9078                checkedGrants = false;
9079            }
9080        }
9081        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9082                cpi.applicationInfo.uid, cpi.exported)
9083                == PackageManager.PERMISSION_GRANTED) {
9084            return null;
9085        }
9086        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9087                cpi.applicationInfo.uid, cpi.exported)
9088                == PackageManager.PERMISSION_GRANTED) {
9089            return null;
9090        }
9091
9092        PathPermission[] pps = cpi.pathPermissions;
9093        if (pps != null) {
9094            int i = pps.length;
9095            while (i > 0) {
9096                i--;
9097                PathPermission pp = pps[i];
9098                String pprperm = pp.getReadPermission();
9099                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9100                        cpi.applicationInfo.uid, cpi.exported)
9101                        == PackageManager.PERMISSION_GRANTED) {
9102                    return null;
9103                }
9104                String ppwperm = pp.getWritePermission();
9105                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9106                        cpi.applicationInfo.uid, cpi.exported)
9107                        == PackageManager.PERMISSION_GRANTED) {
9108                    return null;
9109                }
9110            }
9111        }
9112        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9113            return null;
9114        }
9115
9116        String msg;
9117        if (!cpi.exported) {
9118            msg = "Permission Denial: opening provider " + cpi.name
9119                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9120                    + ", uid=" + callingUid + ") that is not exported from uid "
9121                    + cpi.applicationInfo.uid;
9122        } else {
9123            msg = "Permission Denial: opening provider " + cpi.name
9124                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9125                    + ", uid=" + callingUid + ") requires "
9126                    + cpi.readPermission + " or " + cpi.writePermission;
9127        }
9128        Slog.w(TAG, msg);
9129        return msg;
9130    }
9131
9132    /**
9133     * Returns if the ContentProvider has granted a uri to callingUid
9134     */
9135    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9136        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9137        if (perms != null) {
9138            for (int i=perms.size()-1; i>=0; i--) {
9139                GrantUri grantUri = perms.keyAt(i);
9140                if (grantUri.sourceUserId == userId || !checkUser) {
9141                    if (matchesProvider(grantUri.uri, cpi)) {
9142                        return true;
9143                    }
9144                }
9145            }
9146        }
9147        return false;
9148    }
9149
9150    /**
9151     * Returns true if the uri authority is one of the authorities specified in the provider.
9152     */
9153    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9154        String uriAuth = uri.getAuthority();
9155        String cpiAuth = cpi.authority;
9156        if (cpiAuth.indexOf(';') == -1) {
9157            return cpiAuth.equals(uriAuth);
9158        }
9159        String[] cpiAuths = cpiAuth.split(";");
9160        int length = cpiAuths.length;
9161        for (int i = 0; i < length; i++) {
9162            if (cpiAuths[i].equals(uriAuth)) return true;
9163        }
9164        return false;
9165    }
9166
9167    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9168            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9169        if (r != null) {
9170            for (int i=0; i<r.conProviders.size(); i++) {
9171                ContentProviderConnection conn = r.conProviders.get(i);
9172                if (conn.provider == cpr) {
9173                    if (DEBUG_PROVIDER) Slog.v(TAG,
9174                            "Adding provider requested by "
9175                            + r.processName + " from process "
9176                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9177                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9178                    if (stable) {
9179                        conn.stableCount++;
9180                        conn.numStableIncs++;
9181                    } else {
9182                        conn.unstableCount++;
9183                        conn.numUnstableIncs++;
9184                    }
9185                    return conn;
9186                }
9187            }
9188            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9189            if (stable) {
9190                conn.stableCount = 1;
9191                conn.numStableIncs = 1;
9192            } else {
9193                conn.unstableCount = 1;
9194                conn.numUnstableIncs = 1;
9195            }
9196            cpr.connections.add(conn);
9197            r.conProviders.add(conn);
9198            return conn;
9199        }
9200        cpr.addExternalProcessHandleLocked(externalProcessToken);
9201        return null;
9202    }
9203
9204    boolean decProviderCountLocked(ContentProviderConnection conn,
9205            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9206        if (conn != null) {
9207            cpr = conn.provider;
9208            if (DEBUG_PROVIDER) Slog.v(TAG,
9209                    "Removing provider requested by "
9210                    + conn.client.processName + " from process "
9211                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9212                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9213            if (stable) {
9214                conn.stableCount--;
9215            } else {
9216                conn.unstableCount--;
9217            }
9218            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9219                cpr.connections.remove(conn);
9220                conn.client.conProviders.remove(conn);
9221                return true;
9222            }
9223            return false;
9224        }
9225        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9226        return false;
9227    }
9228
9229    private void checkTime(long startTime, String where) {
9230        long now = SystemClock.elapsedRealtime();
9231        if ((now-startTime) > 1000) {
9232            // If we are taking more than a second, log about it.
9233            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9234        }
9235    }
9236
9237    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9238            String name, IBinder token, boolean stable, int userId) {
9239        ContentProviderRecord cpr;
9240        ContentProviderConnection conn = null;
9241        ProviderInfo cpi = null;
9242
9243        synchronized(this) {
9244            long startTime = SystemClock.elapsedRealtime();
9245
9246            ProcessRecord r = null;
9247            if (caller != null) {
9248                r = getRecordForAppLocked(caller);
9249                if (r == null) {
9250                    throw new SecurityException(
9251                            "Unable to find app for caller " + caller
9252                          + " (pid=" + Binder.getCallingPid()
9253                          + ") when getting content provider " + name);
9254                }
9255            }
9256
9257            boolean checkCrossUser = true;
9258
9259            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9260
9261            // First check if this content provider has been published...
9262            cpr = mProviderMap.getProviderByName(name, userId);
9263            // If that didn't work, check if it exists for user 0 and then
9264            // verify that it's a singleton provider before using it.
9265            if (cpr == null && userId != UserHandle.USER_OWNER) {
9266                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9267                if (cpr != null) {
9268                    cpi = cpr.info;
9269                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9270                            cpi.name, cpi.flags)
9271                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9272                        userId = UserHandle.USER_OWNER;
9273                        checkCrossUser = false;
9274                    } else {
9275                        cpr = null;
9276                        cpi = null;
9277                    }
9278                }
9279            }
9280
9281            boolean providerRunning = cpr != null;
9282            if (providerRunning) {
9283                cpi = cpr.info;
9284                String msg;
9285                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9286                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9287                        != null) {
9288                    throw new SecurityException(msg);
9289                }
9290                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9291
9292                if (r != null && cpr.canRunHere(r)) {
9293                    // This provider has been published or is in the process
9294                    // of being published...  but it is also allowed to run
9295                    // in the caller's process, so don't make a connection
9296                    // and just let the caller instantiate its own instance.
9297                    ContentProviderHolder holder = cpr.newHolder(null);
9298                    // don't give caller the provider object, it needs
9299                    // to make its own.
9300                    holder.provider = null;
9301                    return holder;
9302                }
9303
9304                final long origId = Binder.clearCallingIdentity();
9305
9306                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9307
9308                // In this case the provider instance already exists, so we can
9309                // return it right away.
9310                conn = incProviderCountLocked(r, cpr, token, stable);
9311                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9312                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9313                        // If this is a perceptible app accessing the provider,
9314                        // make sure to count it as being accessed and thus
9315                        // back up on the LRU list.  This is good because
9316                        // content providers are often expensive to start.
9317                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9318                        updateLruProcessLocked(cpr.proc, false, null);
9319                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9320                    }
9321                }
9322
9323                if (cpr.proc != null) {
9324                    if (false) {
9325                        if (cpr.name.flattenToShortString().equals(
9326                                "com.android.providers.calendar/.CalendarProvider2")) {
9327                            Slog.v(TAG, "****************** KILLING "
9328                                + cpr.name.flattenToShortString());
9329                            Process.killProcess(cpr.proc.pid);
9330                        }
9331                    }
9332                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9333                    boolean success = updateOomAdjLocked(cpr.proc);
9334                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9335                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9336                    // NOTE: there is still a race here where a signal could be
9337                    // pending on the process even though we managed to update its
9338                    // adj level.  Not sure what to do about this, but at least
9339                    // the race is now smaller.
9340                    if (!success) {
9341                        // Uh oh...  it looks like the provider's process
9342                        // has been killed on us.  We need to wait for a new
9343                        // process to be started, and make sure its death
9344                        // doesn't kill our process.
9345                        Slog.i(TAG,
9346                                "Existing provider " + cpr.name.flattenToShortString()
9347                                + " is crashing; detaching " + r);
9348                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9349                        checkTime(startTime, "getContentProviderImpl: before appDied");
9350                        appDiedLocked(cpr.proc);
9351                        checkTime(startTime, "getContentProviderImpl: after appDied");
9352                        if (!lastRef) {
9353                            // This wasn't the last ref our process had on
9354                            // the provider...  we have now been killed, bail.
9355                            return null;
9356                        }
9357                        providerRunning = false;
9358                        conn = null;
9359                    }
9360                }
9361
9362                Binder.restoreCallingIdentity(origId);
9363            }
9364
9365            boolean singleton;
9366            if (!providerRunning) {
9367                try {
9368                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9369                    cpi = AppGlobals.getPackageManager().
9370                        resolveContentProvider(name,
9371                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9372                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9373                } catch (RemoteException ex) {
9374                }
9375                if (cpi == null) {
9376                    return null;
9377                }
9378                // If the provider is a singleton AND
9379                // (it's a call within the same user || the provider is a
9380                // privileged app)
9381                // Then allow connecting to the singleton provider
9382                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9383                        cpi.name, cpi.flags)
9384                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9385                if (singleton) {
9386                    userId = UserHandle.USER_OWNER;
9387                }
9388                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9389                checkTime(startTime, "getContentProviderImpl: got app info for user");
9390
9391                String msg;
9392                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9393                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9394                        != null) {
9395                    throw new SecurityException(msg);
9396                }
9397                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9398
9399                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9400                        && !cpi.processName.equals("system")) {
9401                    // If this content provider does not run in the system
9402                    // process, and the system is not yet ready to run other
9403                    // processes, then fail fast instead of hanging.
9404                    throw new IllegalArgumentException(
9405                            "Attempt to launch content provider before system ready");
9406                }
9407
9408                // Make sure that the user who owns this provider is running.  If not,
9409                // we don't want to allow it to run.
9410                if (!isUserRunningLocked(userId, false)) {
9411                    Slog.w(TAG, "Unable to launch app "
9412                            + cpi.applicationInfo.packageName + "/"
9413                            + cpi.applicationInfo.uid + " for provider "
9414                            + name + ": user " + userId + " is stopped");
9415                    return null;
9416                }
9417
9418                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9419                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9420                cpr = mProviderMap.getProviderByClass(comp, userId);
9421                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9422                final boolean firstClass = cpr == null;
9423                if (firstClass) {
9424                    final long ident = Binder.clearCallingIdentity();
9425                    try {
9426                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9427                        ApplicationInfo ai =
9428                            AppGlobals.getPackageManager().
9429                                getApplicationInfo(
9430                                        cpi.applicationInfo.packageName,
9431                                        STOCK_PM_FLAGS, userId);
9432                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9433                        if (ai == null) {
9434                            Slog.w(TAG, "No package info for content provider "
9435                                    + cpi.name);
9436                            return null;
9437                        }
9438                        ai = getAppInfoForUser(ai, userId);
9439                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9440                    } catch (RemoteException ex) {
9441                        // pm is in same process, this will never happen.
9442                    } finally {
9443                        Binder.restoreCallingIdentity(ident);
9444                    }
9445                }
9446
9447                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9448
9449                if (r != null && cpr.canRunHere(r)) {
9450                    // If this is a multiprocess provider, then just return its
9451                    // info and allow the caller to instantiate it.  Only do
9452                    // this if the provider is the same user as the caller's
9453                    // process, or can run as root (so can be in any process).
9454                    return cpr.newHolder(null);
9455                }
9456
9457                if (DEBUG_PROVIDER) {
9458                    RuntimeException e = new RuntimeException("here");
9459                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9460                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9461                }
9462
9463                // This is single process, and our app is now connecting to it.
9464                // See if we are already in the process of launching this
9465                // provider.
9466                final int N = mLaunchingProviders.size();
9467                int i;
9468                for (i=0; i<N; i++) {
9469                    if (mLaunchingProviders.get(i) == cpr) {
9470                        break;
9471                    }
9472                }
9473
9474                // If the provider is not already being launched, then get it
9475                // started.
9476                if (i >= N) {
9477                    final long origId = Binder.clearCallingIdentity();
9478
9479                    try {
9480                        // Content provider is now in use, its package can't be stopped.
9481                        try {
9482                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9483                            AppGlobals.getPackageManager().setPackageStoppedState(
9484                                    cpr.appInfo.packageName, false, userId);
9485                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9486                        } catch (RemoteException e) {
9487                        } catch (IllegalArgumentException e) {
9488                            Slog.w(TAG, "Failed trying to unstop package "
9489                                    + cpr.appInfo.packageName + ": " + e);
9490                        }
9491
9492                        // Use existing process if already started
9493                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9494                        ProcessRecord proc = getProcessRecordLocked(
9495                                cpi.processName, cpr.appInfo.uid, false);
9496                        if (proc != null && proc.thread != null) {
9497                            if (DEBUG_PROVIDER) {
9498                                Slog.d(TAG, "Installing in existing process " + proc);
9499                            }
9500                            if (!proc.pubProviders.containsKey(cpi.name)) {
9501                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9502                                proc.pubProviders.put(cpi.name, cpr);
9503                                try {
9504                                    proc.thread.scheduleInstallProvider(cpi);
9505                                } catch (RemoteException e) {
9506                                }
9507                            }
9508                        } else {
9509                            checkTime(startTime, "getContentProviderImpl: before start process");
9510                            proc = startProcessLocked(cpi.processName,
9511                                    cpr.appInfo, false, 0, "content provider",
9512                                    new ComponentName(cpi.applicationInfo.packageName,
9513                                            cpi.name), false, false, false);
9514                            checkTime(startTime, "getContentProviderImpl: after start process");
9515                            if (proc == null) {
9516                                Slog.w(TAG, "Unable to launch app "
9517                                        + cpi.applicationInfo.packageName + "/"
9518                                        + cpi.applicationInfo.uid + " for provider "
9519                                        + name + ": process is bad");
9520                                return null;
9521                            }
9522                        }
9523                        cpr.launchingApp = proc;
9524                        mLaunchingProviders.add(cpr);
9525                    } finally {
9526                        Binder.restoreCallingIdentity(origId);
9527                    }
9528                }
9529
9530                checkTime(startTime, "getContentProviderImpl: updating data structures");
9531
9532                // Make sure the provider is published (the same provider class
9533                // may be published under multiple names).
9534                if (firstClass) {
9535                    mProviderMap.putProviderByClass(comp, cpr);
9536                }
9537
9538                mProviderMap.putProviderByName(name, cpr);
9539                conn = incProviderCountLocked(r, cpr, token, stable);
9540                if (conn != null) {
9541                    conn.waiting = true;
9542                }
9543            }
9544            checkTime(startTime, "getContentProviderImpl: done!");
9545        }
9546
9547        // Wait for the provider to be published...
9548        synchronized (cpr) {
9549            while (cpr.provider == null) {
9550                if (cpr.launchingApp == null) {
9551                    Slog.w(TAG, "Unable to launch app "
9552                            + cpi.applicationInfo.packageName + "/"
9553                            + cpi.applicationInfo.uid + " for provider "
9554                            + name + ": launching app became null");
9555                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9556                            UserHandle.getUserId(cpi.applicationInfo.uid),
9557                            cpi.applicationInfo.packageName,
9558                            cpi.applicationInfo.uid, name);
9559                    return null;
9560                }
9561                try {
9562                    if (DEBUG_MU) {
9563                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9564                                + cpr.launchingApp);
9565                    }
9566                    if (conn != null) {
9567                        conn.waiting = true;
9568                    }
9569                    cpr.wait();
9570                } catch (InterruptedException ex) {
9571                } finally {
9572                    if (conn != null) {
9573                        conn.waiting = false;
9574                    }
9575                }
9576            }
9577        }
9578        return cpr != null ? cpr.newHolder(conn) : null;
9579    }
9580
9581    @Override
9582    public final ContentProviderHolder getContentProvider(
9583            IApplicationThread caller, String name, int userId, boolean stable) {
9584        enforceNotIsolatedCaller("getContentProvider");
9585        if (caller == null) {
9586            String msg = "null IApplicationThread when getting content provider "
9587                    + name;
9588            Slog.w(TAG, msg);
9589            throw new SecurityException(msg);
9590        }
9591        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9592        // with cross-user grant.
9593        return getContentProviderImpl(caller, name, null, stable, userId);
9594    }
9595
9596    public ContentProviderHolder getContentProviderExternal(
9597            String name, int userId, IBinder token) {
9598        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9599            "Do not have permission in call getContentProviderExternal()");
9600        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9601                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9602        return getContentProviderExternalUnchecked(name, token, userId);
9603    }
9604
9605    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9606            IBinder token, int userId) {
9607        return getContentProviderImpl(null, name, token, true, userId);
9608    }
9609
9610    /**
9611     * Drop a content provider from a ProcessRecord's bookkeeping
9612     */
9613    public void removeContentProvider(IBinder connection, boolean stable) {
9614        enforceNotIsolatedCaller("removeContentProvider");
9615        long ident = Binder.clearCallingIdentity();
9616        try {
9617            synchronized (this) {
9618                ContentProviderConnection conn;
9619                try {
9620                    conn = (ContentProviderConnection)connection;
9621                } catch (ClassCastException e) {
9622                    String msg ="removeContentProvider: " + connection
9623                            + " not a ContentProviderConnection";
9624                    Slog.w(TAG, msg);
9625                    throw new IllegalArgumentException(msg);
9626                }
9627                if (conn == null) {
9628                    throw new NullPointerException("connection is null");
9629                }
9630                if (decProviderCountLocked(conn, null, null, stable)) {
9631                    updateOomAdjLocked();
9632                }
9633            }
9634        } finally {
9635            Binder.restoreCallingIdentity(ident);
9636        }
9637    }
9638
9639    public void removeContentProviderExternal(String name, IBinder token) {
9640        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9641            "Do not have permission in call removeContentProviderExternal()");
9642        int userId = UserHandle.getCallingUserId();
9643        long ident = Binder.clearCallingIdentity();
9644        try {
9645            removeContentProviderExternalUnchecked(name, token, userId);
9646        } finally {
9647            Binder.restoreCallingIdentity(ident);
9648        }
9649    }
9650
9651    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9652        synchronized (this) {
9653            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9654            if(cpr == null) {
9655                //remove from mProvidersByClass
9656                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9657                return;
9658            }
9659
9660            //update content provider record entry info
9661            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9662            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9663            if (localCpr.hasExternalProcessHandles()) {
9664                if (localCpr.removeExternalProcessHandleLocked(token)) {
9665                    updateOomAdjLocked();
9666                } else {
9667                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9668                            + " with no external reference for token: "
9669                            + token + ".");
9670                }
9671            } else {
9672                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9673                        + " with no external references.");
9674            }
9675        }
9676    }
9677
9678    public final void publishContentProviders(IApplicationThread caller,
9679            List<ContentProviderHolder> providers) {
9680        if (providers == null) {
9681            return;
9682        }
9683
9684        enforceNotIsolatedCaller("publishContentProviders");
9685        synchronized (this) {
9686            final ProcessRecord r = getRecordForAppLocked(caller);
9687            if (DEBUG_MU)
9688                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9689            if (r == null) {
9690                throw new SecurityException(
9691                        "Unable to find app for caller " + caller
9692                      + " (pid=" + Binder.getCallingPid()
9693                      + ") when publishing content providers");
9694            }
9695
9696            final long origId = Binder.clearCallingIdentity();
9697
9698            final int N = providers.size();
9699            for (int i=0; i<N; i++) {
9700                ContentProviderHolder src = providers.get(i);
9701                if (src == null || src.info == null || src.provider == null) {
9702                    continue;
9703                }
9704                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9705                if (DEBUG_MU)
9706                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9707                if (dst != null) {
9708                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9709                    mProviderMap.putProviderByClass(comp, dst);
9710                    String names[] = dst.info.authority.split(";");
9711                    for (int j = 0; j < names.length; j++) {
9712                        mProviderMap.putProviderByName(names[j], dst);
9713                    }
9714
9715                    int NL = mLaunchingProviders.size();
9716                    int j;
9717                    for (j=0; j<NL; j++) {
9718                        if (mLaunchingProviders.get(j) == dst) {
9719                            mLaunchingProviders.remove(j);
9720                            j--;
9721                            NL--;
9722                        }
9723                    }
9724                    synchronized (dst) {
9725                        dst.provider = src.provider;
9726                        dst.proc = r;
9727                        dst.notifyAll();
9728                    }
9729                    updateOomAdjLocked(r);
9730                }
9731            }
9732
9733            Binder.restoreCallingIdentity(origId);
9734        }
9735    }
9736
9737    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9738        ContentProviderConnection conn;
9739        try {
9740            conn = (ContentProviderConnection)connection;
9741        } catch (ClassCastException e) {
9742            String msg ="refContentProvider: " + connection
9743                    + " not a ContentProviderConnection";
9744            Slog.w(TAG, msg);
9745            throw new IllegalArgumentException(msg);
9746        }
9747        if (conn == null) {
9748            throw new NullPointerException("connection is null");
9749        }
9750
9751        synchronized (this) {
9752            if (stable > 0) {
9753                conn.numStableIncs += stable;
9754            }
9755            stable = conn.stableCount + stable;
9756            if (stable < 0) {
9757                throw new IllegalStateException("stableCount < 0: " + stable);
9758            }
9759
9760            if (unstable > 0) {
9761                conn.numUnstableIncs += unstable;
9762            }
9763            unstable = conn.unstableCount + unstable;
9764            if (unstable < 0) {
9765                throw new IllegalStateException("unstableCount < 0: " + unstable);
9766            }
9767
9768            if ((stable+unstable) <= 0) {
9769                throw new IllegalStateException("ref counts can't go to zero here: stable="
9770                        + stable + " unstable=" + unstable);
9771            }
9772            conn.stableCount = stable;
9773            conn.unstableCount = unstable;
9774            return !conn.dead;
9775        }
9776    }
9777
9778    public void unstableProviderDied(IBinder connection) {
9779        ContentProviderConnection conn;
9780        try {
9781            conn = (ContentProviderConnection)connection;
9782        } catch (ClassCastException e) {
9783            String msg ="refContentProvider: " + connection
9784                    + " not a ContentProviderConnection";
9785            Slog.w(TAG, msg);
9786            throw new IllegalArgumentException(msg);
9787        }
9788        if (conn == null) {
9789            throw new NullPointerException("connection is null");
9790        }
9791
9792        // Safely retrieve the content provider associated with the connection.
9793        IContentProvider provider;
9794        synchronized (this) {
9795            provider = conn.provider.provider;
9796        }
9797
9798        if (provider == null) {
9799            // Um, yeah, we're way ahead of you.
9800            return;
9801        }
9802
9803        // Make sure the caller is being honest with us.
9804        if (provider.asBinder().pingBinder()) {
9805            // Er, no, still looks good to us.
9806            synchronized (this) {
9807                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9808                        + " says " + conn + " died, but we don't agree");
9809                return;
9810            }
9811        }
9812
9813        // Well look at that!  It's dead!
9814        synchronized (this) {
9815            if (conn.provider.provider != provider) {
9816                // But something changed...  good enough.
9817                return;
9818            }
9819
9820            ProcessRecord proc = conn.provider.proc;
9821            if (proc == null || proc.thread == null) {
9822                // Seems like the process is already cleaned up.
9823                return;
9824            }
9825
9826            // As far as we're concerned, this is just like receiving a
9827            // death notification...  just a bit prematurely.
9828            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9829                    + ") early provider death");
9830            final long ident = Binder.clearCallingIdentity();
9831            try {
9832                appDiedLocked(proc);
9833            } finally {
9834                Binder.restoreCallingIdentity(ident);
9835            }
9836        }
9837    }
9838
9839    @Override
9840    public void appNotRespondingViaProvider(IBinder connection) {
9841        enforceCallingPermission(
9842                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9843
9844        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9845        if (conn == null) {
9846            Slog.w(TAG, "ContentProviderConnection is null");
9847            return;
9848        }
9849
9850        final ProcessRecord host = conn.provider.proc;
9851        if (host == null) {
9852            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9853            return;
9854        }
9855
9856        final long token = Binder.clearCallingIdentity();
9857        try {
9858            appNotResponding(host, null, null, false, "ContentProvider not responding");
9859        } finally {
9860            Binder.restoreCallingIdentity(token);
9861        }
9862    }
9863
9864    public final void installSystemProviders() {
9865        List<ProviderInfo> providers;
9866        synchronized (this) {
9867            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9868            providers = generateApplicationProvidersLocked(app);
9869            if (providers != null) {
9870                for (int i=providers.size()-1; i>=0; i--) {
9871                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9872                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9873                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9874                                + ": not system .apk");
9875                        providers.remove(i);
9876                    }
9877                }
9878            }
9879        }
9880        if (providers != null) {
9881            mSystemThread.installSystemProviders(providers);
9882        }
9883
9884        mCoreSettingsObserver = new CoreSettingsObserver(this);
9885
9886        //mUsageStatsService.monitorPackages();
9887    }
9888
9889    /**
9890     * Allows apps to retrieve the MIME type of a URI.
9891     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9892     * users, then it does not need permission to access the ContentProvider.
9893     * Either, it needs cross-user uri grants.
9894     *
9895     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9896     *
9897     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9898     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9899     */
9900    public String getProviderMimeType(Uri uri, int userId) {
9901        enforceNotIsolatedCaller("getProviderMimeType");
9902        final String name = uri.getAuthority();
9903        int callingUid = Binder.getCallingUid();
9904        int callingPid = Binder.getCallingPid();
9905        long ident = 0;
9906        boolean clearedIdentity = false;
9907        userId = unsafeConvertIncomingUser(userId);
9908        if (canClearIdentity(callingPid, callingUid, userId)) {
9909            clearedIdentity = true;
9910            ident = Binder.clearCallingIdentity();
9911        }
9912        ContentProviderHolder holder = null;
9913        try {
9914            holder = getContentProviderExternalUnchecked(name, null, userId);
9915            if (holder != null) {
9916                return holder.provider.getType(uri);
9917            }
9918        } catch (RemoteException e) {
9919            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9920            return null;
9921        } finally {
9922            // We need to clear the identity to call removeContentProviderExternalUnchecked
9923            if (!clearedIdentity) {
9924                ident = Binder.clearCallingIdentity();
9925            }
9926            try {
9927                if (holder != null) {
9928                    removeContentProviderExternalUnchecked(name, null, userId);
9929                }
9930            } finally {
9931                Binder.restoreCallingIdentity(ident);
9932            }
9933        }
9934
9935        return null;
9936    }
9937
9938    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9939        if (UserHandle.getUserId(callingUid) == userId) {
9940            return true;
9941        }
9942        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9943                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9944                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9945                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9946                return true;
9947        }
9948        return false;
9949    }
9950
9951    // =========================================================
9952    // GLOBAL MANAGEMENT
9953    // =========================================================
9954
9955    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9956            boolean isolated, int isolatedUid) {
9957        String proc = customProcess != null ? customProcess : info.processName;
9958        BatteryStatsImpl.Uid.Proc ps = null;
9959        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9960        int uid = info.uid;
9961        if (isolated) {
9962            if (isolatedUid == 0) {
9963                int userId = UserHandle.getUserId(uid);
9964                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9965                while (true) {
9966                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9967                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9968                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9969                    }
9970                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9971                    mNextIsolatedProcessUid++;
9972                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9973                        // No process for this uid, use it.
9974                        break;
9975                    }
9976                    stepsLeft--;
9977                    if (stepsLeft <= 0) {
9978                        return null;
9979                    }
9980                }
9981            } else {
9982                // Special case for startIsolatedProcess (internal only), where
9983                // the uid of the isolated process is specified by the caller.
9984                uid = isolatedUid;
9985            }
9986        }
9987        return new ProcessRecord(stats, info, proc, uid);
9988    }
9989
9990    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9991            String abiOverride) {
9992        ProcessRecord app;
9993        if (!isolated) {
9994            app = getProcessRecordLocked(info.processName, info.uid, true);
9995        } else {
9996            app = null;
9997        }
9998
9999        if (app == null) {
10000            app = newProcessRecordLocked(info, null, isolated, 0);
10001            mProcessNames.put(info.processName, app.uid, app);
10002            if (isolated) {
10003                mIsolatedProcesses.put(app.uid, app);
10004            }
10005            updateLruProcessLocked(app, false, null);
10006            updateOomAdjLocked();
10007        }
10008
10009        // This package really, really can not be stopped.
10010        try {
10011            AppGlobals.getPackageManager().setPackageStoppedState(
10012                    info.packageName, false, UserHandle.getUserId(app.uid));
10013        } catch (RemoteException e) {
10014        } catch (IllegalArgumentException e) {
10015            Slog.w(TAG, "Failed trying to unstop package "
10016                    + info.packageName + ": " + e);
10017        }
10018
10019        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
10020                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
10021            app.persistent = true;
10022            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10023        }
10024        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10025            mPersistentStartingProcesses.add(app);
10026            startProcessLocked(app, "added application", app.processName, abiOverride,
10027                    null /* entryPoint */, null /* entryPointArgs */);
10028        }
10029
10030        return app;
10031    }
10032
10033    public void unhandledBack() {
10034        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10035                "unhandledBack()");
10036
10037        synchronized(this) {
10038            final long origId = Binder.clearCallingIdentity();
10039            try {
10040                getFocusedStack().unhandledBackLocked();
10041            } finally {
10042                Binder.restoreCallingIdentity(origId);
10043            }
10044        }
10045    }
10046
10047    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10048        enforceNotIsolatedCaller("openContentUri");
10049        final int userId = UserHandle.getCallingUserId();
10050        String name = uri.getAuthority();
10051        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10052        ParcelFileDescriptor pfd = null;
10053        if (cph != null) {
10054            // We record the binder invoker's uid in thread-local storage before
10055            // going to the content provider to open the file.  Later, in the code
10056            // that handles all permissions checks, we look for this uid and use
10057            // that rather than the Activity Manager's own uid.  The effect is that
10058            // we do the check against the caller's permissions even though it looks
10059            // to the content provider like the Activity Manager itself is making
10060            // the request.
10061            sCallerIdentity.set(new Identity(
10062                    Binder.getCallingPid(), Binder.getCallingUid()));
10063            try {
10064                pfd = cph.provider.openFile(null, uri, "r", null);
10065            } catch (FileNotFoundException e) {
10066                // do nothing; pfd will be returned null
10067            } finally {
10068                // Ensure that whatever happens, we clean up the identity state
10069                sCallerIdentity.remove();
10070                // Ensure we're done with the provider.
10071                removeContentProviderExternalUnchecked(name, null, userId);
10072            }
10073        } else {
10074            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10075        }
10076        return pfd;
10077    }
10078
10079    // Actually is sleeping or shutting down or whatever else in the future
10080    // is an inactive state.
10081    public boolean isSleepingOrShuttingDown() {
10082        return isSleeping() || mShuttingDown;
10083    }
10084
10085    public boolean isSleeping() {
10086        return mSleeping;
10087    }
10088
10089    void goingToSleep() {
10090        synchronized(this) {
10091            mWentToSleep = true;
10092            goToSleepIfNeededLocked();
10093        }
10094    }
10095
10096    void finishRunningVoiceLocked() {
10097        if (mRunningVoice) {
10098            mRunningVoice = false;
10099            goToSleepIfNeededLocked();
10100        }
10101    }
10102
10103    void goToSleepIfNeededLocked() {
10104        if (mWentToSleep && !mRunningVoice) {
10105            if (!mSleeping) {
10106                mSleeping = true;
10107                mStackSupervisor.goingToSleepLocked();
10108
10109                // Initialize the wake times of all processes.
10110                checkExcessivePowerUsageLocked(false);
10111                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10112                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10113                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10114            }
10115        }
10116    }
10117
10118    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10119        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10120            // Never persist the home stack.
10121            return;
10122        }
10123        mTaskPersister.wakeup(task, flush);
10124    }
10125
10126    @Override
10127    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10128        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10129    }
10130
10131    @Override
10132    public boolean shutdown(int timeout) {
10133        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10134                != PackageManager.PERMISSION_GRANTED) {
10135            throw new SecurityException("Requires permission "
10136                    + android.Manifest.permission.SHUTDOWN);
10137        }
10138
10139        boolean timedout = false;
10140
10141        synchronized(this) {
10142            mShuttingDown = true;
10143            updateEventDispatchingLocked();
10144            timedout = mStackSupervisor.shutdownLocked(timeout);
10145        }
10146
10147        mAppOpsService.shutdown();
10148        if (mUsageStatsService != null) {
10149            mUsageStatsService.prepareShutdown();
10150        }
10151        mBatteryStatsService.shutdown();
10152        synchronized (this) {
10153            mProcessStats.shutdownLocked();
10154        }
10155        notifyTaskPersisterLocked(null, true);
10156
10157        return timedout;
10158    }
10159
10160    public final void activitySlept(IBinder token) {
10161        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10162
10163        final long origId = Binder.clearCallingIdentity();
10164
10165        synchronized (this) {
10166            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10167            if (r != null) {
10168                mStackSupervisor.activitySleptLocked(r);
10169            }
10170        }
10171
10172        Binder.restoreCallingIdentity(origId);
10173    }
10174
10175    void logLockScreen(String msg) {
10176        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10177                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10178                mWentToSleep + " mSleeping=" + mSleeping);
10179    }
10180
10181    private void comeOutOfSleepIfNeededLocked() {
10182        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10183            if (mSleeping) {
10184                mSleeping = false;
10185                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10186            }
10187        }
10188    }
10189
10190    void wakingUp() {
10191        synchronized(this) {
10192            mWentToSleep = false;
10193            comeOutOfSleepIfNeededLocked();
10194        }
10195    }
10196
10197    void startRunningVoiceLocked() {
10198        if (!mRunningVoice) {
10199            mRunningVoice = true;
10200            comeOutOfSleepIfNeededLocked();
10201        }
10202    }
10203
10204    private void updateEventDispatchingLocked() {
10205        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10206    }
10207
10208    public void setLockScreenShown(boolean shown) {
10209        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10210                != PackageManager.PERMISSION_GRANTED) {
10211            throw new SecurityException("Requires permission "
10212                    + android.Manifest.permission.DEVICE_POWER);
10213        }
10214
10215        synchronized(this) {
10216            long ident = Binder.clearCallingIdentity();
10217            try {
10218                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10219                mLockScreenShown = shown;
10220                comeOutOfSleepIfNeededLocked();
10221            } finally {
10222                Binder.restoreCallingIdentity(ident);
10223            }
10224        }
10225    }
10226
10227    @Override
10228    public void stopAppSwitches() {
10229        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10230                != PackageManager.PERMISSION_GRANTED) {
10231            throw new SecurityException("Requires permission "
10232                    + android.Manifest.permission.STOP_APP_SWITCHES);
10233        }
10234
10235        synchronized(this) {
10236            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10237                    + APP_SWITCH_DELAY_TIME;
10238            mDidAppSwitch = false;
10239            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10240            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10241            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10242        }
10243    }
10244
10245    public void resumeAppSwitches() {
10246        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10247                != PackageManager.PERMISSION_GRANTED) {
10248            throw new SecurityException("Requires permission "
10249                    + android.Manifest.permission.STOP_APP_SWITCHES);
10250        }
10251
10252        synchronized(this) {
10253            // Note that we don't execute any pending app switches... we will
10254            // let those wait until either the timeout, or the next start
10255            // activity request.
10256            mAppSwitchesAllowedTime = 0;
10257        }
10258    }
10259
10260    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10261            int callingPid, int callingUid, String name) {
10262        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10263            return true;
10264        }
10265
10266        int perm = checkComponentPermission(
10267                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10268                sourceUid, -1, true);
10269        if (perm == PackageManager.PERMISSION_GRANTED) {
10270            return true;
10271        }
10272
10273        // If the actual IPC caller is different from the logical source, then
10274        // also see if they are allowed to control app switches.
10275        if (callingUid != -1 && callingUid != sourceUid) {
10276            perm = checkComponentPermission(
10277                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10278                    callingUid, -1, true);
10279            if (perm == PackageManager.PERMISSION_GRANTED) {
10280                return true;
10281            }
10282        }
10283
10284        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10285        return false;
10286    }
10287
10288    public void setDebugApp(String packageName, boolean waitForDebugger,
10289            boolean persistent) {
10290        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10291                "setDebugApp()");
10292
10293        long ident = Binder.clearCallingIdentity();
10294        try {
10295            // Note that this is not really thread safe if there are multiple
10296            // callers into it at the same time, but that's not a situation we
10297            // care about.
10298            if (persistent) {
10299                final ContentResolver resolver = mContext.getContentResolver();
10300                Settings.Global.putString(
10301                    resolver, Settings.Global.DEBUG_APP,
10302                    packageName);
10303                Settings.Global.putInt(
10304                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10305                    waitForDebugger ? 1 : 0);
10306            }
10307
10308            synchronized (this) {
10309                if (!persistent) {
10310                    mOrigDebugApp = mDebugApp;
10311                    mOrigWaitForDebugger = mWaitForDebugger;
10312                }
10313                mDebugApp = packageName;
10314                mWaitForDebugger = waitForDebugger;
10315                mDebugTransient = !persistent;
10316                if (packageName != null) {
10317                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10318                            false, UserHandle.USER_ALL, "set debug app");
10319                }
10320            }
10321        } finally {
10322            Binder.restoreCallingIdentity(ident);
10323        }
10324    }
10325
10326    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10327        synchronized (this) {
10328            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10329            if (!isDebuggable) {
10330                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10331                    throw new SecurityException("Process not debuggable: " + app.packageName);
10332                }
10333            }
10334
10335            mOpenGlTraceApp = processName;
10336        }
10337    }
10338
10339    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10340        synchronized (this) {
10341            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10342            if (!isDebuggable) {
10343                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10344                    throw new SecurityException("Process not debuggable: " + app.packageName);
10345                }
10346            }
10347            mProfileApp = processName;
10348            mProfileFile = profilerInfo.profileFile;
10349            if (mProfileFd != null) {
10350                try {
10351                    mProfileFd.close();
10352                } catch (IOException e) {
10353                }
10354                mProfileFd = null;
10355            }
10356            mProfileFd = profilerInfo.profileFd;
10357            mSamplingInterval = profilerInfo.samplingInterval;
10358            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10359            mProfileType = 0;
10360        }
10361    }
10362
10363    @Override
10364    public void setAlwaysFinish(boolean enabled) {
10365        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10366                "setAlwaysFinish()");
10367
10368        Settings.Global.putInt(
10369                mContext.getContentResolver(),
10370                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10371
10372        synchronized (this) {
10373            mAlwaysFinishActivities = enabled;
10374        }
10375    }
10376
10377    @Override
10378    public void setActivityController(IActivityController controller) {
10379        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10380                "setActivityController()");
10381        synchronized (this) {
10382            mController = controller;
10383            Watchdog.getInstance().setActivityController(controller);
10384        }
10385    }
10386
10387    @Override
10388    public void setUserIsMonkey(boolean userIsMonkey) {
10389        synchronized (this) {
10390            synchronized (mPidsSelfLocked) {
10391                final int callingPid = Binder.getCallingPid();
10392                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10393                if (precessRecord == null) {
10394                    throw new SecurityException("Unknown process: " + callingPid);
10395                }
10396                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10397                    throw new SecurityException("Only an instrumentation process "
10398                            + "with a UiAutomation can call setUserIsMonkey");
10399                }
10400            }
10401            mUserIsMonkey = userIsMonkey;
10402        }
10403    }
10404
10405    @Override
10406    public boolean isUserAMonkey() {
10407        synchronized (this) {
10408            // If there is a controller also implies the user is a monkey.
10409            return (mUserIsMonkey || mController != null);
10410        }
10411    }
10412
10413    public void requestBugReport() {
10414        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10415        SystemProperties.set("ctl.start", "bugreport");
10416    }
10417
10418    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10419        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10420    }
10421
10422    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10423        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10424            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10425        }
10426        return KEY_DISPATCHING_TIMEOUT;
10427    }
10428
10429    @Override
10430    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10431        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10432                != PackageManager.PERMISSION_GRANTED) {
10433            throw new SecurityException("Requires permission "
10434                    + android.Manifest.permission.FILTER_EVENTS);
10435        }
10436        ProcessRecord proc;
10437        long timeout;
10438        synchronized (this) {
10439            synchronized (mPidsSelfLocked) {
10440                proc = mPidsSelfLocked.get(pid);
10441            }
10442            timeout = getInputDispatchingTimeoutLocked(proc);
10443        }
10444
10445        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10446            return -1;
10447        }
10448
10449        return timeout;
10450    }
10451
10452    /**
10453     * Handle input dispatching timeouts.
10454     * Returns whether input dispatching should be aborted or not.
10455     */
10456    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10457            final ActivityRecord activity, final ActivityRecord parent,
10458            final boolean aboveSystem, String reason) {
10459        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10460                != PackageManager.PERMISSION_GRANTED) {
10461            throw new SecurityException("Requires permission "
10462                    + android.Manifest.permission.FILTER_EVENTS);
10463        }
10464
10465        final String annotation;
10466        if (reason == null) {
10467            annotation = "Input dispatching timed out";
10468        } else {
10469            annotation = "Input dispatching timed out (" + reason + ")";
10470        }
10471
10472        if (proc != null) {
10473            synchronized (this) {
10474                if (proc.debugging) {
10475                    return false;
10476                }
10477
10478                if (mDidDexOpt) {
10479                    // Give more time since we were dexopting.
10480                    mDidDexOpt = false;
10481                    return false;
10482                }
10483
10484                if (proc.instrumentationClass != null) {
10485                    Bundle info = new Bundle();
10486                    info.putString("shortMsg", "keyDispatchingTimedOut");
10487                    info.putString("longMsg", annotation);
10488                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10489                    return true;
10490                }
10491            }
10492            mHandler.post(new Runnable() {
10493                @Override
10494                public void run() {
10495                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10496                }
10497            });
10498        }
10499
10500        return true;
10501    }
10502
10503    public Bundle getAssistContextExtras(int requestType) {
10504        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10505                UserHandle.getCallingUserId());
10506        if (pae == null) {
10507            return null;
10508        }
10509        synchronized (pae) {
10510            while (!pae.haveResult) {
10511                try {
10512                    pae.wait();
10513                } catch (InterruptedException e) {
10514                }
10515            }
10516            if (pae.result != null) {
10517                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10518            }
10519        }
10520        synchronized (this) {
10521            mPendingAssistExtras.remove(pae);
10522            mHandler.removeCallbacks(pae);
10523        }
10524        return pae.extras;
10525    }
10526
10527    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10528            int userHandle) {
10529        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10530                "getAssistContextExtras()");
10531        PendingAssistExtras pae;
10532        Bundle extras = new Bundle();
10533        synchronized (this) {
10534            ActivityRecord activity = getFocusedStack().mResumedActivity;
10535            if (activity == null) {
10536                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10537                return null;
10538            }
10539            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10540            if (activity.app == null || activity.app.thread == null) {
10541                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10542                return null;
10543            }
10544            if (activity.app.pid == Binder.getCallingPid()) {
10545                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10546                return null;
10547            }
10548            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10549            try {
10550                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10551                        requestType);
10552                mPendingAssistExtras.add(pae);
10553                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10554            } catch (RemoteException e) {
10555                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10556                return null;
10557            }
10558            return pae;
10559        }
10560    }
10561
10562    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10563        PendingAssistExtras pae = (PendingAssistExtras)token;
10564        synchronized (pae) {
10565            pae.result = extras;
10566            pae.haveResult = true;
10567            pae.notifyAll();
10568            if (pae.intent == null) {
10569                // Caller is just waiting for the result.
10570                return;
10571            }
10572        }
10573
10574        // We are now ready to launch the assist activity.
10575        synchronized (this) {
10576            boolean exists = mPendingAssistExtras.remove(pae);
10577            mHandler.removeCallbacks(pae);
10578            if (!exists) {
10579                // Timed out.
10580                return;
10581            }
10582        }
10583        pae.intent.replaceExtras(extras);
10584        if (pae.hint != null) {
10585            pae.intent.putExtra(pae.hint, true);
10586        }
10587        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10588                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10589                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10590        closeSystemDialogs("assist");
10591        try {
10592            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10593        } catch (ActivityNotFoundException e) {
10594            Slog.w(TAG, "No activity to handle assist action.", e);
10595        }
10596    }
10597
10598    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10599        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10600    }
10601
10602    public void registerProcessObserver(IProcessObserver observer) {
10603        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10604                "registerProcessObserver()");
10605        synchronized (this) {
10606            mProcessObservers.register(observer);
10607        }
10608    }
10609
10610    @Override
10611    public void unregisterProcessObserver(IProcessObserver observer) {
10612        synchronized (this) {
10613            mProcessObservers.unregister(observer);
10614        }
10615    }
10616
10617    @Override
10618    public boolean convertFromTranslucent(IBinder token) {
10619        final long origId = Binder.clearCallingIdentity();
10620        try {
10621            synchronized (this) {
10622                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10623                if (r == null) {
10624                    return false;
10625                }
10626                final boolean translucentChanged = r.changeWindowTranslucency(true);
10627                if (translucentChanged) {
10628                    r.task.stack.releaseBackgroundResources();
10629                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10630                }
10631                mWindowManager.setAppFullscreen(token, true);
10632                return translucentChanged;
10633            }
10634        } finally {
10635            Binder.restoreCallingIdentity(origId);
10636        }
10637    }
10638
10639    @Override
10640    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10641        final long origId = Binder.clearCallingIdentity();
10642        try {
10643            synchronized (this) {
10644                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10645                if (r == null) {
10646                    return false;
10647                }
10648                int index = r.task.mActivities.lastIndexOf(r);
10649                if (index > 0) {
10650                    ActivityRecord under = r.task.mActivities.get(index - 1);
10651                    under.returningOptions = options;
10652                }
10653                final boolean translucentChanged = r.changeWindowTranslucency(false);
10654                if (translucentChanged) {
10655                    r.task.stack.convertToTranslucent(r);
10656                }
10657                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10658                mWindowManager.setAppFullscreen(token, false);
10659                return translucentChanged;
10660            }
10661        } finally {
10662            Binder.restoreCallingIdentity(origId);
10663        }
10664    }
10665
10666    @Override
10667    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10668        final long origId = Binder.clearCallingIdentity();
10669        try {
10670            synchronized (this) {
10671                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10672                if (r != null) {
10673                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10674                }
10675            }
10676            return false;
10677        } finally {
10678            Binder.restoreCallingIdentity(origId);
10679        }
10680    }
10681
10682    @Override
10683    public boolean isBackgroundVisibleBehind(IBinder token) {
10684        final long origId = Binder.clearCallingIdentity();
10685        try {
10686            synchronized (this) {
10687                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10688                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10689                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10690                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10691                return visible;
10692            }
10693        } finally {
10694            Binder.restoreCallingIdentity(origId);
10695        }
10696    }
10697
10698    @Override
10699    public ActivityOptions getActivityOptions(IBinder token) {
10700        final long origId = Binder.clearCallingIdentity();
10701        try {
10702            synchronized (this) {
10703                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10704                if (r != null) {
10705                    final ActivityOptions activityOptions = r.pendingOptions;
10706                    r.pendingOptions = null;
10707                    return activityOptions;
10708                }
10709                return null;
10710            }
10711        } finally {
10712            Binder.restoreCallingIdentity(origId);
10713        }
10714    }
10715
10716    @Override
10717    public void setImmersive(IBinder token, boolean immersive) {
10718        synchronized(this) {
10719            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10720            if (r == null) {
10721                throw new IllegalArgumentException();
10722            }
10723            r.immersive = immersive;
10724
10725            // update associated state if we're frontmost
10726            if (r == mFocusedActivity) {
10727                if (DEBUG_IMMERSIVE) {
10728                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10729                }
10730                applyUpdateLockStateLocked(r);
10731            }
10732        }
10733    }
10734
10735    @Override
10736    public boolean isImmersive(IBinder token) {
10737        synchronized (this) {
10738            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10739            if (r == null) {
10740                throw new IllegalArgumentException();
10741            }
10742            return r.immersive;
10743        }
10744    }
10745
10746    public boolean isTopActivityImmersive() {
10747        enforceNotIsolatedCaller("startActivity");
10748        synchronized (this) {
10749            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10750            return (r != null) ? r.immersive : false;
10751        }
10752    }
10753
10754    @Override
10755    public boolean isTopOfTask(IBinder token) {
10756        synchronized (this) {
10757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10758            if (r == null) {
10759                throw new IllegalArgumentException();
10760            }
10761            return r.task.getTopActivity() == r;
10762        }
10763    }
10764
10765    public final void enterSafeMode() {
10766        synchronized(this) {
10767            // It only makes sense to do this before the system is ready
10768            // and started launching other packages.
10769            if (!mSystemReady) {
10770                try {
10771                    AppGlobals.getPackageManager().enterSafeMode();
10772                } catch (RemoteException e) {
10773                }
10774            }
10775
10776            mSafeMode = true;
10777        }
10778    }
10779
10780    public final void showSafeModeOverlay() {
10781        View v = LayoutInflater.from(mContext).inflate(
10782                com.android.internal.R.layout.safe_mode, null);
10783        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10784        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10785        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10786        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10787        lp.gravity = Gravity.BOTTOM | Gravity.START;
10788        lp.format = v.getBackground().getOpacity();
10789        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10790                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10791        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10792        ((WindowManager)mContext.getSystemService(
10793                Context.WINDOW_SERVICE)).addView(v, lp);
10794    }
10795
10796    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10797        if (!(sender instanceof PendingIntentRecord)) {
10798            return;
10799        }
10800        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10801        synchronized (stats) {
10802            if (mBatteryStatsService.isOnBattery()) {
10803                mBatteryStatsService.enforceCallingPermission();
10804                PendingIntentRecord rec = (PendingIntentRecord)sender;
10805                int MY_UID = Binder.getCallingUid();
10806                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10807                BatteryStatsImpl.Uid.Pkg pkg =
10808                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10809                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10810                pkg.incWakeupsLocked();
10811            }
10812        }
10813    }
10814
10815    public boolean killPids(int[] pids, String pReason, boolean secure) {
10816        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10817            throw new SecurityException("killPids only available to the system");
10818        }
10819        String reason = (pReason == null) ? "Unknown" : pReason;
10820        // XXX Note: don't acquire main activity lock here, because the window
10821        // manager calls in with its locks held.
10822
10823        boolean killed = false;
10824        synchronized (mPidsSelfLocked) {
10825            int[] types = new int[pids.length];
10826            int worstType = 0;
10827            for (int i=0; i<pids.length; i++) {
10828                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10829                if (proc != null) {
10830                    int type = proc.setAdj;
10831                    types[i] = type;
10832                    if (type > worstType) {
10833                        worstType = type;
10834                    }
10835                }
10836            }
10837
10838            // If the worst oom_adj is somewhere in the cached proc LRU range,
10839            // then constrain it so we will kill all cached procs.
10840            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10841                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10842                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10843            }
10844
10845            // If this is not a secure call, don't let it kill processes that
10846            // are important.
10847            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10848                worstType = ProcessList.SERVICE_ADJ;
10849            }
10850
10851            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10852            for (int i=0; i<pids.length; i++) {
10853                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10854                if (proc == null) {
10855                    continue;
10856                }
10857                int adj = proc.setAdj;
10858                if (adj >= worstType && !proc.killedByAm) {
10859                    proc.kill(reason, true);
10860                    killed = true;
10861                }
10862            }
10863        }
10864        return killed;
10865    }
10866
10867    @Override
10868    public void killUid(int uid, String reason) {
10869        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10870            throw new SecurityException("killUid only available to the system");
10871        }
10872        synchronized (this) {
10873            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10874                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10875                    reason != null ? reason : "kill uid");
10876        }
10877    }
10878
10879    @Override
10880    public boolean killProcessesBelowForeground(String reason) {
10881        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10882            throw new SecurityException("killProcessesBelowForeground() only available to system");
10883        }
10884
10885        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10886    }
10887
10888    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10889        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10890            throw new SecurityException("killProcessesBelowAdj() only available to system");
10891        }
10892
10893        boolean killed = false;
10894        synchronized (mPidsSelfLocked) {
10895            final int size = mPidsSelfLocked.size();
10896            for (int i = 0; i < size; i++) {
10897                final int pid = mPidsSelfLocked.keyAt(i);
10898                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10899                if (proc == null) continue;
10900
10901                final int adj = proc.setAdj;
10902                if (adj > belowAdj && !proc.killedByAm) {
10903                    proc.kill(reason, true);
10904                    killed = true;
10905                }
10906            }
10907        }
10908        return killed;
10909    }
10910
10911    @Override
10912    public void hang(final IBinder who, boolean allowRestart) {
10913        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10914                != PackageManager.PERMISSION_GRANTED) {
10915            throw new SecurityException("Requires permission "
10916                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10917        }
10918
10919        final IBinder.DeathRecipient death = new DeathRecipient() {
10920            @Override
10921            public void binderDied() {
10922                synchronized (this) {
10923                    notifyAll();
10924                }
10925            }
10926        };
10927
10928        try {
10929            who.linkToDeath(death, 0);
10930        } catch (RemoteException e) {
10931            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10932            return;
10933        }
10934
10935        synchronized (this) {
10936            Watchdog.getInstance().setAllowRestart(allowRestart);
10937            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10938            synchronized (death) {
10939                while (who.isBinderAlive()) {
10940                    try {
10941                        death.wait();
10942                    } catch (InterruptedException e) {
10943                    }
10944                }
10945            }
10946            Watchdog.getInstance().setAllowRestart(true);
10947        }
10948    }
10949
10950    @Override
10951    public void restart() {
10952        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10953                != PackageManager.PERMISSION_GRANTED) {
10954            throw new SecurityException("Requires permission "
10955                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10956        }
10957
10958        Log.i(TAG, "Sending shutdown broadcast...");
10959
10960        BroadcastReceiver br = new BroadcastReceiver() {
10961            @Override public void onReceive(Context context, Intent intent) {
10962                // Now the broadcast is done, finish up the low-level shutdown.
10963                Log.i(TAG, "Shutting down activity manager...");
10964                shutdown(10000);
10965                Log.i(TAG, "Shutdown complete, restarting!");
10966                Process.killProcess(Process.myPid());
10967                System.exit(10);
10968            }
10969        };
10970
10971        // First send the high-level shut down broadcast.
10972        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10973        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10974        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10975        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10976        mContext.sendOrderedBroadcastAsUser(intent,
10977                UserHandle.ALL, null, br, mHandler, 0, null, null);
10978        */
10979        br.onReceive(mContext, intent);
10980    }
10981
10982    private long getLowRamTimeSinceIdle(long now) {
10983        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10984    }
10985
10986    @Override
10987    public void performIdleMaintenance() {
10988        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10989                != PackageManager.PERMISSION_GRANTED) {
10990            throw new SecurityException("Requires permission "
10991                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10992        }
10993
10994        synchronized (this) {
10995            final long now = SystemClock.uptimeMillis();
10996            final long timeSinceLastIdle = now - mLastIdleTime;
10997            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10998            mLastIdleTime = now;
10999            mLowRamTimeSinceLastIdle = 0;
11000            if (mLowRamStartTime != 0) {
11001                mLowRamStartTime = now;
11002            }
11003
11004            StringBuilder sb = new StringBuilder(128);
11005            sb.append("Idle maintenance over ");
11006            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11007            sb.append(" low RAM for ");
11008            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11009            Slog.i(TAG, sb.toString());
11010
11011            // If at least 1/3 of our time since the last idle period has been spent
11012            // with RAM low, then we want to kill processes.
11013            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11014
11015            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11016                ProcessRecord proc = mLruProcesses.get(i);
11017                if (proc.notCachedSinceIdle) {
11018                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
11019                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11020                        if (doKilling && proc.initialIdlePss != 0
11021                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11022                            proc.kill("idle maint (pss " + proc.lastPss
11023                                    + " from " + proc.initialIdlePss + ")", true);
11024                        }
11025                    }
11026                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11027                    proc.notCachedSinceIdle = true;
11028                    proc.initialIdlePss = 0;
11029                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11030                            isSleeping(), now);
11031                }
11032            }
11033
11034            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11035            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11036        }
11037    }
11038
11039    private void retrieveSettings() {
11040        final ContentResolver resolver = mContext.getContentResolver();
11041        String debugApp = Settings.Global.getString(
11042            resolver, Settings.Global.DEBUG_APP);
11043        boolean waitForDebugger = Settings.Global.getInt(
11044            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11045        boolean alwaysFinishActivities = Settings.Global.getInt(
11046            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11047        boolean forceRtl = Settings.Global.getInt(
11048                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11049        // Transfer any global setting for forcing RTL layout, into a System Property
11050        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11051
11052        Configuration configuration = new Configuration();
11053        Settings.System.getConfiguration(resolver, configuration);
11054        if (forceRtl) {
11055            // This will take care of setting the correct layout direction flags
11056            configuration.setLayoutDirection(configuration.locale);
11057        }
11058
11059        synchronized (this) {
11060            mDebugApp = mOrigDebugApp = debugApp;
11061            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11062            mAlwaysFinishActivities = alwaysFinishActivities;
11063            // This happens before any activities are started, so we can
11064            // change mConfiguration in-place.
11065            updateConfigurationLocked(configuration, null, false, true);
11066            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11067        }
11068    }
11069
11070    /** Loads resources after the current configuration has been set. */
11071    private void loadResourcesOnSystemReady() {
11072        final Resources res = mContext.getResources();
11073        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11074        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11075        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11076    }
11077
11078    public boolean testIsSystemReady() {
11079        // no need to synchronize(this) just to read & return the value
11080        return mSystemReady;
11081    }
11082
11083    private static File getCalledPreBootReceiversFile() {
11084        File dataDir = Environment.getDataDirectory();
11085        File systemDir = new File(dataDir, "system");
11086        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11087        return fname;
11088    }
11089
11090    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11091        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11092        File file = getCalledPreBootReceiversFile();
11093        FileInputStream fis = null;
11094        try {
11095            fis = new FileInputStream(file);
11096            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11097            int fvers = dis.readInt();
11098            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11099                String vers = dis.readUTF();
11100                String codename = dis.readUTF();
11101                String build = dis.readUTF();
11102                if (android.os.Build.VERSION.RELEASE.equals(vers)
11103                        && android.os.Build.VERSION.CODENAME.equals(codename)
11104                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11105                    int num = dis.readInt();
11106                    while (num > 0) {
11107                        num--;
11108                        String pkg = dis.readUTF();
11109                        String cls = dis.readUTF();
11110                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11111                    }
11112                }
11113            }
11114        } catch (FileNotFoundException e) {
11115        } catch (IOException e) {
11116            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11117        } finally {
11118            if (fis != null) {
11119                try {
11120                    fis.close();
11121                } catch (IOException e) {
11122                }
11123            }
11124        }
11125        return lastDoneReceivers;
11126    }
11127
11128    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11129        File file = getCalledPreBootReceiversFile();
11130        FileOutputStream fos = null;
11131        DataOutputStream dos = null;
11132        try {
11133            fos = new FileOutputStream(file);
11134            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11135            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11136            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11137            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11138            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11139            dos.writeInt(list.size());
11140            for (int i=0; i<list.size(); i++) {
11141                dos.writeUTF(list.get(i).getPackageName());
11142                dos.writeUTF(list.get(i).getClassName());
11143            }
11144        } catch (IOException e) {
11145            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11146            file.delete();
11147        } finally {
11148            FileUtils.sync(fos);
11149            if (dos != null) {
11150                try {
11151                    dos.close();
11152                } catch (IOException e) {
11153                    // TODO Auto-generated catch block
11154                    e.printStackTrace();
11155                }
11156            }
11157        }
11158    }
11159
11160    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11161            ArrayList<ComponentName> doneReceivers, int userId) {
11162        boolean waitingUpdate = false;
11163        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11164        List<ResolveInfo> ris = null;
11165        try {
11166            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11167                    intent, null, 0, userId);
11168        } catch (RemoteException e) {
11169        }
11170        if (ris != null) {
11171            for (int i=ris.size()-1; i>=0; i--) {
11172                if ((ris.get(i).activityInfo.applicationInfo.flags
11173                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11174                    ris.remove(i);
11175                }
11176            }
11177            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11178
11179            // For User 0, load the version number. When delivering to a new user, deliver
11180            // to all receivers.
11181            if (userId == UserHandle.USER_OWNER) {
11182                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11183                for (int i=0; i<ris.size(); i++) {
11184                    ActivityInfo ai = ris.get(i).activityInfo;
11185                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11186                    if (lastDoneReceivers.contains(comp)) {
11187                        // We already did the pre boot receiver for this app with the current
11188                        // platform version, so don't do it again...
11189                        ris.remove(i);
11190                        i--;
11191                        // ...however, do keep it as one that has been done, so we don't
11192                        // forget about it when rewriting the file of last done receivers.
11193                        doneReceivers.add(comp);
11194                    }
11195                }
11196            }
11197
11198            // If primary user, send broadcast to all available users, else just to userId
11199            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11200                    : new int[] { userId };
11201            for (int i = 0; i < ris.size(); i++) {
11202                ActivityInfo ai = ris.get(i).activityInfo;
11203                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11204                doneReceivers.add(comp);
11205                intent.setComponent(comp);
11206                for (int j=0; j<users.length; j++) {
11207                    IIntentReceiver finisher = null;
11208                    // On last receiver and user, set up a completion callback
11209                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11210                        finisher = new IIntentReceiver.Stub() {
11211                            public void performReceive(Intent intent, int resultCode,
11212                                    String data, Bundle extras, boolean ordered,
11213                                    boolean sticky, int sendingUser) {
11214                                // The raw IIntentReceiver interface is called
11215                                // with the AM lock held, so redispatch to
11216                                // execute our code without the lock.
11217                                mHandler.post(onFinishCallback);
11218                            }
11219                        };
11220                    }
11221                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11222                            + " for user " + users[j]);
11223                    broadcastIntentLocked(null, null, intent, null, finisher,
11224                            0, null, null, null, AppOpsManager.OP_NONE,
11225                            true, false, MY_PID, Process.SYSTEM_UID,
11226                            users[j]);
11227                    if (finisher != null) {
11228                        waitingUpdate = true;
11229                    }
11230                }
11231            }
11232        }
11233
11234        return waitingUpdate;
11235    }
11236
11237    public void systemReady(final Runnable goingCallback) {
11238        synchronized(this) {
11239            if (mSystemReady) {
11240                // If we're done calling all the receivers, run the next "boot phase" passed in
11241                // by the SystemServer
11242                if (goingCallback != null) {
11243                    goingCallback.run();
11244                }
11245                return;
11246            }
11247
11248            // Make sure we have the current profile info, since it is needed for
11249            // security checks.
11250            updateCurrentProfileIdsLocked();
11251
11252            if (mRecentTasks == null) {
11253                mRecentTasks = mTaskPersister.restoreTasksLocked();
11254                if (!mRecentTasks.isEmpty()) {
11255                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11256                }
11257                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11258                mTaskPersister.startPersisting();
11259            }
11260
11261            // Check to see if there are any update receivers to run.
11262            if (!mDidUpdate) {
11263                if (mWaitingUpdate) {
11264                    return;
11265                }
11266                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11267                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11268                    public void run() {
11269                        synchronized (ActivityManagerService.this) {
11270                            mDidUpdate = true;
11271                        }
11272                        writeLastDonePreBootReceivers(doneReceivers);
11273                        showBootMessage(mContext.getText(
11274                                R.string.android_upgrading_complete),
11275                                false);
11276                        systemReady(goingCallback);
11277                    }
11278                }, doneReceivers, UserHandle.USER_OWNER);
11279
11280                if (mWaitingUpdate) {
11281                    return;
11282                }
11283                mDidUpdate = true;
11284            }
11285
11286            mAppOpsService.systemReady();
11287            mSystemReady = true;
11288        }
11289
11290        ArrayList<ProcessRecord> procsToKill = null;
11291        synchronized(mPidsSelfLocked) {
11292            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11293                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11294                if (!isAllowedWhileBooting(proc.info)){
11295                    if (procsToKill == null) {
11296                        procsToKill = new ArrayList<ProcessRecord>();
11297                    }
11298                    procsToKill.add(proc);
11299                }
11300            }
11301        }
11302
11303        synchronized(this) {
11304            if (procsToKill != null) {
11305                for (int i=procsToKill.size()-1; i>=0; i--) {
11306                    ProcessRecord proc = procsToKill.get(i);
11307                    Slog.i(TAG, "Removing system update proc: " + proc);
11308                    removeProcessLocked(proc, true, false, "system update done");
11309                }
11310            }
11311
11312            // Now that we have cleaned up any update processes, we
11313            // are ready to start launching real processes and know that
11314            // we won't trample on them any more.
11315            mProcessesReady = true;
11316        }
11317
11318        Slog.i(TAG, "System now ready");
11319        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11320            SystemClock.uptimeMillis());
11321
11322        synchronized(this) {
11323            // Make sure we have no pre-ready processes sitting around.
11324
11325            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11326                ResolveInfo ri = mContext.getPackageManager()
11327                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11328                                STOCK_PM_FLAGS);
11329                CharSequence errorMsg = null;
11330                if (ri != null) {
11331                    ActivityInfo ai = ri.activityInfo;
11332                    ApplicationInfo app = ai.applicationInfo;
11333                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11334                        mTopAction = Intent.ACTION_FACTORY_TEST;
11335                        mTopData = null;
11336                        mTopComponent = new ComponentName(app.packageName,
11337                                ai.name);
11338                    } else {
11339                        errorMsg = mContext.getResources().getText(
11340                                com.android.internal.R.string.factorytest_not_system);
11341                    }
11342                } else {
11343                    errorMsg = mContext.getResources().getText(
11344                            com.android.internal.R.string.factorytest_no_action);
11345                }
11346                if (errorMsg != null) {
11347                    mTopAction = null;
11348                    mTopData = null;
11349                    mTopComponent = null;
11350                    Message msg = Message.obtain();
11351                    msg.what = SHOW_FACTORY_ERROR_MSG;
11352                    msg.getData().putCharSequence("msg", errorMsg);
11353                    mHandler.sendMessage(msg);
11354                }
11355            }
11356        }
11357
11358        retrieveSettings();
11359        loadResourcesOnSystemReady();
11360
11361        synchronized (this) {
11362            readGrantedUriPermissionsLocked();
11363        }
11364
11365        if (goingCallback != null) goingCallback.run();
11366
11367        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11368                Integer.toString(mCurrentUserId), mCurrentUserId);
11369        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11370                Integer.toString(mCurrentUserId), mCurrentUserId);
11371        mSystemServiceManager.startUser(mCurrentUserId);
11372
11373        synchronized (this) {
11374            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11375                try {
11376                    List apps = AppGlobals.getPackageManager().
11377                        getPersistentApplications(STOCK_PM_FLAGS);
11378                    if (apps != null) {
11379                        int N = apps.size();
11380                        int i;
11381                        for (i=0; i<N; i++) {
11382                            ApplicationInfo info
11383                                = (ApplicationInfo)apps.get(i);
11384                            if (info != null &&
11385                                    !info.packageName.equals("android")) {
11386                                addAppLocked(info, false, null /* ABI override */);
11387                            }
11388                        }
11389                    }
11390                } catch (RemoteException ex) {
11391                    // pm is in same process, this will never happen.
11392                }
11393            }
11394
11395            // Start up initial activity.
11396            mBooting = true;
11397            startHomeActivityLocked(mCurrentUserId);
11398
11399            try {
11400                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11401                    Message msg = Message.obtain();
11402                    msg.what = SHOW_UID_ERROR_MSG;
11403                    mHandler.sendMessage(msg);
11404                }
11405            } catch (RemoteException e) {
11406            }
11407
11408            long ident = Binder.clearCallingIdentity();
11409            try {
11410                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11411                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11412                        | Intent.FLAG_RECEIVER_FOREGROUND);
11413                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11414                broadcastIntentLocked(null, null, intent,
11415                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11416                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11417                intent = new Intent(Intent.ACTION_USER_STARTING);
11418                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11419                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11420                broadcastIntentLocked(null, null, intent,
11421                        null, new IIntentReceiver.Stub() {
11422                            @Override
11423                            public void performReceive(Intent intent, int resultCode, String data,
11424                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11425                                    throws RemoteException {
11426                            }
11427                        }, 0, null, null,
11428                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11429                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11430            } catch (Throwable t) {
11431                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11432            } finally {
11433                Binder.restoreCallingIdentity(ident);
11434            }
11435            mStackSupervisor.resumeTopActivitiesLocked();
11436            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11437        }
11438    }
11439
11440    private boolean makeAppCrashingLocked(ProcessRecord app,
11441            String shortMsg, String longMsg, String stackTrace) {
11442        app.crashing = true;
11443        app.crashingReport = generateProcessError(app,
11444                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11445        startAppProblemLocked(app);
11446        app.stopFreezingAllLocked();
11447        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11448    }
11449
11450    private void makeAppNotRespondingLocked(ProcessRecord app,
11451            String activity, String shortMsg, String longMsg) {
11452        app.notResponding = true;
11453        app.notRespondingReport = generateProcessError(app,
11454                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11455                activity, shortMsg, longMsg, null);
11456        startAppProblemLocked(app);
11457        app.stopFreezingAllLocked();
11458    }
11459
11460    /**
11461     * Generate a process error record, suitable for attachment to a ProcessRecord.
11462     *
11463     * @param app The ProcessRecord in which the error occurred.
11464     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11465     *                      ActivityManager.AppErrorStateInfo
11466     * @param activity The activity associated with the crash, if known.
11467     * @param shortMsg Short message describing the crash.
11468     * @param longMsg Long message describing the crash.
11469     * @param stackTrace Full crash stack trace, may be null.
11470     *
11471     * @return Returns a fully-formed AppErrorStateInfo record.
11472     */
11473    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11474            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11475        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11476
11477        report.condition = condition;
11478        report.processName = app.processName;
11479        report.pid = app.pid;
11480        report.uid = app.info.uid;
11481        report.tag = activity;
11482        report.shortMsg = shortMsg;
11483        report.longMsg = longMsg;
11484        report.stackTrace = stackTrace;
11485
11486        return report;
11487    }
11488
11489    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11490        synchronized (this) {
11491            app.crashing = false;
11492            app.crashingReport = null;
11493            app.notResponding = false;
11494            app.notRespondingReport = null;
11495            if (app.anrDialog == fromDialog) {
11496                app.anrDialog = null;
11497            }
11498            if (app.waitDialog == fromDialog) {
11499                app.waitDialog = null;
11500            }
11501            if (app.pid > 0 && app.pid != MY_PID) {
11502                handleAppCrashLocked(app, null, null, null);
11503                app.kill("user request after error", true);
11504            }
11505        }
11506    }
11507
11508    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11509            String stackTrace) {
11510        long now = SystemClock.uptimeMillis();
11511
11512        Long crashTime;
11513        if (!app.isolated) {
11514            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11515        } else {
11516            crashTime = null;
11517        }
11518        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11519            // This process loses!
11520            Slog.w(TAG, "Process " + app.info.processName
11521                    + " has crashed too many times: killing!");
11522            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11523                    app.userId, app.info.processName, app.uid);
11524            mStackSupervisor.handleAppCrashLocked(app);
11525            if (!app.persistent) {
11526                // We don't want to start this process again until the user
11527                // explicitly does so...  but for persistent process, we really
11528                // need to keep it running.  If a persistent process is actually
11529                // repeatedly crashing, then badness for everyone.
11530                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11531                        app.info.processName);
11532                if (!app.isolated) {
11533                    // XXX We don't have a way to mark isolated processes
11534                    // as bad, since they don't have a peristent identity.
11535                    mBadProcesses.put(app.info.processName, app.uid,
11536                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11537                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11538                }
11539                app.bad = true;
11540                app.removed = true;
11541                // Don't let services in this process be restarted and potentially
11542                // annoy the user repeatedly.  Unless it is persistent, since those
11543                // processes run critical code.
11544                removeProcessLocked(app, false, false, "crash");
11545                mStackSupervisor.resumeTopActivitiesLocked();
11546                return false;
11547            }
11548            mStackSupervisor.resumeTopActivitiesLocked();
11549        } else {
11550            mStackSupervisor.finishTopRunningActivityLocked(app);
11551        }
11552
11553        // Bump up the crash count of any services currently running in the proc.
11554        for (int i=app.services.size()-1; i>=0; i--) {
11555            // Any services running in the application need to be placed
11556            // back in the pending list.
11557            ServiceRecord sr = app.services.valueAt(i);
11558            sr.crashCount++;
11559        }
11560
11561        // If the crashing process is what we consider to be the "home process" and it has been
11562        // replaced by a third-party app, clear the package preferred activities from packages
11563        // with a home activity running in the process to prevent a repeatedly crashing app
11564        // from blocking the user to manually clear the list.
11565        final ArrayList<ActivityRecord> activities = app.activities;
11566        if (app == mHomeProcess && activities.size() > 0
11567                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11568            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11569                final ActivityRecord r = activities.get(activityNdx);
11570                if (r.isHomeActivity()) {
11571                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11572                    try {
11573                        ActivityThread.getPackageManager()
11574                                .clearPackagePreferredActivities(r.packageName);
11575                    } catch (RemoteException c) {
11576                        // pm is in same process, this will never happen.
11577                    }
11578                }
11579            }
11580        }
11581
11582        if (!app.isolated) {
11583            // XXX Can't keep track of crash times for isolated processes,
11584            // because they don't have a perisistent identity.
11585            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11586        }
11587
11588        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11589        return true;
11590    }
11591
11592    void startAppProblemLocked(ProcessRecord app) {
11593        // If this app is not running under the current user, then we
11594        // can't give it a report button because that would require
11595        // launching the report UI under a different user.
11596        app.errorReportReceiver = null;
11597
11598        for (int userId : mCurrentProfileIds) {
11599            if (app.userId == userId) {
11600                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11601                        mContext, app.info.packageName, app.info.flags);
11602            }
11603        }
11604        skipCurrentReceiverLocked(app);
11605    }
11606
11607    void skipCurrentReceiverLocked(ProcessRecord app) {
11608        for (BroadcastQueue queue : mBroadcastQueues) {
11609            queue.skipCurrentReceiverLocked(app);
11610        }
11611    }
11612
11613    /**
11614     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11615     * The application process will exit immediately after this call returns.
11616     * @param app object of the crashing app, null for the system server
11617     * @param crashInfo describing the exception
11618     */
11619    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11620        ProcessRecord r = findAppProcess(app, "Crash");
11621        final String processName = app == null ? "system_server"
11622                : (r == null ? "unknown" : r.processName);
11623
11624        handleApplicationCrashInner("crash", r, processName, crashInfo);
11625    }
11626
11627    /* Native crash reporting uses this inner version because it needs to be somewhat
11628     * decoupled from the AM-managed cleanup lifecycle
11629     */
11630    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11631            ApplicationErrorReport.CrashInfo crashInfo) {
11632        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11633                UserHandle.getUserId(Binder.getCallingUid()), processName,
11634                r == null ? -1 : r.info.flags,
11635                crashInfo.exceptionClassName,
11636                crashInfo.exceptionMessage,
11637                crashInfo.throwFileName,
11638                crashInfo.throwLineNumber);
11639
11640        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11641
11642        crashApplication(r, crashInfo);
11643    }
11644
11645    public void handleApplicationStrictModeViolation(
11646            IBinder app,
11647            int violationMask,
11648            StrictMode.ViolationInfo info) {
11649        ProcessRecord r = findAppProcess(app, "StrictMode");
11650        if (r == null) {
11651            return;
11652        }
11653
11654        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11655            Integer stackFingerprint = info.hashCode();
11656            boolean logIt = true;
11657            synchronized (mAlreadyLoggedViolatedStacks) {
11658                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11659                    logIt = false;
11660                    // TODO: sub-sample into EventLog for these, with
11661                    // the info.durationMillis?  Then we'd get
11662                    // the relative pain numbers, without logging all
11663                    // the stack traces repeatedly.  We'd want to do
11664                    // likewise in the client code, which also does
11665                    // dup suppression, before the Binder call.
11666                } else {
11667                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11668                        mAlreadyLoggedViolatedStacks.clear();
11669                    }
11670                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11671                }
11672            }
11673            if (logIt) {
11674                logStrictModeViolationToDropBox(r, info);
11675            }
11676        }
11677
11678        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11679            AppErrorResult result = new AppErrorResult();
11680            synchronized (this) {
11681                final long origId = Binder.clearCallingIdentity();
11682
11683                Message msg = Message.obtain();
11684                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11685                HashMap<String, Object> data = new HashMap<String, Object>();
11686                data.put("result", result);
11687                data.put("app", r);
11688                data.put("violationMask", violationMask);
11689                data.put("info", info);
11690                msg.obj = data;
11691                mHandler.sendMessage(msg);
11692
11693                Binder.restoreCallingIdentity(origId);
11694            }
11695            int res = result.get();
11696            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11697        }
11698    }
11699
11700    // Depending on the policy in effect, there could be a bunch of
11701    // these in quick succession so we try to batch these together to
11702    // minimize disk writes, number of dropbox entries, and maximize
11703    // compression, by having more fewer, larger records.
11704    private void logStrictModeViolationToDropBox(
11705            ProcessRecord process,
11706            StrictMode.ViolationInfo info) {
11707        if (info == null) {
11708            return;
11709        }
11710        final boolean isSystemApp = process == null ||
11711                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11712                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11713        final String processName = process == null ? "unknown" : process.processName;
11714        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11715        final DropBoxManager dbox = (DropBoxManager)
11716                mContext.getSystemService(Context.DROPBOX_SERVICE);
11717
11718        // Exit early if the dropbox isn't configured to accept this report type.
11719        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11720
11721        boolean bufferWasEmpty;
11722        boolean needsFlush;
11723        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11724        synchronized (sb) {
11725            bufferWasEmpty = sb.length() == 0;
11726            appendDropBoxProcessHeaders(process, processName, sb);
11727            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11728            sb.append("System-App: ").append(isSystemApp).append("\n");
11729            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11730            if (info.violationNumThisLoop != 0) {
11731                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11732            }
11733            if (info.numAnimationsRunning != 0) {
11734                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11735            }
11736            if (info.broadcastIntentAction != null) {
11737                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11738            }
11739            if (info.durationMillis != -1) {
11740                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11741            }
11742            if (info.numInstances != -1) {
11743                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11744            }
11745            if (info.tags != null) {
11746                for (String tag : info.tags) {
11747                    sb.append("Span-Tag: ").append(tag).append("\n");
11748                }
11749            }
11750            sb.append("\n");
11751            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11752                sb.append(info.crashInfo.stackTrace);
11753                sb.append("\n");
11754            }
11755            if (info.message != null) {
11756                sb.append(info.message);
11757                sb.append("\n");
11758            }
11759
11760            // Only buffer up to ~64k.  Various logging bits truncate
11761            // things at 128k.
11762            needsFlush = (sb.length() > 64 * 1024);
11763        }
11764
11765        // Flush immediately if the buffer's grown too large, or this
11766        // is a non-system app.  Non-system apps are isolated with a
11767        // different tag & policy and not batched.
11768        //
11769        // Batching is useful during internal testing with
11770        // StrictMode settings turned up high.  Without batching,
11771        // thousands of separate files could be created on boot.
11772        if (!isSystemApp || needsFlush) {
11773            new Thread("Error dump: " + dropboxTag) {
11774                @Override
11775                public void run() {
11776                    String report;
11777                    synchronized (sb) {
11778                        report = sb.toString();
11779                        sb.delete(0, sb.length());
11780                        sb.trimToSize();
11781                    }
11782                    if (report.length() != 0) {
11783                        dbox.addText(dropboxTag, report);
11784                    }
11785                }
11786            }.start();
11787            return;
11788        }
11789
11790        // System app batching:
11791        if (!bufferWasEmpty) {
11792            // An existing dropbox-writing thread is outstanding, so
11793            // we don't need to start it up.  The existing thread will
11794            // catch the buffer appends we just did.
11795            return;
11796        }
11797
11798        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11799        // (After this point, we shouldn't access AMS internal data structures.)
11800        new Thread("Error dump: " + dropboxTag) {
11801            @Override
11802            public void run() {
11803                // 5 second sleep to let stacks arrive and be batched together
11804                try {
11805                    Thread.sleep(5000);  // 5 seconds
11806                } catch (InterruptedException e) {}
11807
11808                String errorReport;
11809                synchronized (mStrictModeBuffer) {
11810                    errorReport = mStrictModeBuffer.toString();
11811                    if (errorReport.length() == 0) {
11812                        return;
11813                    }
11814                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11815                    mStrictModeBuffer.trimToSize();
11816                }
11817                dbox.addText(dropboxTag, errorReport);
11818            }
11819        }.start();
11820    }
11821
11822    /**
11823     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11824     * @param app object of the crashing app, null for the system server
11825     * @param tag reported by the caller
11826     * @param system whether this wtf is coming from the system
11827     * @param crashInfo describing the context of the error
11828     * @return true if the process should exit immediately (WTF is fatal)
11829     */
11830    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11831            final ApplicationErrorReport.CrashInfo crashInfo) {
11832        final int callingUid = Binder.getCallingUid();
11833        final int callingPid = Binder.getCallingPid();
11834
11835        if (system) {
11836            // If this is coming from the system, we could very well have low-level
11837            // system locks held, so we want to do this all asynchronously.  And we
11838            // never want this to become fatal, so there is that too.
11839            mHandler.post(new Runnable() {
11840                @Override public void run() {
11841                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11842                }
11843            });
11844            return false;
11845        }
11846
11847        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11848                crashInfo);
11849
11850        if (r != null && r.pid != Process.myPid() &&
11851                Settings.Global.getInt(mContext.getContentResolver(),
11852                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11853            crashApplication(r, crashInfo);
11854            return true;
11855        } else {
11856            return false;
11857        }
11858    }
11859
11860    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11861            final ApplicationErrorReport.CrashInfo crashInfo) {
11862        final ProcessRecord r = findAppProcess(app, "WTF");
11863        final String processName = app == null ? "system_server"
11864                : (r == null ? "unknown" : r.processName);
11865
11866        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11867                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11868
11869        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11870
11871        return r;
11872    }
11873
11874    /**
11875     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11876     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11877     */
11878    private ProcessRecord findAppProcess(IBinder app, String reason) {
11879        if (app == null) {
11880            return null;
11881        }
11882
11883        synchronized (this) {
11884            final int NP = mProcessNames.getMap().size();
11885            for (int ip=0; ip<NP; ip++) {
11886                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11887                final int NA = apps.size();
11888                for (int ia=0; ia<NA; ia++) {
11889                    ProcessRecord p = apps.valueAt(ia);
11890                    if (p.thread != null && p.thread.asBinder() == app) {
11891                        return p;
11892                    }
11893                }
11894            }
11895
11896            Slog.w(TAG, "Can't find mystery application for " + reason
11897                    + " from pid=" + Binder.getCallingPid()
11898                    + " uid=" + Binder.getCallingUid() + ": " + app);
11899            return null;
11900        }
11901    }
11902
11903    /**
11904     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11905     * to append various headers to the dropbox log text.
11906     */
11907    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11908            StringBuilder sb) {
11909        // Watchdog thread ends up invoking this function (with
11910        // a null ProcessRecord) to add the stack file to dropbox.
11911        // Do not acquire a lock on this (am) in such cases, as it
11912        // could cause a potential deadlock, if and when watchdog
11913        // is invoked due to unavailability of lock on am and it
11914        // would prevent watchdog from killing system_server.
11915        if (process == null) {
11916            sb.append("Process: ").append(processName).append("\n");
11917            return;
11918        }
11919        // Note: ProcessRecord 'process' is guarded by the service
11920        // instance.  (notably process.pkgList, which could otherwise change
11921        // concurrently during execution of this method)
11922        synchronized (this) {
11923            sb.append("Process: ").append(processName).append("\n");
11924            int flags = process.info.flags;
11925            IPackageManager pm = AppGlobals.getPackageManager();
11926            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11927            for (int ip=0; ip<process.pkgList.size(); ip++) {
11928                String pkg = process.pkgList.keyAt(ip);
11929                sb.append("Package: ").append(pkg);
11930                try {
11931                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11932                    if (pi != null) {
11933                        sb.append(" v").append(pi.versionCode);
11934                        if (pi.versionName != null) {
11935                            sb.append(" (").append(pi.versionName).append(")");
11936                        }
11937                    }
11938                } catch (RemoteException e) {
11939                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11940                }
11941                sb.append("\n");
11942            }
11943        }
11944    }
11945
11946    private static String processClass(ProcessRecord process) {
11947        if (process == null || process.pid == MY_PID) {
11948            return "system_server";
11949        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11950            return "system_app";
11951        } else {
11952            return "data_app";
11953        }
11954    }
11955
11956    /**
11957     * Write a description of an error (crash, WTF, ANR) to the drop box.
11958     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11959     * @param process which caused the error, null means the system server
11960     * @param activity which triggered the error, null if unknown
11961     * @param parent activity related to the error, null if unknown
11962     * @param subject line related to the error, null if absent
11963     * @param report in long form describing the error, null if absent
11964     * @param logFile to include in the report, null if none
11965     * @param crashInfo giving an application stack trace, null if absent
11966     */
11967    public void addErrorToDropBox(String eventType,
11968            ProcessRecord process, String processName, ActivityRecord activity,
11969            ActivityRecord parent, String subject,
11970            final String report, final File logFile,
11971            final ApplicationErrorReport.CrashInfo crashInfo) {
11972        // NOTE -- this must never acquire the ActivityManagerService lock,
11973        // otherwise the watchdog may be prevented from resetting the system.
11974
11975        final String dropboxTag = processClass(process) + "_" + eventType;
11976        final DropBoxManager dbox = (DropBoxManager)
11977                mContext.getSystemService(Context.DROPBOX_SERVICE);
11978
11979        // Exit early if the dropbox isn't configured to accept this report type.
11980        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11981
11982        final StringBuilder sb = new StringBuilder(1024);
11983        appendDropBoxProcessHeaders(process, processName, sb);
11984        if (activity != null) {
11985            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11986        }
11987        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11988            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11989        }
11990        if (parent != null && parent != activity) {
11991            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11992        }
11993        if (subject != null) {
11994            sb.append("Subject: ").append(subject).append("\n");
11995        }
11996        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11997        if (Debug.isDebuggerConnected()) {
11998            sb.append("Debugger: Connected\n");
11999        }
12000        sb.append("\n");
12001
12002        // Do the rest in a worker thread to avoid blocking the caller on I/O
12003        // (After this point, we shouldn't access AMS internal data structures.)
12004        Thread worker = new Thread("Error dump: " + dropboxTag) {
12005            @Override
12006            public void run() {
12007                if (report != null) {
12008                    sb.append(report);
12009                }
12010                if (logFile != null) {
12011                    try {
12012                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12013                                    "\n\n[[TRUNCATED]]"));
12014                    } catch (IOException e) {
12015                        Slog.e(TAG, "Error reading " + logFile, e);
12016                    }
12017                }
12018                if (crashInfo != null && crashInfo.stackTrace != null) {
12019                    sb.append(crashInfo.stackTrace);
12020                }
12021
12022                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12023                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12024                if (lines > 0) {
12025                    sb.append("\n");
12026
12027                    // Merge several logcat streams, and take the last N lines
12028                    InputStreamReader input = null;
12029                    try {
12030                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12031                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12032                                "-b", "crash",
12033                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12034
12035                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12036                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12037                        input = new InputStreamReader(logcat.getInputStream());
12038
12039                        int num;
12040                        char[] buf = new char[8192];
12041                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12042                    } catch (IOException e) {
12043                        Slog.e(TAG, "Error running logcat", e);
12044                    } finally {
12045                        if (input != null) try { input.close(); } catch (IOException e) {}
12046                    }
12047                }
12048
12049                dbox.addText(dropboxTag, sb.toString());
12050            }
12051        };
12052
12053        if (process == null) {
12054            // If process is null, we are being called from some internal code
12055            // and may be about to die -- run this synchronously.
12056            worker.run();
12057        } else {
12058            worker.start();
12059        }
12060    }
12061
12062    /**
12063     * Bring up the "unexpected error" dialog box for a crashing app.
12064     * Deal with edge cases (intercepts from instrumented applications,
12065     * ActivityController, error intent receivers, that sort of thing).
12066     * @param r the application crashing
12067     * @param crashInfo describing the failure
12068     */
12069    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12070        long timeMillis = System.currentTimeMillis();
12071        String shortMsg = crashInfo.exceptionClassName;
12072        String longMsg = crashInfo.exceptionMessage;
12073        String stackTrace = crashInfo.stackTrace;
12074        if (shortMsg != null && longMsg != null) {
12075            longMsg = shortMsg + ": " + longMsg;
12076        } else if (shortMsg != null) {
12077            longMsg = shortMsg;
12078        }
12079
12080        AppErrorResult result = new AppErrorResult();
12081        synchronized (this) {
12082            if (mController != null) {
12083                try {
12084                    String name = r != null ? r.processName : null;
12085                    int pid = r != null ? r.pid : Binder.getCallingPid();
12086                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12087                    if (!mController.appCrashed(name, pid,
12088                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12089                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12090                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12091                            Slog.w(TAG, "Skip killing native crashed app " + name
12092                                    + "(" + pid + ") during testing");
12093                        } else {
12094                            Slog.w(TAG, "Force-killing crashed app " + name
12095                                    + " at watcher's request");
12096                            if (r != null) {
12097                                r.kill("crash", true);
12098                            } else {
12099                                // Huh.
12100                                Process.killProcess(pid);
12101                                Process.killProcessGroup(uid, pid);
12102                            }
12103                        }
12104                        return;
12105                    }
12106                } catch (RemoteException e) {
12107                    mController = null;
12108                    Watchdog.getInstance().setActivityController(null);
12109                }
12110            }
12111
12112            final long origId = Binder.clearCallingIdentity();
12113
12114            // If this process is running instrumentation, finish it.
12115            if (r != null && r.instrumentationClass != null) {
12116                Slog.w(TAG, "Error in app " + r.processName
12117                      + " running instrumentation " + r.instrumentationClass + ":");
12118                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12119                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12120                Bundle info = new Bundle();
12121                info.putString("shortMsg", shortMsg);
12122                info.putString("longMsg", longMsg);
12123                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12124                Binder.restoreCallingIdentity(origId);
12125                return;
12126            }
12127
12128            // If we can't identify the process or it's already exceeded its crash quota,
12129            // quit right away without showing a crash dialog.
12130            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12131                Binder.restoreCallingIdentity(origId);
12132                return;
12133            }
12134
12135            Message msg = Message.obtain();
12136            msg.what = SHOW_ERROR_MSG;
12137            HashMap data = new HashMap();
12138            data.put("result", result);
12139            data.put("app", r);
12140            msg.obj = data;
12141            mHandler.sendMessage(msg);
12142
12143            Binder.restoreCallingIdentity(origId);
12144        }
12145
12146        int res = result.get();
12147
12148        Intent appErrorIntent = null;
12149        synchronized (this) {
12150            if (r != null && !r.isolated) {
12151                // XXX Can't keep track of crash time for isolated processes,
12152                // since they don't have a persistent identity.
12153                mProcessCrashTimes.put(r.info.processName, r.uid,
12154                        SystemClock.uptimeMillis());
12155            }
12156            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12157                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12158            }
12159        }
12160
12161        if (appErrorIntent != null) {
12162            try {
12163                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12164            } catch (ActivityNotFoundException e) {
12165                Slog.w(TAG, "bug report receiver dissappeared", e);
12166            }
12167        }
12168    }
12169
12170    Intent createAppErrorIntentLocked(ProcessRecord r,
12171            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12172        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12173        if (report == null) {
12174            return null;
12175        }
12176        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12177        result.setComponent(r.errorReportReceiver);
12178        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12179        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12180        return result;
12181    }
12182
12183    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12184            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12185        if (r.errorReportReceiver == null) {
12186            return null;
12187        }
12188
12189        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12190            return null;
12191        }
12192
12193        ApplicationErrorReport report = new ApplicationErrorReport();
12194        report.packageName = r.info.packageName;
12195        report.installerPackageName = r.errorReportReceiver.getPackageName();
12196        report.processName = r.processName;
12197        report.time = timeMillis;
12198        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12199
12200        if (r.crashing || r.forceCrashReport) {
12201            report.type = ApplicationErrorReport.TYPE_CRASH;
12202            report.crashInfo = crashInfo;
12203        } else if (r.notResponding) {
12204            report.type = ApplicationErrorReport.TYPE_ANR;
12205            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12206
12207            report.anrInfo.activity = r.notRespondingReport.tag;
12208            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12209            report.anrInfo.info = r.notRespondingReport.longMsg;
12210        }
12211
12212        return report;
12213    }
12214
12215    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12216        enforceNotIsolatedCaller("getProcessesInErrorState");
12217        // assume our apps are happy - lazy create the list
12218        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12219
12220        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12221                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12222        int userId = UserHandle.getUserId(Binder.getCallingUid());
12223
12224        synchronized (this) {
12225
12226            // iterate across all processes
12227            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12228                ProcessRecord app = mLruProcesses.get(i);
12229                if (!allUsers && app.userId != userId) {
12230                    continue;
12231                }
12232                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12233                    // This one's in trouble, so we'll generate a report for it
12234                    // crashes are higher priority (in case there's a crash *and* an anr)
12235                    ActivityManager.ProcessErrorStateInfo report = null;
12236                    if (app.crashing) {
12237                        report = app.crashingReport;
12238                    } else if (app.notResponding) {
12239                        report = app.notRespondingReport;
12240                    }
12241
12242                    if (report != null) {
12243                        if (errList == null) {
12244                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12245                        }
12246                        errList.add(report);
12247                    } else {
12248                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12249                                " crashing = " + app.crashing +
12250                                " notResponding = " + app.notResponding);
12251                    }
12252                }
12253            }
12254        }
12255
12256        return errList;
12257    }
12258
12259    static int procStateToImportance(int procState, int memAdj,
12260            ActivityManager.RunningAppProcessInfo currApp) {
12261        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12262        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12263            currApp.lru = memAdj;
12264        } else {
12265            currApp.lru = 0;
12266        }
12267        return imp;
12268    }
12269
12270    private void fillInProcMemInfo(ProcessRecord app,
12271            ActivityManager.RunningAppProcessInfo outInfo) {
12272        outInfo.pid = app.pid;
12273        outInfo.uid = app.info.uid;
12274        if (mHeavyWeightProcess == app) {
12275            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12276        }
12277        if (app.persistent) {
12278            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12279        }
12280        if (app.activities.size() > 0) {
12281            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12282        }
12283        outInfo.lastTrimLevel = app.trimMemoryLevel;
12284        int adj = app.curAdj;
12285        int procState = app.curProcState;
12286        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12287        outInfo.importanceReasonCode = app.adjTypeCode;
12288        outInfo.processState = app.curProcState;
12289    }
12290
12291    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12292        enforceNotIsolatedCaller("getRunningAppProcesses");
12293        // Lazy instantiation of list
12294        List<ActivityManager.RunningAppProcessInfo> runList = null;
12295        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12296                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12297        int userId = UserHandle.getUserId(Binder.getCallingUid());
12298        synchronized (this) {
12299            // Iterate across all processes
12300            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12301                ProcessRecord app = mLruProcesses.get(i);
12302                if (!allUsers && app.userId != userId) {
12303                    continue;
12304                }
12305                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12306                    // Generate process state info for running application
12307                    ActivityManager.RunningAppProcessInfo currApp =
12308                        new ActivityManager.RunningAppProcessInfo(app.processName,
12309                                app.pid, app.getPackageList());
12310                    fillInProcMemInfo(app, currApp);
12311                    if (app.adjSource instanceof ProcessRecord) {
12312                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12313                        currApp.importanceReasonImportance =
12314                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12315                                        app.adjSourceProcState);
12316                    } else if (app.adjSource instanceof ActivityRecord) {
12317                        ActivityRecord r = (ActivityRecord)app.adjSource;
12318                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12319                    }
12320                    if (app.adjTarget instanceof ComponentName) {
12321                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12322                    }
12323                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12324                    //        + " lru=" + currApp.lru);
12325                    if (runList == null) {
12326                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12327                    }
12328                    runList.add(currApp);
12329                }
12330            }
12331        }
12332        return runList;
12333    }
12334
12335    public List<ApplicationInfo> getRunningExternalApplications() {
12336        enforceNotIsolatedCaller("getRunningExternalApplications");
12337        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12338        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12339        if (runningApps != null && runningApps.size() > 0) {
12340            Set<String> extList = new HashSet<String>();
12341            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12342                if (app.pkgList != null) {
12343                    for (String pkg : app.pkgList) {
12344                        extList.add(pkg);
12345                    }
12346                }
12347            }
12348            IPackageManager pm = AppGlobals.getPackageManager();
12349            for (String pkg : extList) {
12350                try {
12351                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12352                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12353                        retList.add(info);
12354                    }
12355                } catch (RemoteException e) {
12356                }
12357            }
12358        }
12359        return retList;
12360    }
12361
12362    @Override
12363    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12364        enforceNotIsolatedCaller("getMyMemoryState");
12365        synchronized (this) {
12366            ProcessRecord proc;
12367            synchronized (mPidsSelfLocked) {
12368                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12369            }
12370            fillInProcMemInfo(proc, outInfo);
12371        }
12372    }
12373
12374    @Override
12375    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12376        if (checkCallingPermission(android.Manifest.permission.DUMP)
12377                != PackageManager.PERMISSION_GRANTED) {
12378            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12379                    + Binder.getCallingPid()
12380                    + ", uid=" + Binder.getCallingUid()
12381                    + " without permission "
12382                    + android.Manifest.permission.DUMP);
12383            return;
12384        }
12385
12386        boolean dumpAll = false;
12387        boolean dumpClient = false;
12388        String dumpPackage = null;
12389
12390        int opti = 0;
12391        while (opti < args.length) {
12392            String opt = args[opti];
12393            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12394                break;
12395            }
12396            opti++;
12397            if ("-a".equals(opt)) {
12398                dumpAll = true;
12399            } else if ("-c".equals(opt)) {
12400                dumpClient = true;
12401            } else if ("-h".equals(opt)) {
12402                pw.println("Activity manager dump options:");
12403                pw.println("  [-a] [-c] [-h] [cmd] ...");
12404                pw.println("  cmd may be one of:");
12405                pw.println("    a[ctivities]: activity stack state");
12406                pw.println("    r[recents]: recent activities state");
12407                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12408                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12409                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12410                pw.println("    o[om]: out of memory management");
12411                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12412                pw.println("    provider [COMP_SPEC]: provider client-side state");
12413                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12414                pw.println("    service [COMP_SPEC]: service client-side state");
12415                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12416                pw.println("    all: dump all activities");
12417                pw.println("    top: dump the top activity");
12418                pw.println("    write: write all pending state to storage");
12419                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12420                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12421                pw.println("    a partial substring in a component name, a");
12422                pw.println("    hex object identifier.");
12423                pw.println("  -a: include all available server state.");
12424                pw.println("  -c: include client state.");
12425                return;
12426            } else {
12427                pw.println("Unknown argument: " + opt + "; use -h for help");
12428            }
12429        }
12430
12431        long origId = Binder.clearCallingIdentity();
12432        boolean more = false;
12433        // Is the caller requesting to dump a particular piece of data?
12434        if (opti < args.length) {
12435            String cmd = args[opti];
12436            opti++;
12437            if ("activities".equals(cmd) || "a".equals(cmd)) {
12438                synchronized (this) {
12439                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12440                }
12441            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12442                synchronized (this) {
12443                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12444                }
12445            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12446                String[] newArgs;
12447                String name;
12448                if (opti >= args.length) {
12449                    name = null;
12450                    newArgs = EMPTY_STRING_ARRAY;
12451                } else {
12452                    name = args[opti];
12453                    opti++;
12454                    newArgs = new String[args.length - opti];
12455                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12456                            args.length - opti);
12457                }
12458                synchronized (this) {
12459                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12460                }
12461            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12462                String[] newArgs;
12463                String name;
12464                if (opti >= args.length) {
12465                    name = null;
12466                    newArgs = EMPTY_STRING_ARRAY;
12467                } else {
12468                    name = args[opti];
12469                    opti++;
12470                    newArgs = new String[args.length - opti];
12471                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12472                            args.length - opti);
12473                }
12474                synchronized (this) {
12475                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12476                }
12477            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12478                String[] newArgs;
12479                String name;
12480                if (opti >= args.length) {
12481                    name = null;
12482                    newArgs = EMPTY_STRING_ARRAY;
12483                } else {
12484                    name = args[opti];
12485                    opti++;
12486                    newArgs = new String[args.length - opti];
12487                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12488                            args.length - opti);
12489                }
12490                synchronized (this) {
12491                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12492                }
12493            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12494                synchronized (this) {
12495                    dumpOomLocked(fd, pw, args, opti, true);
12496                }
12497            } else if ("provider".equals(cmd)) {
12498                String[] newArgs;
12499                String name;
12500                if (opti >= args.length) {
12501                    name = null;
12502                    newArgs = EMPTY_STRING_ARRAY;
12503                } else {
12504                    name = args[opti];
12505                    opti++;
12506                    newArgs = new String[args.length - opti];
12507                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12508                }
12509                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12510                    pw.println("No providers match: " + name);
12511                    pw.println("Use -h for help.");
12512                }
12513            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12514                synchronized (this) {
12515                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12516                }
12517            } else if ("service".equals(cmd)) {
12518                String[] newArgs;
12519                String name;
12520                if (opti >= args.length) {
12521                    name = null;
12522                    newArgs = EMPTY_STRING_ARRAY;
12523                } else {
12524                    name = args[opti];
12525                    opti++;
12526                    newArgs = new String[args.length - opti];
12527                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12528                            args.length - opti);
12529                }
12530                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12531                    pw.println("No services match: " + name);
12532                    pw.println("Use -h for help.");
12533                }
12534            } else if ("package".equals(cmd)) {
12535                String[] newArgs;
12536                if (opti >= args.length) {
12537                    pw.println("package: no package name specified");
12538                    pw.println("Use -h for help.");
12539                } else {
12540                    dumpPackage = args[opti];
12541                    opti++;
12542                    newArgs = new String[args.length - opti];
12543                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12544                            args.length - opti);
12545                    args = newArgs;
12546                    opti = 0;
12547                    more = true;
12548                }
12549            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12550                synchronized (this) {
12551                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12552                }
12553            } else if ("write".equals(cmd)) {
12554                mTaskPersister.flush();
12555                pw.println("All tasks persisted.");
12556                return;
12557            } else {
12558                // Dumping a single activity?
12559                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12560                    pw.println("Bad activity command, or no activities match: " + cmd);
12561                    pw.println("Use -h for help.");
12562                }
12563            }
12564            if (!more) {
12565                Binder.restoreCallingIdentity(origId);
12566                return;
12567            }
12568        }
12569
12570        // No piece of data specified, dump everything.
12571        synchronized (this) {
12572            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12573            pw.println();
12574            if (dumpAll) {
12575                pw.println("-------------------------------------------------------------------------------");
12576            }
12577            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12578            pw.println();
12579            if (dumpAll) {
12580                pw.println("-------------------------------------------------------------------------------");
12581            }
12582            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12583            pw.println();
12584            if (dumpAll) {
12585                pw.println("-------------------------------------------------------------------------------");
12586            }
12587            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12588            pw.println();
12589            if (dumpAll) {
12590                pw.println("-------------------------------------------------------------------------------");
12591            }
12592            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12593            pw.println();
12594            if (dumpAll) {
12595                pw.println("-------------------------------------------------------------------------------");
12596            }
12597            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12598            pw.println();
12599            if (dumpAll) {
12600                pw.println("-------------------------------------------------------------------------------");
12601            }
12602            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12603        }
12604        Binder.restoreCallingIdentity(origId);
12605    }
12606
12607    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12608            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12609        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12610
12611        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12612                dumpPackage);
12613        boolean needSep = printedAnything;
12614
12615        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12616                dumpPackage, needSep, "  mFocusedActivity: ");
12617        if (printed) {
12618            printedAnything = true;
12619            needSep = false;
12620        }
12621
12622        if (dumpPackage == null) {
12623            if (needSep) {
12624                pw.println();
12625            }
12626            needSep = true;
12627            printedAnything = true;
12628            mStackSupervisor.dump(pw, "  ");
12629        }
12630
12631        if (!printedAnything) {
12632            pw.println("  (nothing)");
12633        }
12634    }
12635
12636    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12637            int opti, boolean dumpAll, String dumpPackage) {
12638        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12639
12640        boolean printedAnything = false;
12641
12642        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12643            boolean printedHeader = false;
12644
12645            final int N = mRecentTasks.size();
12646            for (int i=0; i<N; i++) {
12647                TaskRecord tr = mRecentTasks.get(i);
12648                if (dumpPackage != null) {
12649                    if (tr.realActivity == null ||
12650                            !dumpPackage.equals(tr.realActivity)) {
12651                        continue;
12652                    }
12653                }
12654                if (!printedHeader) {
12655                    pw.println("  Recent tasks:");
12656                    printedHeader = true;
12657                    printedAnything = true;
12658                }
12659                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12660                        pw.println(tr);
12661                if (dumpAll) {
12662                    mRecentTasks.get(i).dump(pw, "    ");
12663                }
12664            }
12665        }
12666
12667        if (!printedAnything) {
12668            pw.println("  (nothing)");
12669        }
12670    }
12671
12672    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12673            int opti, boolean dumpAll, String dumpPackage) {
12674        boolean needSep = false;
12675        boolean printedAnything = false;
12676        int numPers = 0;
12677
12678        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12679
12680        if (dumpAll) {
12681            final int NP = mProcessNames.getMap().size();
12682            for (int ip=0; ip<NP; ip++) {
12683                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12684                final int NA = procs.size();
12685                for (int ia=0; ia<NA; ia++) {
12686                    ProcessRecord r = procs.valueAt(ia);
12687                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12688                        continue;
12689                    }
12690                    if (!needSep) {
12691                        pw.println("  All known processes:");
12692                        needSep = true;
12693                        printedAnything = true;
12694                    }
12695                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12696                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12697                        pw.print(" "); pw.println(r);
12698                    r.dump(pw, "    ");
12699                    if (r.persistent) {
12700                        numPers++;
12701                    }
12702                }
12703            }
12704        }
12705
12706        if (mIsolatedProcesses.size() > 0) {
12707            boolean printed = false;
12708            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12709                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12710                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12711                    continue;
12712                }
12713                if (!printed) {
12714                    if (needSep) {
12715                        pw.println();
12716                    }
12717                    pw.println("  Isolated process list (sorted by uid):");
12718                    printedAnything = true;
12719                    printed = true;
12720                    needSep = true;
12721                }
12722                pw.println(String.format("%sIsolated #%2d: %s",
12723                        "    ", i, r.toString()));
12724            }
12725        }
12726
12727        if (mLruProcesses.size() > 0) {
12728            if (needSep) {
12729                pw.println();
12730            }
12731            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12732                    pw.print(" total, non-act at ");
12733                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12734                    pw.print(", non-svc at ");
12735                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12736                    pw.println("):");
12737            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12738            needSep = true;
12739            printedAnything = true;
12740        }
12741
12742        if (dumpAll || dumpPackage != null) {
12743            synchronized (mPidsSelfLocked) {
12744                boolean printed = false;
12745                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12746                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12747                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12748                        continue;
12749                    }
12750                    if (!printed) {
12751                        if (needSep) pw.println();
12752                        needSep = true;
12753                        pw.println("  PID mappings:");
12754                        printed = true;
12755                        printedAnything = true;
12756                    }
12757                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12758                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12759                }
12760            }
12761        }
12762
12763        if (mForegroundProcesses.size() > 0) {
12764            synchronized (mPidsSelfLocked) {
12765                boolean printed = false;
12766                for (int i=0; i<mForegroundProcesses.size(); i++) {
12767                    ProcessRecord r = mPidsSelfLocked.get(
12768                            mForegroundProcesses.valueAt(i).pid);
12769                    if (dumpPackage != null && (r == null
12770                            || !r.pkgList.containsKey(dumpPackage))) {
12771                        continue;
12772                    }
12773                    if (!printed) {
12774                        if (needSep) pw.println();
12775                        needSep = true;
12776                        pw.println("  Foreground Processes:");
12777                        printed = true;
12778                        printedAnything = true;
12779                    }
12780                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12781                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12782                }
12783            }
12784        }
12785
12786        if (mPersistentStartingProcesses.size() > 0) {
12787            if (needSep) pw.println();
12788            needSep = true;
12789            printedAnything = true;
12790            pw.println("  Persisent processes that are starting:");
12791            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12792                    "Starting Norm", "Restarting PERS", dumpPackage);
12793        }
12794
12795        if (mRemovedProcesses.size() > 0) {
12796            if (needSep) pw.println();
12797            needSep = true;
12798            printedAnything = true;
12799            pw.println("  Processes that are being removed:");
12800            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12801                    "Removed Norm", "Removed PERS", dumpPackage);
12802        }
12803
12804        if (mProcessesOnHold.size() > 0) {
12805            if (needSep) pw.println();
12806            needSep = true;
12807            printedAnything = true;
12808            pw.println("  Processes that are on old until the system is ready:");
12809            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12810                    "OnHold Norm", "OnHold PERS", dumpPackage);
12811        }
12812
12813        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12814
12815        if (mProcessCrashTimes.getMap().size() > 0) {
12816            boolean printed = false;
12817            long now = SystemClock.uptimeMillis();
12818            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12819            final int NP = pmap.size();
12820            for (int ip=0; ip<NP; ip++) {
12821                String pname = pmap.keyAt(ip);
12822                SparseArray<Long> uids = pmap.valueAt(ip);
12823                final int N = uids.size();
12824                for (int i=0; i<N; i++) {
12825                    int puid = uids.keyAt(i);
12826                    ProcessRecord r = mProcessNames.get(pname, puid);
12827                    if (dumpPackage != null && (r == null
12828                            || !r.pkgList.containsKey(dumpPackage))) {
12829                        continue;
12830                    }
12831                    if (!printed) {
12832                        if (needSep) pw.println();
12833                        needSep = true;
12834                        pw.println("  Time since processes crashed:");
12835                        printed = true;
12836                        printedAnything = true;
12837                    }
12838                    pw.print("    Process "); pw.print(pname);
12839                            pw.print(" uid "); pw.print(puid);
12840                            pw.print(": last crashed ");
12841                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12842                            pw.println(" ago");
12843                }
12844            }
12845        }
12846
12847        if (mBadProcesses.getMap().size() > 0) {
12848            boolean printed = false;
12849            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12850            final int NP = pmap.size();
12851            for (int ip=0; ip<NP; ip++) {
12852                String pname = pmap.keyAt(ip);
12853                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12854                final int N = uids.size();
12855                for (int i=0; i<N; i++) {
12856                    int puid = uids.keyAt(i);
12857                    ProcessRecord r = mProcessNames.get(pname, puid);
12858                    if (dumpPackage != null && (r == null
12859                            || !r.pkgList.containsKey(dumpPackage))) {
12860                        continue;
12861                    }
12862                    if (!printed) {
12863                        if (needSep) pw.println();
12864                        needSep = true;
12865                        pw.println("  Bad processes:");
12866                        printedAnything = true;
12867                    }
12868                    BadProcessInfo info = uids.valueAt(i);
12869                    pw.print("    Bad process "); pw.print(pname);
12870                            pw.print(" uid "); pw.print(puid);
12871                            pw.print(": crashed at time "); pw.println(info.time);
12872                    if (info.shortMsg != null) {
12873                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12874                    }
12875                    if (info.longMsg != null) {
12876                        pw.print("      Long msg: "); pw.println(info.longMsg);
12877                    }
12878                    if (info.stack != null) {
12879                        pw.println("      Stack:");
12880                        int lastPos = 0;
12881                        for (int pos=0; pos<info.stack.length(); pos++) {
12882                            if (info.stack.charAt(pos) == '\n') {
12883                                pw.print("        ");
12884                                pw.write(info.stack, lastPos, pos-lastPos);
12885                                pw.println();
12886                                lastPos = pos+1;
12887                            }
12888                        }
12889                        if (lastPos < info.stack.length()) {
12890                            pw.print("        ");
12891                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12892                            pw.println();
12893                        }
12894                    }
12895                }
12896            }
12897        }
12898
12899        if (dumpPackage == null) {
12900            pw.println();
12901            needSep = false;
12902            pw.println("  mStartedUsers:");
12903            for (int i=0; i<mStartedUsers.size(); i++) {
12904                UserStartedState uss = mStartedUsers.valueAt(i);
12905                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12906                        pw.print(": "); uss.dump("", pw);
12907            }
12908            pw.print("  mStartedUserArray: [");
12909            for (int i=0; i<mStartedUserArray.length; i++) {
12910                if (i > 0) pw.print(", ");
12911                pw.print(mStartedUserArray[i]);
12912            }
12913            pw.println("]");
12914            pw.print("  mUserLru: [");
12915            for (int i=0; i<mUserLru.size(); i++) {
12916                if (i > 0) pw.print(", ");
12917                pw.print(mUserLru.get(i));
12918            }
12919            pw.println("]");
12920            if (dumpAll) {
12921                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12922            }
12923            synchronized (mUserProfileGroupIdsSelfLocked) {
12924                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12925                    pw.println("  mUserProfileGroupIds:");
12926                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12927                        pw.print("    User #");
12928                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12929                        pw.print(" -> profile #");
12930                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12931                    }
12932                }
12933            }
12934        }
12935        if (mHomeProcess != null && (dumpPackage == null
12936                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12937            if (needSep) {
12938                pw.println();
12939                needSep = false;
12940            }
12941            pw.println("  mHomeProcess: " + mHomeProcess);
12942        }
12943        if (mPreviousProcess != null && (dumpPackage == null
12944                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12945            if (needSep) {
12946                pw.println();
12947                needSep = false;
12948            }
12949            pw.println("  mPreviousProcess: " + mPreviousProcess);
12950        }
12951        if (dumpAll) {
12952            StringBuilder sb = new StringBuilder(128);
12953            sb.append("  mPreviousProcessVisibleTime: ");
12954            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12955            pw.println(sb);
12956        }
12957        if (mHeavyWeightProcess != null && (dumpPackage == null
12958                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12959            if (needSep) {
12960                pw.println();
12961                needSep = false;
12962            }
12963            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12964        }
12965        if (dumpPackage == null) {
12966            pw.println("  mConfiguration: " + mConfiguration);
12967        }
12968        if (dumpAll) {
12969            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12970            if (mCompatModePackages.getPackages().size() > 0) {
12971                boolean printed = false;
12972                for (Map.Entry<String, Integer> entry
12973                        : mCompatModePackages.getPackages().entrySet()) {
12974                    String pkg = entry.getKey();
12975                    int mode = entry.getValue();
12976                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12977                        continue;
12978                    }
12979                    if (!printed) {
12980                        pw.println("  mScreenCompatPackages:");
12981                        printed = true;
12982                    }
12983                    pw.print("    "); pw.print(pkg); pw.print(": ");
12984                            pw.print(mode); pw.println();
12985                }
12986            }
12987        }
12988        if (dumpPackage == null) {
12989            if (mSleeping || mWentToSleep || mLockScreenShown) {
12990                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12991                        + " mLockScreenShown " + mLockScreenShown);
12992            }
12993            if (mShuttingDown || mRunningVoice) {
12994                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12995            }
12996        }
12997        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12998                || mOrigWaitForDebugger) {
12999            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13000                    || dumpPackage.equals(mOrigDebugApp)) {
13001                if (needSep) {
13002                    pw.println();
13003                    needSep = false;
13004                }
13005                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13006                        + " mDebugTransient=" + mDebugTransient
13007                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13008            }
13009        }
13010        if (mOpenGlTraceApp != null) {
13011            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13012                if (needSep) {
13013                    pw.println();
13014                    needSep = false;
13015                }
13016                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13017            }
13018        }
13019        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13020                || mProfileFd != null) {
13021            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13022                if (needSep) {
13023                    pw.println();
13024                    needSep = false;
13025                }
13026                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13027                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13028                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13029                        + mAutoStopProfiler);
13030                pw.println("  mProfileType=" + mProfileType);
13031            }
13032        }
13033        if (dumpPackage == null) {
13034            if (mAlwaysFinishActivities || mController != null) {
13035                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13036                        + " mController=" + mController);
13037            }
13038            if (dumpAll) {
13039                pw.println("  Total persistent processes: " + numPers);
13040                pw.println("  mProcessesReady=" + mProcessesReady
13041                        + " mSystemReady=" + mSystemReady
13042                        + " mBooted=" + mBooted
13043                        + " mFactoryTest=" + mFactoryTest);
13044                pw.println("  mBooting=" + mBooting
13045                        + " mCallFinishBooting=" + mCallFinishBooting
13046                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13047                pw.print("  mLastPowerCheckRealtime=");
13048                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13049                        pw.println("");
13050                pw.print("  mLastPowerCheckUptime=");
13051                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13052                        pw.println("");
13053                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13054                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13055                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13056                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13057                        + " (" + mLruProcesses.size() + " total)"
13058                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13059                        + " mNumServiceProcs=" + mNumServiceProcs
13060                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13061                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13062                        + " mLastMemoryLevel" + mLastMemoryLevel
13063                        + " mLastNumProcesses" + mLastNumProcesses);
13064                long now = SystemClock.uptimeMillis();
13065                pw.print("  mLastIdleTime=");
13066                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13067                        pw.print(" mLowRamSinceLastIdle=");
13068                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13069                        pw.println();
13070            }
13071        }
13072
13073        if (!printedAnything) {
13074            pw.println("  (nothing)");
13075        }
13076    }
13077
13078    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13079            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13080        if (mProcessesToGc.size() > 0) {
13081            boolean printed = false;
13082            long now = SystemClock.uptimeMillis();
13083            for (int i=0; i<mProcessesToGc.size(); i++) {
13084                ProcessRecord proc = mProcessesToGc.get(i);
13085                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13086                    continue;
13087                }
13088                if (!printed) {
13089                    if (needSep) pw.println();
13090                    needSep = true;
13091                    pw.println("  Processes that are waiting to GC:");
13092                    printed = true;
13093                }
13094                pw.print("    Process "); pw.println(proc);
13095                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13096                        pw.print(", last gced=");
13097                        pw.print(now-proc.lastRequestedGc);
13098                        pw.print(" ms ago, last lowMem=");
13099                        pw.print(now-proc.lastLowMemory);
13100                        pw.println(" ms ago");
13101
13102            }
13103        }
13104        return needSep;
13105    }
13106
13107    void printOomLevel(PrintWriter pw, String name, int adj) {
13108        pw.print("    ");
13109        if (adj >= 0) {
13110            pw.print(' ');
13111            if (adj < 10) pw.print(' ');
13112        } else {
13113            if (adj > -10) pw.print(' ');
13114        }
13115        pw.print(adj);
13116        pw.print(": ");
13117        pw.print(name);
13118        pw.print(" (");
13119        pw.print(mProcessList.getMemLevel(adj)/1024);
13120        pw.println(" kB)");
13121    }
13122
13123    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13124            int opti, boolean dumpAll) {
13125        boolean needSep = false;
13126
13127        if (mLruProcesses.size() > 0) {
13128            if (needSep) pw.println();
13129            needSep = true;
13130            pw.println("  OOM levels:");
13131            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13132            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13133            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13134            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13135            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13136            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13137            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13138            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13139            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13140            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13141            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13142            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13143            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13144            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13145
13146            if (needSep) pw.println();
13147            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13148                    pw.print(" total, non-act at ");
13149                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13150                    pw.print(", non-svc at ");
13151                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13152                    pw.println("):");
13153            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13154            needSep = true;
13155        }
13156
13157        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13158
13159        pw.println();
13160        pw.println("  mHomeProcess: " + mHomeProcess);
13161        pw.println("  mPreviousProcess: " + mPreviousProcess);
13162        if (mHeavyWeightProcess != null) {
13163            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13164        }
13165
13166        return true;
13167    }
13168
13169    /**
13170     * There are three ways to call this:
13171     *  - no provider specified: dump all the providers
13172     *  - a flattened component name that matched an existing provider was specified as the
13173     *    first arg: dump that one provider
13174     *  - the first arg isn't the flattened component name of an existing provider:
13175     *    dump all providers whose component contains the first arg as a substring
13176     */
13177    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13178            int opti, boolean dumpAll) {
13179        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13180    }
13181
13182    static class ItemMatcher {
13183        ArrayList<ComponentName> components;
13184        ArrayList<String> strings;
13185        ArrayList<Integer> objects;
13186        boolean all;
13187
13188        ItemMatcher() {
13189            all = true;
13190        }
13191
13192        void build(String name) {
13193            ComponentName componentName = ComponentName.unflattenFromString(name);
13194            if (componentName != null) {
13195                if (components == null) {
13196                    components = new ArrayList<ComponentName>();
13197                }
13198                components.add(componentName);
13199                all = false;
13200            } else {
13201                int objectId = 0;
13202                // Not a '/' separated full component name; maybe an object ID?
13203                try {
13204                    objectId = Integer.parseInt(name, 16);
13205                    if (objects == null) {
13206                        objects = new ArrayList<Integer>();
13207                    }
13208                    objects.add(objectId);
13209                    all = false;
13210                } catch (RuntimeException e) {
13211                    // Not an integer; just do string match.
13212                    if (strings == null) {
13213                        strings = new ArrayList<String>();
13214                    }
13215                    strings.add(name);
13216                    all = false;
13217                }
13218            }
13219        }
13220
13221        int build(String[] args, int opti) {
13222            for (; opti<args.length; opti++) {
13223                String name = args[opti];
13224                if ("--".equals(name)) {
13225                    return opti+1;
13226                }
13227                build(name);
13228            }
13229            return opti;
13230        }
13231
13232        boolean match(Object object, ComponentName comp) {
13233            if (all) {
13234                return true;
13235            }
13236            if (components != null) {
13237                for (int i=0; i<components.size(); i++) {
13238                    if (components.get(i).equals(comp)) {
13239                        return true;
13240                    }
13241                }
13242            }
13243            if (objects != null) {
13244                for (int i=0; i<objects.size(); i++) {
13245                    if (System.identityHashCode(object) == objects.get(i)) {
13246                        return true;
13247                    }
13248                }
13249            }
13250            if (strings != null) {
13251                String flat = comp.flattenToString();
13252                for (int i=0; i<strings.size(); i++) {
13253                    if (flat.contains(strings.get(i))) {
13254                        return true;
13255                    }
13256                }
13257            }
13258            return false;
13259        }
13260    }
13261
13262    /**
13263     * There are three things that cmd can be:
13264     *  - a flattened component name that matches an existing activity
13265     *  - the cmd arg isn't the flattened component name of an existing activity:
13266     *    dump all activity whose component contains the cmd as a substring
13267     *  - A hex number of the ActivityRecord object instance.
13268     */
13269    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13270            int opti, boolean dumpAll) {
13271        ArrayList<ActivityRecord> activities;
13272
13273        synchronized (this) {
13274            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13275        }
13276
13277        if (activities.size() <= 0) {
13278            return false;
13279        }
13280
13281        String[] newArgs = new String[args.length - opti];
13282        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13283
13284        TaskRecord lastTask = null;
13285        boolean needSep = false;
13286        for (int i=activities.size()-1; i>=0; i--) {
13287            ActivityRecord r = activities.get(i);
13288            if (needSep) {
13289                pw.println();
13290            }
13291            needSep = true;
13292            synchronized (this) {
13293                if (lastTask != r.task) {
13294                    lastTask = r.task;
13295                    pw.print("TASK "); pw.print(lastTask.affinity);
13296                            pw.print(" id="); pw.println(lastTask.taskId);
13297                    if (dumpAll) {
13298                        lastTask.dump(pw, "  ");
13299                    }
13300                }
13301            }
13302            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13303        }
13304        return true;
13305    }
13306
13307    /**
13308     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13309     * there is a thread associated with the activity.
13310     */
13311    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13312            final ActivityRecord r, String[] args, boolean dumpAll) {
13313        String innerPrefix = prefix + "  ";
13314        synchronized (this) {
13315            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13316                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13317                    pw.print(" pid=");
13318                    if (r.app != null) pw.println(r.app.pid);
13319                    else pw.println("(not running)");
13320            if (dumpAll) {
13321                r.dump(pw, innerPrefix);
13322            }
13323        }
13324        if (r.app != null && r.app.thread != null) {
13325            // flush anything that is already in the PrintWriter since the thread is going
13326            // to write to the file descriptor directly
13327            pw.flush();
13328            try {
13329                TransferPipe tp = new TransferPipe();
13330                try {
13331                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13332                            r.appToken, innerPrefix, args);
13333                    tp.go(fd);
13334                } finally {
13335                    tp.kill();
13336                }
13337            } catch (IOException e) {
13338                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13339            } catch (RemoteException e) {
13340                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13341            }
13342        }
13343    }
13344
13345    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13346            int opti, boolean dumpAll, String dumpPackage) {
13347        boolean needSep = false;
13348        boolean onlyHistory = false;
13349        boolean printedAnything = false;
13350
13351        if ("history".equals(dumpPackage)) {
13352            if (opti < args.length && "-s".equals(args[opti])) {
13353                dumpAll = false;
13354            }
13355            onlyHistory = true;
13356            dumpPackage = null;
13357        }
13358
13359        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13360        if (!onlyHistory && dumpAll) {
13361            if (mRegisteredReceivers.size() > 0) {
13362                boolean printed = false;
13363                Iterator it = mRegisteredReceivers.values().iterator();
13364                while (it.hasNext()) {
13365                    ReceiverList r = (ReceiverList)it.next();
13366                    if (dumpPackage != null && (r.app == null ||
13367                            !dumpPackage.equals(r.app.info.packageName))) {
13368                        continue;
13369                    }
13370                    if (!printed) {
13371                        pw.println("  Registered Receivers:");
13372                        needSep = true;
13373                        printed = true;
13374                        printedAnything = true;
13375                    }
13376                    pw.print("  * "); pw.println(r);
13377                    r.dump(pw, "    ");
13378                }
13379            }
13380
13381            if (mReceiverResolver.dump(pw, needSep ?
13382                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13383                    "    ", dumpPackage, false)) {
13384                needSep = true;
13385                printedAnything = true;
13386            }
13387        }
13388
13389        for (BroadcastQueue q : mBroadcastQueues) {
13390            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13391            printedAnything |= needSep;
13392        }
13393
13394        needSep = true;
13395
13396        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13397            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13398                if (needSep) {
13399                    pw.println();
13400                }
13401                needSep = true;
13402                printedAnything = true;
13403                pw.print("  Sticky broadcasts for user ");
13404                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13405                StringBuilder sb = new StringBuilder(128);
13406                for (Map.Entry<String, ArrayList<Intent>> ent
13407                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13408                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13409                    if (dumpAll) {
13410                        pw.println(":");
13411                        ArrayList<Intent> intents = ent.getValue();
13412                        final int N = intents.size();
13413                        for (int i=0; i<N; i++) {
13414                            sb.setLength(0);
13415                            sb.append("    Intent: ");
13416                            intents.get(i).toShortString(sb, false, true, false, false);
13417                            pw.println(sb.toString());
13418                            Bundle bundle = intents.get(i).getExtras();
13419                            if (bundle != null) {
13420                                pw.print("      ");
13421                                pw.println(bundle.toString());
13422                            }
13423                        }
13424                    } else {
13425                        pw.println("");
13426                    }
13427                }
13428            }
13429        }
13430
13431        if (!onlyHistory && dumpAll) {
13432            pw.println();
13433            for (BroadcastQueue queue : mBroadcastQueues) {
13434                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13435                        + queue.mBroadcastsScheduled);
13436            }
13437            pw.println("  mHandler:");
13438            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13439            needSep = true;
13440            printedAnything = true;
13441        }
13442
13443        if (!printedAnything) {
13444            pw.println("  (nothing)");
13445        }
13446    }
13447
13448    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13449            int opti, boolean dumpAll, String dumpPackage) {
13450        boolean needSep;
13451        boolean printedAnything = false;
13452
13453        ItemMatcher matcher = new ItemMatcher();
13454        matcher.build(args, opti);
13455
13456        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13457
13458        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13459        printedAnything |= needSep;
13460
13461        if (mLaunchingProviders.size() > 0) {
13462            boolean printed = false;
13463            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13464                ContentProviderRecord r = mLaunchingProviders.get(i);
13465                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13466                    continue;
13467                }
13468                if (!printed) {
13469                    if (needSep) pw.println();
13470                    needSep = true;
13471                    pw.println("  Launching content providers:");
13472                    printed = true;
13473                    printedAnything = true;
13474                }
13475                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13476                        pw.println(r);
13477            }
13478        }
13479
13480        if (mGrantedUriPermissions.size() > 0) {
13481            boolean printed = false;
13482            int dumpUid = -2;
13483            if (dumpPackage != null) {
13484                try {
13485                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13486                } catch (NameNotFoundException e) {
13487                    dumpUid = -1;
13488                }
13489            }
13490            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13491                int uid = mGrantedUriPermissions.keyAt(i);
13492                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13493                    continue;
13494                }
13495                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13496                if (!printed) {
13497                    if (needSep) pw.println();
13498                    needSep = true;
13499                    pw.println("  Granted Uri Permissions:");
13500                    printed = true;
13501                    printedAnything = true;
13502                }
13503                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13504                for (UriPermission perm : perms.values()) {
13505                    pw.print("    "); pw.println(perm);
13506                    if (dumpAll) {
13507                        perm.dump(pw, "      ");
13508                    }
13509                }
13510            }
13511        }
13512
13513        if (!printedAnything) {
13514            pw.println("  (nothing)");
13515        }
13516    }
13517
13518    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13519            int opti, boolean dumpAll, String dumpPackage) {
13520        boolean printed = false;
13521
13522        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13523
13524        if (mIntentSenderRecords.size() > 0) {
13525            Iterator<WeakReference<PendingIntentRecord>> it
13526                    = mIntentSenderRecords.values().iterator();
13527            while (it.hasNext()) {
13528                WeakReference<PendingIntentRecord> ref = it.next();
13529                PendingIntentRecord rec = ref != null ? ref.get(): null;
13530                if (dumpPackage != null && (rec == null
13531                        || !dumpPackage.equals(rec.key.packageName))) {
13532                    continue;
13533                }
13534                printed = true;
13535                if (rec != null) {
13536                    pw.print("  * "); pw.println(rec);
13537                    if (dumpAll) {
13538                        rec.dump(pw, "    ");
13539                    }
13540                } else {
13541                    pw.print("  * "); pw.println(ref);
13542                }
13543            }
13544        }
13545
13546        if (!printed) {
13547            pw.println("  (nothing)");
13548        }
13549    }
13550
13551    private static final int dumpProcessList(PrintWriter pw,
13552            ActivityManagerService service, List list,
13553            String prefix, String normalLabel, String persistentLabel,
13554            String dumpPackage) {
13555        int numPers = 0;
13556        final int N = list.size()-1;
13557        for (int i=N; i>=0; i--) {
13558            ProcessRecord r = (ProcessRecord)list.get(i);
13559            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13560                continue;
13561            }
13562            pw.println(String.format("%s%s #%2d: %s",
13563                    prefix, (r.persistent ? persistentLabel : normalLabel),
13564                    i, r.toString()));
13565            if (r.persistent) {
13566                numPers++;
13567            }
13568        }
13569        return numPers;
13570    }
13571
13572    private static final boolean dumpProcessOomList(PrintWriter pw,
13573            ActivityManagerService service, List<ProcessRecord> origList,
13574            String prefix, String normalLabel, String persistentLabel,
13575            boolean inclDetails, String dumpPackage) {
13576
13577        ArrayList<Pair<ProcessRecord, Integer>> list
13578                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13579        for (int i=0; i<origList.size(); i++) {
13580            ProcessRecord r = origList.get(i);
13581            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13582                continue;
13583            }
13584            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13585        }
13586
13587        if (list.size() <= 0) {
13588            return false;
13589        }
13590
13591        Comparator<Pair<ProcessRecord, Integer>> comparator
13592                = new Comparator<Pair<ProcessRecord, Integer>>() {
13593            @Override
13594            public int compare(Pair<ProcessRecord, Integer> object1,
13595                    Pair<ProcessRecord, Integer> object2) {
13596                if (object1.first.setAdj != object2.first.setAdj) {
13597                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13598                }
13599                if (object1.second.intValue() != object2.second.intValue()) {
13600                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13601                }
13602                return 0;
13603            }
13604        };
13605
13606        Collections.sort(list, comparator);
13607
13608        final long curRealtime = SystemClock.elapsedRealtime();
13609        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13610        final long curUptime = SystemClock.uptimeMillis();
13611        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13612
13613        for (int i=list.size()-1; i>=0; i--) {
13614            ProcessRecord r = list.get(i).first;
13615            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13616            char schedGroup;
13617            switch (r.setSchedGroup) {
13618                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13619                    schedGroup = 'B';
13620                    break;
13621                case Process.THREAD_GROUP_DEFAULT:
13622                    schedGroup = 'F';
13623                    break;
13624                default:
13625                    schedGroup = '?';
13626                    break;
13627            }
13628            char foreground;
13629            if (r.foregroundActivities) {
13630                foreground = 'A';
13631            } else if (r.foregroundServices) {
13632                foreground = 'S';
13633            } else {
13634                foreground = ' ';
13635            }
13636            String procState = ProcessList.makeProcStateString(r.curProcState);
13637            pw.print(prefix);
13638            pw.print(r.persistent ? persistentLabel : normalLabel);
13639            pw.print(" #");
13640            int num = (origList.size()-1)-list.get(i).second;
13641            if (num < 10) pw.print(' ');
13642            pw.print(num);
13643            pw.print(": ");
13644            pw.print(oomAdj);
13645            pw.print(' ');
13646            pw.print(schedGroup);
13647            pw.print('/');
13648            pw.print(foreground);
13649            pw.print('/');
13650            pw.print(procState);
13651            pw.print(" trm:");
13652            if (r.trimMemoryLevel < 10) pw.print(' ');
13653            pw.print(r.trimMemoryLevel);
13654            pw.print(' ');
13655            pw.print(r.toShortString());
13656            pw.print(" (");
13657            pw.print(r.adjType);
13658            pw.println(')');
13659            if (r.adjSource != null || r.adjTarget != null) {
13660                pw.print(prefix);
13661                pw.print("    ");
13662                if (r.adjTarget instanceof ComponentName) {
13663                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13664                } else if (r.adjTarget != null) {
13665                    pw.print(r.adjTarget.toString());
13666                } else {
13667                    pw.print("{null}");
13668                }
13669                pw.print("<=");
13670                if (r.adjSource instanceof ProcessRecord) {
13671                    pw.print("Proc{");
13672                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13673                    pw.println("}");
13674                } else if (r.adjSource != null) {
13675                    pw.println(r.adjSource.toString());
13676                } else {
13677                    pw.println("{null}");
13678                }
13679            }
13680            if (inclDetails) {
13681                pw.print(prefix);
13682                pw.print("    ");
13683                pw.print("oom: max="); pw.print(r.maxAdj);
13684                pw.print(" curRaw="); pw.print(r.curRawAdj);
13685                pw.print(" setRaw="); pw.print(r.setRawAdj);
13686                pw.print(" cur="); pw.print(r.curAdj);
13687                pw.print(" set="); pw.println(r.setAdj);
13688                pw.print(prefix);
13689                pw.print("    ");
13690                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13691                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13692                pw.print(" lastPss="); pw.print(r.lastPss);
13693                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13694                pw.print(prefix);
13695                pw.print("    ");
13696                pw.print("cached="); pw.print(r.cached);
13697                pw.print(" empty="); pw.print(r.empty);
13698                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13699
13700                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13701                    if (r.lastWakeTime != 0) {
13702                        long wtime;
13703                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13704                        synchronized (stats) {
13705                            wtime = stats.getProcessWakeTime(r.info.uid,
13706                                    r.pid, curRealtime);
13707                        }
13708                        long timeUsed = wtime - r.lastWakeTime;
13709                        pw.print(prefix);
13710                        pw.print("    ");
13711                        pw.print("keep awake over ");
13712                        TimeUtils.formatDuration(realtimeSince, pw);
13713                        pw.print(" used ");
13714                        TimeUtils.formatDuration(timeUsed, pw);
13715                        pw.print(" (");
13716                        pw.print((timeUsed*100)/realtimeSince);
13717                        pw.println("%)");
13718                    }
13719                    if (r.lastCpuTime != 0) {
13720                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13721                        pw.print(prefix);
13722                        pw.print("    ");
13723                        pw.print("run cpu over ");
13724                        TimeUtils.formatDuration(uptimeSince, pw);
13725                        pw.print(" used ");
13726                        TimeUtils.formatDuration(timeUsed, pw);
13727                        pw.print(" (");
13728                        pw.print((timeUsed*100)/uptimeSince);
13729                        pw.println("%)");
13730                    }
13731                }
13732            }
13733        }
13734        return true;
13735    }
13736
13737    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13738            String[] args) {
13739        ArrayList<ProcessRecord> procs;
13740        synchronized (this) {
13741            if (args != null && args.length > start
13742                    && args[start].charAt(0) != '-') {
13743                procs = new ArrayList<ProcessRecord>();
13744                int pid = -1;
13745                try {
13746                    pid = Integer.parseInt(args[start]);
13747                } catch (NumberFormatException e) {
13748                }
13749                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13750                    ProcessRecord proc = mLruProcesses.get(i);
13751                    if (proc.pid == pid) {
13752                        procs.add(proc);
13753                    } else if (allPkgs && proc.pkgList != null
13754                            && proc.pkgList.containsKey(args[start])) {
13755                        procs.add(proc);
13756                    } else if (proc.processName.equals(args[start])) {
13757                        procs.add(proc);
13758                    }
13759                }
13760                if (procs.size() <= 0) {
13761                    return null;
13762                }
13763            } else {
13764                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13765            }
13766        }
13767        return procs;
13768    }
13769
13770    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13771            PrintWriter pw, String[] args) {
13772        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13773        if (procs == null) {
13774            pw.println("No process found for: " + args[0]);
13775            return;
13776        }
13777
13778        long uptime = SystemClock.uptimeMillis();
13779        long realtime = SystemClock.elapsedRealtime();
13780        pw.println("Applications Graphics Acceleration Info:");
13781        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13782
13783        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13784            ProcessRecord r = procs.get(i);
13785            if (r.thread != null) {
13786                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13787                pw.flush();
13788                try {
13789                    TransferPipe tp = new TransferPipe();
13790                    try {
13791                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13792                        tp.go(fd);
13793                    } finally {
13794                        tp.kill();
13795                    }
13796                } catch (IOException e) {
13797                    pw.println("Failure while dumping the app: " + r);
13798                    pw.flush();
13799                } catch (RemoteException e) {
13800                    pw.println("Got a RemoteException while dumping the app " + r);
13801                    pw.flush();
13802                }
13803            }
13804        }
13805    }
13806
13807    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13808        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13809        if (procs == null) {
13810            pw.println("No process found for: " + args[0]);
13811            return;
13812        }
13813
13814        pw.println("Applications Database Info:");
13815
13816        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13817            ProcessRecord r = procs.get(i);
13818            if (r.thread != null) {
13819                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13820                pw.flush();
13821                try {
13822                    TransferPipe tp = new TransferPipe();
13823                    try {
13824                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13825                        tp.go(fd);
13826                    } finally {
13827                        tp.kill();
13828                    }
13829                } catch (IOException e) {
13830                    pw.println("Failure while dumping the app: " + r);
13831                    pw.flush();
13832                } catch (RemoteException e) {
13833                    pw.println("Got a RemoteException while dumping the app " + r);
13834                    pw.flush();
13835                }
13836            }
13837        }
13838    }
13839
13840    final static class MemItem {
13841        final boolean isProc;
13842        final String label;
13843        final String shortLabel;
13844        final long pss;
13845        final int id;
13846        final boolean hasActivities;
13847        ArrayList<MemItem> subitems;
13848
13849        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13850                boolean _hasActivities) {
13851            isProc = true;
13852            label = _label;
13853            shortLabel = _shortLabel;
13854            pss = _pss;
13855            id = _id;
13856            hasActivities = _hasActivities;
13857        }
13858
13859        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13860            isProc = false;
13861            label = _label;
13862            shortLabel = _shortLabel;
13863            pss = _pss;
13864            id = _id;
13865            hasActivities = false;
13866        }
13867    }
13868
13869    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13870            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13871        if (sort && !isCompact) {
13872            Collections.sort(items, new Comparator<MemItem>() {
13873                @Override
13874                public int compare(MemItem lhs, MemItem rhs) {
13875                    if (lhs.pss < rhs.pss) {
13876                        return 1;
13877                    } else if (lhs.pss > rhs.pss) {
13878                        return -1;
13879                    }
13880                    return 0;
13881                }
13882            });
13883        }
13884
13885        for (int i=0; i<items.size(); i++) {
13886            MemItem mi = items.get(i);
13887            if (!isCompact) {
13888                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13889            } else if (mi.isProc) {
13890                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13891                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13892                pw.println(mi.hasActivities ? ",a" : ",e");
13893            } else {
13894                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13895                pw.println(mi.pss);
13896            }
13897            if (mi.subitems != null) {
13898                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13899                        true, isCompact);
13900            }
13901        }
13902    }
13903
13904    // These are in KB.
13905    static final long[] DUMP_MEM_BUCKETS = new long[] {
13906        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13907        120*1024, 160*1024, 200*1024,
13908        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13909        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13910    };
13911
13912    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13913            boolean stackLike) {
13914        int start = label.lastIndexOf('.');
13915        if (start >= 0) start++;
13916        else start = 0;
13917        int end = label.length();
13918        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13919            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13920                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13921                out.append(bucket);
13922                out.append(stackLike ? "MB." : "MB ");
13923                out.append(label, start, end);
13924                return;
13925            }
13926        }
13927        out.append(memKB/1024);
13928        out.append(stackLike ? "MB." : "MB ");
13929        out.append(label, start, end);
13930    }
13931
13932    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13933            ProcessList.NATIVE_ADJ,
13934            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13935            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13936            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13937            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13938            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13939            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13940    };
13941    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13942            "Native",
13943            "System", "Persistent", "Persistent Service", "Foreground",
13944            "Visible", "Perceptible",
13945            "Heavy Weight", "Backup",
13946            "A Services", "Home",
13947            "Previous", "B Services", "Cached"
13948    };
13949    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13950            "native",
13951            "sys", "pers", "persvc", "fore",
13952            "vis", "percept",
13953            "heavy", "backup",
13954            "servicea", "home",
13955            "prev", "serviceb", "cached"
13956    };
13957
13958    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13959            long realtime, boolean isCheckinRequest, boolean isCompact) {
13960        if (isCheckinRequest || isCompact) {
13961            // short checkin version
13962            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13963        } else {
13964            pw.println("Applications Memory Usage (kB):");
13965            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13966        }
13967    }
13968
13969    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13970            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13971        boolean dumpDetails = false;
13972        boolean dumpFullDetails = false;
13973        boolean dumpDalvik = false;
13974        boolean oomOnly = false;
13975        boolean isCompact = false;
13976        boolean localOnly = false;
13977        boolean packages = false;
13978
13979        int opti = 0;
13980        while (opti < args.length) {
13981            String opt = args[opti];
13982            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13983                break;
13984            }
13985            opti++;
13986            if ("-a".equals(opt)) {
13987                dumpDetails = true;
13988                dumpFullDetails = true;
13989                dumpDalvik = true;
13990            } else if ("-d".equals(opt)) {
13991                dumpDalvik = true;
13992            } else if ("-c".equals(opt)) {
13993                isCompact = true;
13994            } else if ("--oom".equals(opt)) {
13995                oomOnly = true;
13996            } else if ("--local".equals(opt)) {
13997                localOnly = true;
13998            } else if ("--package".equals(opt)) {
13999                packages = true;
14000            } else if ("-h".equals(opt)) {
14001                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14002                pw.println("  -a: include all available information for each process.");
14003                pw.println("  -d: include dalvik details when dumping process details.");
14004                pw.println("  -c: dump in a compact machine-parseable representation.");
14005                pw.println("  --oom: only show processes organized by oom adj.");
14006                pw.println("  --local: only collect details locally, don't call process.");
14007                pw.println("  --package: interpret process arg as package, dumping all");
14008                pw.println("             processes that have loaded that package.");
14009                pw.println("If [process] is specified it can be the name or ");
14010                pw.println("pid of a specific process to dump.");
14011                return;
14012            } else {
14013                pw.println("Unknown argument: " + opt + "; use -h for help");
14014            }
14015        }
14016
14017        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14018        long uptime = SystemClock.uptimeMillis();
14019        long realtime = SystemClock.elapsedRealtime();
14020        final long[] tmpLong = new long[1];
14021
14022        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14023        if (procs == null) {
14024            // No Java processes.  Maybe they want to print a native process.
14025            if (args != null && args.length > opti
14026                    && args[opti].charAt(0) != '-') {
14027                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14028                        = new ArrayList<ProcessCpuTracker.Stats>();
14029                updateCpuStatsNow();
14030                int findPid = -1;
14031                try {
14032                    findPid = Integer.parseInt(args[opti]);
14033                } catch (NumberFormatException e) {
14034                }
14035                synchronized (mProcessCpuTracker) {
14036                    final int N = mProcessCpuTracker.countStats();
14037                    for (int i=0; i<N; i++) {
14038                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14039                        if (st.pid == findPid || (st.baseName != null
14040                                && st.baseName.equals(args[opti]))) {
14041                            nativeProcs.add(st);
14042                        }
14043                    }
14044                }
14045                if (nativeProcs.size() > 0) {
14046                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14047                            isCompact);
14048                    Debug.MemoryInfo mi = null;
14049                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14050                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14051                        final int pid = r.pid;
14052                        if (!isCheckinRequest && dumpDetails) {
14053                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14054                        }
14055                        if (mi == null) {
14056                            mi = new Debug.MemoryInfo();
14057                        }
14058                        if (dumpDetails || (!brief && !oomOnly)) {
14059                            Debug.getMemoryInfo(pid, mi);
14060                        } else {
14061                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14062                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14063                        }
14064                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14065                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14066                        if (isCheckinRequest) {
14067                            pw.println();
14068                        }
14069                    }
14070                    return;
14071                }
14072            }
14073            pw.println("No process found for: " + args[opti]);
14074            return;
14075        }
14076
14077        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14078            dumpDetails = true;
14079        }
14080
14081        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14082
14083        String[] innerArgs = new String[args.length-opti];
14084        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14085
14086        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14087        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14088        long nativePss=0, dalvikPss=0, otherPss=0;
14089        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14090
14091        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14092        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14093                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14094
14095        long totalPss = 0;
14096        long cachedPss = 0;
14097
14098        Debug.MemoryInfo mi = null;
14099        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14100            final ProcessRecord r = procs.get(i);
14101            final IApplicationThread thread;
14102            final int pid;
14103            final int oomAdj;
14104            final boolean hasActivities;
14105            synchronized (this) {
14106                thread = r.thread;
14107                pid = r.pid;
14108                oomAdj = r.getSetAdjWithServices();
14109                hasActivities = r.activities.size() > 0;
14110            }
14111            if (thread != null) {
14112                if (!isCheckinRequest && dumpDetails) {
14113                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14114                }
14115                if (mi == null) {
14116                    mi = new Debug.MemoryInfo();
14117                }
14118                if (dumpDetails || (!brief && !oomOnly)) {
14119                    Debug.getMemoryInfo(pid, mi);
14120                } else {
14121                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14122                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14123                }
14124                if (dumpDetails) {
14125                    if (localOnly) {
14126                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14127                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14128                        if (isCheckinRequest) {
14129                            pw.println();
14130                        }
14131                    } else {
14132                        try {
14133                            pw.flush();
14134                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14135                                    dumpDalvik, innerArgs);
14136                        } catch (RemoteException e) {
14137                            if (!isCheckinRequest) {
14138                                pw.println("Got RemoteException!");
14139                                pw.flush();
14140                            }
14141                        }
14142                    }
14143                }
14144
14145                final long myTotalPss = mi.getTotalPss();
14146                final long myTotalUss = mi.getTotalUss();
14147
14148                synchronized (this) {
14149                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14150                        // Record this for posterity if the process has been stable.
14151                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14152                    }
14153                }
14154
14155                if (!isCheckinRequest && mi != null) {
14156                    totalPss += myTotalPss;
14157                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14158                            (hasActivities ? " / activities)" : ")"),
14159                            r.processName, myTotalPss, pid, hasActivities);
14160                    procMems.add(pssItem);
14161                    procMemsMap.put(pid, pssItem);
14162
14163                    nativePss += mi.nativePss;
14164                    dalvikPss += mi.dalvikPss;
14165                    otherPss += mi.otherPss;
14166                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14167                        long mem = mi.getOtherPss(j);
14168                        miscPss[j] += mem;
14169                        otherPss -= mem;
14170                    }
14171
14172                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14173                        cachedPss += myTotalPss;
14174                    }
14175
14176                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14177                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14178                                || oomIndex == (oomPss.length-1)) {
14179                            oomPss[oomIndex] += myTotalPss;
14180                            if (oomProcs[oomIndex] == null) {
14181                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14182                            }
14183                            oomProcs[oomIndex].add(pssItem);
14184                            break;
14185                        }
14186                    }
14187                }
14188            }
14189        }
14190
14191        long nativeProcTotalPss = 0;
14192
14193        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14194            // If we are showing aggregations, also look for native processes to
14195            // include so that our aggregations are more accurate.
14196            updateCpuStatsNow();
14197            synchronized (mProcessCpuTracker) {
14198                final int N = mProcessCpuTracker.countStats();
14199                for (int i=0; i<N; i++) {
14200                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14201                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14202                        if (mi == null) {
14203                            mi = new Debug.MemoryInfo();
14204                        }
14205                        if (!brief && !oomOnly) {
14206                            Debug.getMemoryInfo(st.pid, mi);
14207                        } else {
14208                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14209                            mi.nativePrivateDirty = (int)tmpLong[0];
14210                        }
14211
14212                        final long myTotalPss = mi.getTotalPss();
14213                        totalPss += myTotalPss;
14214                        nativeProcTotalPss += myTotalPss;
14215
14216                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14217                                st.name, myTotalPss, st.pid, false);
14218                        procMems.add(pssItem);
14219
14220                        nativePss += mi.nativePss;
14221                        dalvikPss += mi.dalvikPss;
14222                        otherPss += mi.otherPss;
14223                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14224                            long mem = mi.getOtherPss(j);
14225                            miscPss[j] += mem;
14226                            otherPss -= mem;
14227                        }
14228                        oomPss[0] += myTotalPss;
14229                        if (oomProcs[0] == null) {
14230                            oomProcs[0] = new ArrayList<MemItem>();
14231                        }
14232                        oomProcs[0].add(pssItem);
14233                    }
14234                }
14235            }
14236
14237            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14238
14239            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14240            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14241            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14242            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14243                String label = Debug.MemoryInfo.getOtherLabel(j);
14244                catMems.add(new MemItem(label, label, miscPss[j], j));
14245            }
14246
14247            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14248            for (int j=0; j<oomPss.length; j++) {
14249                if (oomPss[j] != 0) {
14250                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14251                            : DUMP_MEM_OOM_LABEL[j];
14252                    MemItem item = new MemItem(label, label, oomPss[j],
14253                            DUMP_MEM_OOM_ADJ[j]);
14254                    item.subitems = oomProcs[j];
14255                    oomMems.add(item);
14256                }
14257            }
14258
14259            if (!brief && !oomOnly && !isCompact) {
14260                pw.println();
14261                pw.println("Total PSS by process:");
14262                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14263                pw.println();
14264            }
14265            if (!isCompact) {
14266                pw.println("Total PSS by OOM adjustment:");
14267            }
14268            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14269            if (!brief && !oomOnly) {
14270                PrintWriter out = categoryPw != null ? categoryPw : pw;
14271                if (!isCompact) {
14272                    out.println();
14273                    out.println("Total PSS by category:");
14274                }
14275                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14276            }
14277            if (!isCompact) {
14278                pw.println();
14279            }
14280            MemInfoReader memInfo = new MemInfoReader();
14281            memInfo.readMemInfo();
14282            if (nativeProcTotalPss > 0) {
14283                synchronized (this) {
14284                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14285                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14286                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14287                            nativeProcTotalPss);
14288                }
14289            }
14290            if (!brief) {
14291                if (!isCompact) {
14292                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14293                    pw.print(" kB (status ");
14294                    switch (mLastMemoryLevel) {
14295                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14296                            pw.println("normal)");
14297                            break;
14298                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14299                            pw.println("moderate)");
14300                            break;
14301                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14302                            pw.println("low)");
14303                            break;
14304                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14305                            pw.println("critical)");
14306                            break;
14307                        default:
14308                            pw.print(mLastMemoryLevel);
14309                            pw.println(")");
14310                            break;
14311                    }
14312                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14313                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14314                            pw.print(cachedPss); pw.print(" cached pss + ");
14315                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14316                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14317                } else {
14318                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14319                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14320                            + memInfo.getFreeSizeKb()); pw.print(",");
14321                    pw.println(totalPss - cachedPss);
14322                }
14323            }
14324            if (!isCompact) {
14325                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14326                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14327                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14328                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14329                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14330                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14331                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14332                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14333                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14334                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14335                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14336            }
14337            if (!brief) {
14338                if (memInfo.getZramTotalSizeKb() != 0) {
14339                    if (!isCompact) {
14340                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14341                                pw.print(" kB physical used for ");
14342                                pw.print(memInfo.getSwapTotalSizeKb()
14343                                        - memInfo.getSwapFreeSizeKb());
14344                                pw.print(" kB in swap (");
14345                                pw.print(memInfo.getSwapTotalSizeKb());
14346                                pw.println(" kB total swap)");
14347                    } else {
14348                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14349                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14350                                pw.println(memInfo.getSwapFreeSizeKb());
14351                    }
14352                }
14353                final int[] SINGLE_LONG_FORMAT = new int[] {
14354                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14355                };
14356                long[] longOut = new long[1];
14357                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14358                        SINGLE_LONG_FORMAT, null, longOut, null);
14359                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14360                longOut[0] = 0;
14361                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14362                        SINGLE_LONG_FORMAT, null, longOut, null);
14363                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14364                longOut[0] = 0;
14365                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14366                        SINGLE_LONG_FORMAT, null, longOut, null);
14367                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14368                longOut[0] = 0;
14369                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14370                        SINGLE_LONG_FORMAT, null, longOut, null);
14371                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14372                if (!isCompact) {
14373                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14374                        pw.print("      KSM: "); pw.print(sharing);
14375                                pw.print(" kB saved from shared ");
14376                                pw.print(shared); pw.println(" kB");
14377                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14378                                pw.print(voltile); pw.println(" kB volatile");
14379                    }
14380                    pw.print("   Tuning: ");
14381                    pw.print(ActivityManager.staticGetMemoryClass());
14382                    pw.print(" (large ");
14383                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14384                    pw.print("), oom ");
14385                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14386                    pw.print(" kB");
14387                    pw.print(", restore limit ");
14388                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14389                    pw.print(" kB");
14390                    if (ActivityManager.isLowRamDeviceStatic()) {
14391                        pw.print(" (low-ram)");
14392                    }
14393                    if (ActivityManager.isHighEndGfx()) {
14394                        pw.print(" (high-end-gfx)");
14395                    }
14396                    pw.println();
14397                } else {
14398                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14399                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14400                    pw.println(voltile);
14401                    pw.print("tuning,");
14402                    pw.print(ActivityManager.staticGetMemoryClass());
14403                    pw.print(',');
14404                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14405                    pw.print(',');
14406                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14407                    if (ActivityManager.isLowRamDeviceStatic()) {
14408                        pw.print(",low-ram");
14409                    }
14410                    if (ActivityManager.isHighEndGfx()) {
14411                        pw.print(",high-end-gfx");
14412                    }
14413                    pw.println();
14414                }
14415            }
14416        }
14417    }
14418
14419    /**
14420     * Searches array of arguments for the specified string
14421     * @param args array of argument strings
14422     * @param value value to search for
14423     * @return true if the value is contained in the array
14424     */
14425    private static boolean scanArgs(String[] args, String value) {
14426        if (args != null) {
14427            for (String arg : args) {
14428                if (value.equals(arg)) {
14429                    return true;
14430                }
14431            }
14432        }
14433        return false;
14434    }
14435
14436    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14437            ContentProviderRecord cpr, boolean always) {
14438        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14439
14440        if (!inLaunching || always) {
14441            synchronized (cpr) {
14442                cpr.launchingApp = null;
14443                cpr.notifyAll();
14444            }
14445            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14446            String names[] = cpr.info.authority.split(";");
14447            for (int j = 0; j < names.length; j++) {
14448                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14449            }
14450        }
14451
14452        for (int i=0; i<cpr.connections.size(); i++) {
14453            ContentProviderConnection conn = cpr.connections.get(i);
14454            if (conn.waiting) {
14455                // If this connection is waiting for the provider, then we don't
14456                // need to mess with its process unless we are always removing
14457                // or for some reason the provider is not currently launching.
14458                if (inLaunching && !always) {
14459                    continue;
14460                }
14461            }
14462            ProcessRecord capp = conn.client;
14463            conn.dead = true;
14464            if (conn.stableCount > 0) {
14465                if (!capp.persistent && capp.thread != null
14466                        && capp.pid != 0
14467                        && capp.pid != MY_PID) {
14468                    capp.kill("depends on provider "
14469                            + cpr.name.flattenToShortString()
14470                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14471                }
14472            } else if (capp.thread != null && conn.provider.provider != null) {
14473                try {
14474                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14475                } catch (RemoteException e) {
14476                }
14477                // In the protocol here, we don't expect the client to correctly
14478                // clean up this connection, we'll just remove it.
14479                cpr.connections.remove(i);
14480                conn.client.conProviders.remove(conn);
14481            }
14482        }
14483
14484        if (inLaunching && always) {
14485            mLaunchingProviders.remove(cpr);
14486        }
14487        return inLaunching;
14488    }
14489
14490    /**
14491     * Main code for cleaning up a process when it has gone away.  This is
14492     * called both as a result of the process dying, or directly when stopping
14493     * a process when running in single process mode.
14494     *
14495     * @return Returns true if the given process has been restarted, so the
14496     * app that was passed in must remain on the process lists.
14497     */
14498    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14499            boolean restarting, boolean allowRestart, int index) {
14500        if (index >= 0) {
14501            removeLruProcessLocked(app);
14502            ProcessList.remove(app.pid);
14503        }
14504
14505        mProcessesToGc.remove(app);
14506        mPendingPssProcesses.remove(app);
14507
14508        // Dismiss any open dialogs.
14509        if (app.crashDialog != null && !app.forceCrashReport) {
14510            app.crashDialog.dismiss();
14511            app.crashDialog = null;
14512        }
14513        if (app.anrDialog != null) {
14514            app.anrDialog.dismiss();
14515            app.anrDialog = null;
14516        }
14517        if (app.waitDialog != null) {
14518            app.waitDialog.dismiss();
14519            app.waitDialog = null;
14520        }
14521
14522        app.crashing = false;
14523        app.notResponding = false;
14524
14525        app.resetPackageList(mProcessStats);
14526        app.unlinkDeathRecipient();
14527        app.makeInactive(mProcessStats);
14528        app.waitingToKill = null;
14529        app.forcingToForeground = null;
14530        updateProcessForegroundLocked(app, false, false);
14531        app.foregroundActivities = false;
14532        app.hasShownUi = false;
14533        app.treatLikeActivity = false;
14534        app.hasAboveClient = false;
14535        app.hasClientActivities = false;
14536
14537        mServices.killServicesLocked(app, allowRestart);
14538
14539        boolean restart = false;
14540
14541        // Remove published content providers.
14542        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14543            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14544            final boolean always = app.bad || !allowRestart;
14545            if (removeDyingProviderLocked(app, cpr, always) || always) {
14546                // We left the provider in the launching list, need to
14547                // restart it.
14548                restart = true;
14549            }
14550
14551            cpr.provider = null;
14552            cpr.proc = null;
14553        }
14554        app.pubProviders.clear();
14555
14556        // Take care of any launching providers waiting for this process.
14557        if (checkAppInLaunchingProvidersLocked(app, false)) {
14558            restart = true;
14559        }
14560
14561        // Unregister from connected content providers.
14562        if (!app.conProviders.isEmpty()) {
14563            for (int i=0; i<app.conProviders.size(); i++) {
14564                ContentProviderConnection conn = app.conProviders.get(i);
14565                conn.provider.connections.remove(conn);
14566            }
14567            app.conProviders.clear();
14568        }
14569
14570        // At this point there may be remaining entries in mLaunchingProviders
14571        // where we were the only one waiting, so they are no longer of use.
14572        // Look for these and clean up if found.
14573        // XXX Commented out for now.  Trying to figure out a way to reproduce
14574        // the actual situation to identify what is actually going on.
14575        if (false) {
14576            for (int i=0; i<mLaunchingProviders.size(); i++) {
14577                ContentProviderRecord cpr = (ContentProviderRecord)
14578                        mLaunchingProviders.get(i);
14579                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14580                    synchronized (cpr) {
14581                        cpr.launchingApp = null;
14582                        cpr.notifyAll();
14583                    }
14584                }
14585            }
14586        }
14587
14588        skipCurrentReceiverLocked(app);
14589
14590        // Unregister any receivers.
14591        for (int i=app.receivers.size()-1; i>=0; i--) {
14592            removeReceiverLocked(app.receivers.valueAt(i));
14593        }
14594        app.receivers.clear();
14595
14596        // If the app is undergoing backup, tell the backup manager about it
14597        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14598            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14599                    + mBackupTarget.appInfo + " died during backup");
14600            try {
14601                IBackupManager bm = IBackupManager.Stub.asInterface(
14602                        ServiceManager.getService(Context.BACKUP_SERVICE));
14603                bm.agentDisconnected(app.info.packageName);
14604            } catch (RemoteException e) {
14605                // can't happen; backup manager is local
14606            }
14607        }
14608
14609        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14610            ProcessChangeItem item = mPendingProcessChanges.get(i);
14611            if (item.pid == app.pid) {
14612                mPendingProcessChanges.remove(i);
14613                mAvailProcessChanges.add(item);
14614            }
14615        }
14616        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14617
14618        // If the caller is restarting this app, then leave it in its
14619        // current lists and let the caller take care of it.
14620        if (restarting) {
14621            return false;
14622        }
14623
14624        if (!app.persistent || app.isolated) {
14625            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14626                    "Removing non-persistent process during cleanup: " + app);
14627            mProcessNames.remove(app.processName, app.uid);
14628            mIsolatedProcesses.remove(app.uid);
14629            if (mHeavyWeightProcess == app) {
14630                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14631                        mHeavyWeightProcess.userId, 0));
14632                mHeavyWeightProcess = null;
14633            }
14634        } else if (!app.removed) {
14635            // This app is persistent, so we need to keep its record around.
14636            // If it is not already on the pending app list, add it there
14637            // and start a new process for it.
14638            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14639                mPersistentStartingProcesses.add(app);
14640                restart = true;
14641            }
14642        }
14643        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14644                "Clean-up removing on hold: " + app);
14645        mProcessesOnHold.remove(app);
14646
14647        if (app == mHomeProcess) {
14648            mHomeProcess = null;
14649        }
14650        if (app == mPreviousProcess) {
14651            mPreviousProcess = null;
14652        }
14653
14654        if (restart && !app.isolated) {
14655            // We have components that still need to be running in the
14656            // process, so re-launch it.
14657            if (index < 0) {
14658                ProcessList.remove(app.pid);
14659            }
14660            mProcessNames.put(app.processName, app.uid, app);
14661            startProcessLocked(app, "restart", app.processName);
14662            return true;
14663        } else if (app.pid > 0 && app.pid != MY_PID) {
14664            // Goodbye!
14665            boolean removed;
14666            synchronized (mPidsSelfLocked) {
14667                mPidsSelfLocked.remove(app.pid);
14668                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14669            }
14670            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14671            if (app.isolated) {
14672                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14673            }
14674            app.setPid(0);
14675        }
14676        return false;
14677    }
14678
14679    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14680        // Look through the content providers we are waiting to have launched,
14681        // and if any run in this process then either schedule a restart of
14682        // the process or kill the client waiting for it if this process has
14683        // gone bad.
14684        int NL = mLaunchingProviders.size();
14685        boolean restart = false;
14686        for (int i=0; i<NL; i++) {
14687            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14688            if (cpr.launchingApp == app) {
14689                if (!alwaysBad && !app.bad) {
14690                    restart = true;
14691                } else {
14692                    removeDyingProviderLocked(app, cpr, true);
14693                    // cpr should have been removed from mLaunchingProviders
14694                    NL = mLaunchingProviders.size();
14695                    i--;
14696                }
14697            }
14698        }
14699        return restart;
14700    }
14701
14702    // =========================================================
14703    // SERVICES
14704    // =========================================================
14705
14706    @Override
14707    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14708            int flags) {
14709        enforceNotIsolatedCaller("getServices");
14710        synchronized (this) {
14711            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14712        }
14713    }
14714
14715    @Override
14716    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14717        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14718        synchronized (this) {
14719            return mServices.getRunningServiceControlPanelLocked(name);
14720        }
14721    }
14722
14723    @Override
14724    public ComponentName startService(IApplicationThread caller, Intent service,
14725            String resolvedType, int userId) {
14726        enforceNotIsolatedCaller("startService");
14727        // Refuse possible leaked file descriptors
14728        if (service != null && service.hasFileDescriptors() == true) {
14729            throw new IllegalArgumentException("File descriptors passed in Intent");
14730        }
14731
14732        if (DEBUG_SERVICE)
14733            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14734        synchronized(this) {
14735            final int callingPid = Binder.getCallingPid();
14736            final int callingUid = Binder.getCallingUid();
14737            final long origId = Binder.clearCallingIdentity();
14738            ComponentName res = mServices.startServiceLocked(caller, service,
14739                    resolvedType, callingPid, callingUid, userId);
14740            Binder.restoreCallingIdentity(origId);
14741            return res;
14742        }
14743    }
14744
14745    ComponentName startServiceInPackage(int uid,
14746            Intent service, String resolvedType, int userId) {
14747        synchronized(this) {
14748            if (DEBUG_SERVICE)
14749                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14750            final long origId = Binder.clearCallingIdentity();
14751            ComponentName res = mServices.startServiceLocked(null, service,
14752                    resolvedType, -1, uid, userId);
14753            Binder.restoreCallingIdentity(origId);
14754            return res;
14755        }
14756    }
14757
14758    @Override
14759    public int stopService(IApplicationThread caller, Intent service,
14760            String resolvedType, int userId) {
14761        enforceNotIsolatedCaller("stopService");
14762        // Refuse possible leaked file descriptors
14763        if (service != null && service.hasFileDescriptors() == true) {
14764            throw new IllegalArgumentException("File descriptors passed in Intent");
14765        }
14766
14767        synchronized(this) {
14768            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14769        }
14770    }
14771
14772    @Override
14773    public IBinder peekService(Intent service, String resolvedType) {
14774        enforceNotIsolatedCaller("peekService");
14775        // Refuse possible leaked file descriptors
14776        if (service != null && service.hasFileDescriptors() == true) {
14777            throw new IllegalArgumentException("File descriptors passed in Intent");
14778        }
14779        synchronized(this) {
14780            return mServices.peekServiceLocked(service, resolvedType);
14781        }
14782    }
14783
14784    @Override
14785    public boolean stopServiceToken(ComponentName className, IBinder token,
14786            int startId) {
14787        synchronized(this) {
14788            return mServices.stopServiceTokenLocked(className, token, startId);
14789        }
14790    }
14791
14792    @Override
14793    public void setServiceForeground(ComponentName className, IBinder token,
14794            int id, Notification notification, boolean removeNotification) {
14795        synchronized(this) {
14796            mServices.setServiceForegroundLocked(className, token, id, notification,
14797                    removeNotification);
14798        }
14799    }
14800
14801    @Override
14802    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14803            boolean requireFull, String name, String callerPackage) {
14804        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14805                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14806    }
14807
14808    int unsafeConvertIncomingUser(int userId) {
14809        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14810                ? mCurrentUserId : userId;
14811    }
14812
14813    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14814            int allowMode, String name, String callerPackage) {
14815        final int callingUserId = UserHandle.getUserId(callingUid);
14816        if (callingUserId == userId) {
14817            return userId;
14818        }
14819
14820        // Note that we may be accessing mCurrentUserId outside of a lock...
14821        // shouldn't be a big deal, if this is being called outside
14822        // of a locked context there is intrinsically a race with
14823        // the value the caller will receive and someone else changing it.
14824        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14825        // we will switch to the calling user if access to the current user fails.
14826        int targetUserId = unsafeConvertIncomingUser(userId);
14827
14828        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14829            final boolean allow;
14830            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14831                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14832                // If the caller has this permission, they always pass go.  And collect $200.
14833                allow = true;
14834            } else if (allowMode == ALLOW_FULL_ONLY) {
14835                // We require full access, sucks to be you.
14836                allow = false;
14837            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14838                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14839                // If the caller does not have either permission, they are always doomed.
14840                allow = false;
14841            } else if (allowMode == ALLOW_NON_FULL) {
14842                // We are blanket allowing non-full access, you lucky caller!
14843                allow = true;
14844            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14845                // We may or may not allow this depending on whether the two users are
14846                // in the same profile.
14847                synchronized (mUserProfileGroupIdsSelfLocked) {
14848                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14849                            UserInfo.NO_PROFILE_GROUP_ID);
14850                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14851                            UserInfo.NO_PROFILE_GROUP_ID);
14852                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14853                            && callingProfile == targetProfile;
14854                }
14855            } else {
14856                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14857            }
14858            if (!allow) {
14859                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14860                    // In this case, they would like to just execute as their
14861                    // owner user instead of failing.
14862                    targetUserId = callingUserId;
14863                } else {
14864                    StringBuilder builder = new StringBuilder(128);
14865                    builder.append("Permission Denial: ");
14866                    builder.append(name);
14867                    if (callerPackage != null) {
14868                        builder.append(" from ");
14869                        builder.append(callerPackage);
14870                    }
14871                    builder.append(" asks to run as user ");
14872                    builder.append(userId);
14873                    builder.append(" but is calling from user ");
14874                    builder.append(UserHandle.getUserId(callingUid));
14875                    builder.append("; this requires ");
14876                    builder.append(INTERACT_ACROSS_USERS_FULL);
14877                    if (allowMode != ALLOW_FULL_ONLY) {
14878                        builder.append(" or ");
14879                        builder.append(INTERACT_ACROSS_USERS);
14880                    }
14881                    String msg = builder.toString();
14882                    Slog.w(TAG, msg);
14883                    throw new SecurityException(msg);
14884                }
14885            }
14886        }
14887        if (!allowAll && targetUserId < 0) {
14888            throw new IllegalArgumentException(
14889                    "Call does not support special user #" + targetUserId);
14890        }
14891        // Check shell permission
14892        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14893            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14894                    targetUserId)) {
14895                throw new SecurityException("Shell does not have permission to access user "
14896                        + targetUserId + "\n " + Debug.getCallers(3));
14897            }
14898        }
14899        return targetUserId;
14900    }
14901
14902    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14903            String className, int flags) {
14904        boolean result = false;
14905        // For apps that don't have pre-defined UIDs, check for permission
14906        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14907            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14908                if (ActivityManager.checkUidPermission(
14909                        INTERACT_ACROSS_USERS,
14910                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14911                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14912                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14913                            + " requests FLAG_SINGLE_USER, but app does not hold "
14914                            + INTERACT_ACROSS_USERS;
14915                    Slog.w(TAG, msg);
14916                    throw new SecurityException(msg);
14917                }
14918                // Permission passed
14919                result = true;
14920            }
14921        } else if ("system".equals(componentProcessName)) {
14922            result = true;
14923        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14924            // Phone app and persistent apps are allowed to export singleuser providers.
14925            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14926                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14927        }
14928        if (DEBUG_MU) {
14929            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14930                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14931        }
14932        return result;
14933    }
14934
14935    /**
14936     * Checks to see if the caller is in the same app as the singleton
14937     * component, or the component is in a special app. It allows special apps
14938     * to export singleton components but prevents exporting singleton
14939     * components for regular apps.
14940     */
14941    boolean isValidSingletonCall(int callingUid, int componentUid) {
14942        int componentAppId = UserHandle.getAppId(componentUid);
14943        return UserHandle.isSameApp(callingUid, componentUid)
14944                || componentAppId == Process.SYSTEM_UID
14945                || componentAppId == Process.PHONE_UID
14946                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14947                        == PackageManager.PERMISSION_GRANTED;
14948    }
14949
14950    public int bindService(IApplicationThread caller, IBinder token,
14951            Intent service, String resolvedType,
14952            IServiceConnection connection, int flags, int userId) {
14953        enforceNotIsolatedCaller("bindService");
14954
14955        // Refuse possible leaked file descriptors
14956        if (service != null && service.hasFileDescriptors() == true) {
14957            throw new IllegalArgumentException("File descriptors passed in Intent");
14958        }
14959
14960        synchronized(this) {
14961            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14962                    connection, flags, userId);
14963        }
14964    }
14965
14966    public boolean unbindService(IServiceConnection connection) {
14967        synchronized (this) {
14968            return mServices.unbindServiceLocked(connection);
14969        }
14970    }
14971
14972    public void publishService(IBinder token, Intent intent, IBinder service) {
14973        // Refuse possible leaked file descriptors
14974        if (intent != null && intent.hasFileDescriptors() == true) {
14975            throw new IllegalArgumentException("File descriptors passed in Intent");
14976        }
14977
14978        synchronized(this) {
14979            if (!(token instanceof ServiceRecord)) {
14980                throw new IllegalArgumentException("Invalid service token");
14981            }
14982            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14983        }
14984    }
14985
14986    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14987        // Refuse possible leaked file descriptors
14988        if (intent != null && intent.hasFileDescriptors() == true) {
14989            throw new IllegalArgumentException("File descriptors passed in Intent");
14990        }
14991
14992        synchronized(this) {
14993            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14994        }
14995    }
14996
14997    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14998        synchronized(this) {
14999            if (!(token instanceof ServiceRecord)) {
15000                throw new IllegalArgumentException("Invalid service token");
15001            }
15002            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15003        }
15004    }
15005
15006    // =========================================================
15007    // BACKUP AND RESTORE
15008    // =========================================================
15009
15010    // Cause the target app to be launched if necessary and its backup agent
15011    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15012    // activity manager to announce its creation.
15013    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15014        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15015        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15016
15017        synchronized(this) {
15018            // !!! TODO: currently no check here that we're already bound
15019            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15020            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15021            synchronized (stats) {
15022                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15023            }
15024
15025            // Backup agent is now in use, its package can't be stopped.
15026            try {
15027                AppGlobals.getPackageManager().setPackageStoppedState(
15028                        app.packageName, false, UserHandle.getUserId(app.uid));
15029            } catch (RemoteException e) {
15030            } catch (IllegalArgumentException e) {
15031                Slog.w(TAG, "Failed trying to unstop package "
15032                        + app.packageName + ": " + e);
15033            }
15034
15035            BackupRecord r = new BackupRecord(ss, app, backupMode);
15036            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15037                    ? new ComponentName(app.packageName, app.backupAgentName)
15038                    : new ComponentName("android", "FullBackupAgent");
15039            // startProcessLocked() returns existing proc's record if it's already running
15040            ProcessRecord proc = startProcessLocked(app.processName, app,
15041                    false, 0, "backup", hostingName, false, false, false);
15042            if (proc == null) {
15043                Slog.e(TAG, "Unable to start backup agent process " + r);
15044                return false;
15045            }
15046
15047            r.app = proc;
15048            mBackupTarget = r;
15049            mBackupAppName = app.packageName;
15050
15051            // Try not to kill the process during backup
15052            updateOomAdjLocked(proc);
15053
15054            // If the process is already attached, schedule the creation of the backup agent now.
15055            // If it is not yet live, this will be done when it attaches to the framework.
15056            if (proc.thread != null) {
15057                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15058                try {
15059                    proc.thread.scheduleCreateBackupAgent(app,
15060                            compatibilityInfoForPackageLocked(app), backupMode);
15061                } catch (RemoteException e) {
15062                    // Will time out on the backup manager side
15063                }
15064            } else {
15065                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15066            }
15067            // Invariants: at this point, the target app process exists and the application
15068            // is either already running or in the process of coming up.  mBackupTarget and
15069            // mBackupAppName describe the app, so that when it binds back to the AM we
15070            // know that it's scheduled for a backup-agent operation.
15071        }
15072
15073        return true;
15074    }
15075
15076    @Override
15077    public void clearPendingBackup() {
15078        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15079        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15080
15081        synchronized (this) {
15082            mBackupTarget = null;
15083            mBackupAppName = null;
15084        }
15085    }
15086
15087    // A backup agent has just come up
15088    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15089        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15090                + " = " + agent);
15091
15092        synchronized(this) {
15093            if (!agentPackageName.equals(mBackupAppName)) {
15094                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15095                return;
15096            }
15097        }
15098
15099        long oldIdent = Binder.clearCallingIdentity();
15100        try {
15101            IBackupManager bm = IBackupManager.Stub.asInterface(
15102                    ServiceManager.getService(Context.BACKUP_SERVICE));
15103            bm.agentConnected(agentPackageName, agent);
15104        } catch (RemoteException e) {
15105            // can't happen; the backup manager service is local
15106        } catch (Exception e) {
15107            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15108            e.printStackTrace();
15109        } finally {
15110            Binder.restoreCallingIdentity(oldIdent);
15111        }
15112    }
15113
15114    // done with this agent
15115    public void unbindBackupAgent(ApplicationInfo appInfo) {
15116        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15117        if (appInfo == null) {
15118            Slog.w(TAG, "unbind backup agent for null app");
15119            return;
15120        }
15121
15122        synchronized(this) {
15123            try {
15124                if (mBackupAppName == null) {
15125                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15126                    return;
15127                }
15128
15129                if (!mBackupAppName.equals(appInfo.packageName)) {
15130                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15131                    return;
15132                }
15133
15134                // Not backing this app up any more; reset its OOM adjustment
15135                final ProcessRecord proc = mBackupTarget.app;
15136                updateOomAdjLocked(proc);
15137
15138                // If the app crashed during backup, 'thread' will be null here
15139                if (proc.thread != null) {
15140                    try {
15141                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15142                                compatibilityInfoForPackageLocked(appInfo));
15143                    } catch (Exception e) {
15144                        Slog.e(TAG, "Exception when unbinding backup agent:");
15145                        e.printStackTrace();
15146                    }
15147                }
15148            } finally {
15149                mBackupTarget = null;
15150                mBackupAppName = null;
15151            }
15152        }
15153    }
15154    // =========================================================
15155    // BROADCASTS
15156    // =========================================================
15157
15158    private final List getStickiesLocked(String action, IntentFilter filter,
15159            List cur, int userId) {
15160        final ContentResolver resolver = mContext.getContentResolver();
15161        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15162        if (stickies == null) {
15163            return cur;
15164        }
15165        final ArrayList<Intent> list = stickies.get(action);
15166        if (list == null) {
15167            return cur;
15168        }
15169        int N = list.size();
15170        for (int i=0; i<N; i++) {
15171            Intent intent = list.get(i);
15172            if (filter.match(resolver, intent, true, TAG) >= 0) {
15173                if (cur == null) {
15174                    cur = new ArrayList<Intent>();
15175                }
15176                cur.add(intent);
15177            }
15178        }
15179        return cur;
15180    }
15181
15182    boolean isPendingBroadcastProcessLocked(int pid) {
15183        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15184                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15185    }
15186
15187    void skipPendingBroadcastLocked(int pid) {
15188            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15189            for (BroadcastQueue queue : mBroadcastQueues) {
15190                queue.skipPendingBroadcastLocked(pid);
15191            }
15192    }
15193
15194    // The app just attached; send any pending broadcasts that it should receive
15195    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15196        boolean didSomething = false;
15197        for (BroadcastQueue queue : mBroadcastQueues) {
15198            didSomething |= queue.sendPendingBroadcastsLocked(app);
15199        }
15200        return didSomething;
15201    }
15202
15203    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15204            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15205        enforceNotIsolatedCaller("registerReceiver");
15206        int callingUid;
15207        int callingPid;
15208        synchronized(this) {
15209            ProcessRecord callerApp = null;
15210            if (caller != null) {
15211                callerApp = getRecordForAppLocked(caller);
15212                if (callerApp == null) {
15213                    throw new SecurityException(
15214                            "Unable to find app for caller " + caller
15215                            + " (pid=" + Binder.getCallingPid()
15216                            + ") when registering receiver " + receiver);
15217                }
15218                if (callerApp.info.uid != Process.SYSTEM_UID &&
15219                        !callerApp.pkgList.containsKey(callerPackage) &&
15220                        !"android".equals(callerPackage)) {
15221                    throw new SecurityException("Given caller package " + callerPackage
15222                            + " is not running in process " + callerApp);
15223                }
15224                callingUid = callerApp.info.uid;
15225                callingPid = callerApp.pid;
15226            } else {
15227                callerPackage = null;
15228                callingUid = Binder.getCallingUid();
15229                callingPid = Binder.getCallingPid();
15230            }
15231
15232            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15233                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15234
15235            List allSticky = null;
15236
15237            // Look for any matching sticky broadcasts...
15238            Iterator actions = filter.actionsIterator();
15239            if (actions != null) {
15240                while (actions.hasNext()) {
15241                    String action = (String)actions.next();
15242                    allSticky = getStickiesLocked(action, filter, allSticky,
15243                            UserHandle.USER_ALL);
15244                    allSticky = getStickiesLocked(action, filter, allSticky,
15245                            UserHandle.getUserId(callingUid));
15246                }
15247            } else {
15248                allSticky = getStickiesLocked(null, filter, allSticky,
15249                        UserHandle.USER_ALL);
15250                allSticky = getStickiesLocked(null, filter, allSticky,
15251                        UserHandle.getUserId(callingUid));
15252            }
15253
15254            // The first sticky in the list is returned directly back to
15255            // the client.
15256            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15257
15258            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15259                    + ": " + sticky);
15260
15261            if (receiver == null) {
15262                return sticky;
15263            }
15264
15265            ReceiverList rl
15266                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15267            if (rl == null) {
15268                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15269                        userId, receiver);
15270                if (rl.app != null) {
15271                    rl.app.receivers.add(rl);
15272                } else {
15273                    try {
15274                        receiver.asBinder().linkToDeath(rl, 0);
15275                    } catch (RemoteException e) {
15276                        return sticky;
15277                    }
15278                    rl.linkedToDeath = true;
15279                }
15280                mRegisteredReceivers.put(receiver.asBinder(), rl);
15281            } else if (rl.uid != callingUid) {
15282                throw new IllegalArgumentException(
15283                        "Receiver requested to register for uid " + callingUid
15284                        + " was previously registered for uid " + rl.uid);
15285            } else if (rl.pid != callingPid) {
15286                throw new IllegalArgumentException(
15287                        "Receiver requested to register for pid " + callingPid
15288                        + " was previously registered for pid " + rl.pid);
15289            } else if (rl.userId != userId) {
15290                throw new IllegalArgumentException(
15291                        "Receiver requested to register for user " + userId
15292                        + " was previously registered for user " + rl.userId);
15293            }
15294            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15295                    permission, callingUid, userId);
15296            rl.add(bf);
15297            if (!bf.debugCheck()) {
15298                Slog.w(TAG, "==> For Dynamic broadast");
15299            }
15300            mReceiverResolver.addFilter(bf);
15301
15302            // Enqueue broadcasts for all existing stickies that match
15303            // this filter.
15304            if (allSticky != null) {
15305                ArrayList receivers = new ArrayList();
15306                receivers.add(bf);
15307
15308                int N = allSticky.size();
15309                for (int i=0; i<N; i++) {
15310                    Intent intent = (Intent)allSticky.get(i);
15311                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15312                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15313                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15314                            null, null, false, true, true, -1);
15315                    queue.enqueueParallelBroadcastLocked(r);
15316                    queue.scheduleBroadcastsLocked();
15317                }
15318            }
15319
15320            return sticky;
15321        }
15322    }
15323
15324    public void unregisterReceiver(IIntentReceiver receiver) {
15325        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15326
15327        final long origId = Binder.clearCallingIdentity();
15328        try {
15329            boolean doTrim = false;
15330
15331            synchronized(this) {
15332                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15333                if (rl != null) {
15334                    final BroadcastRecord r = rl.curBroadcast;
15335                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15336                        final boolean doNext = r.queue.finishReceiverLocked(
15337                                r, r.resultCode, r.resultData, r.resultExtras,
15338                                r.resultAbort, false);
15339                        if (doNext) {
15340                            doTrim = true;
15341                            r.queue.processNextBroadcast(false);
15342                        }
15343                    }
15344
15345                    if (rl.app != null) {
15346                        rl.app.receivers.remove(rl);
15347                    }
15348                    removeReceiverLocked(rl);
15349                    if (rl.linkedToDeath) {
15350                        rl.linkedToDeath = false;
15351                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15352                    }
15353                }
15354            }
15355
15356            // If we actually concluded any broadcasts, we might now be able
15357            // to trim the recipients' apps from our working set
15358            if (doTrim) {
15359                trimApplications();
15360                return;
15361            }
15362
15363        } finally {
15364            Binder.restoreCallingIdentity(origId);
15365        }
15366    }
15367
15368    void removeReceiverLocked(ReceiverList rl) {
15369        mRegisteredReceivers.remove(rl.receiver.asBinder());
15370        int N = rl.size();
15371        for (int i=0; i<N; i++) {
15372            mReceiverResolver.removeFilter(rl.get(i));
15373        }
15374    }
15375
15376    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15377        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15378            ProcessRecord r = mLruProcesses.get(i);
15379            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15380                try {
15381                    r.thread.dispatchPackageBroadcast(cmd, packages);
15382                } catch (RemoteException ex) {
15383                }
15384            }
15385        }
15386    }
15387
15388    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15389            int callingUid, int[] users) {
15390        List<ResolveInfo> receivers = null;
15391        try {
15392            HashSet<ComponentName> singleUserReceivers = null;
15393            boolean scannedFirstReceivers = false;
15394            for (int user : users) {
15395                // Skip users that have Shell restrictions
15396                if (callingUid == Process.SHELL_UID
15397                        && getUserManagerLocked().hasUserRestriction(
15398                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15399                    continue;
15400                }
15401                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15402                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15403                if (user != 0 && newReceivers != null) {
15404                    // If this is not the primary user, we need to check for
15405                    // any receivers that should be filtered out.
15406                    for (int i=0; i<newReceivers.size(); i++) {
15407                        ResolveInfo ri = newReceivers.get(i);
15408                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15409                            newReceivers.remove(i);
15410                            i--;
15411                        }
15412                    }
15413                }
15414                if (newReceivers != null && newReceivers.size() == 0) {
15415                    newReceivers = null;
15416                }
15417                if (receivers == null) {
15418                    receivers = newReceivers;
15419                } else if (newReceivers != null) {
15420                    // We need to concatenate the additional receivers
15421                    // found with what we have do far.  This would be easy,
15422                    // but we also need to de-dup any receivers that are
15423                    // singleUser.
15424                    if (!scannedFirstReceivers) {
15425                        // Collect any single user receivers we had already retrieved.
15426                        scannedFirstReceivers = true;
15427                        for (int i=0; i<receivers.size(); i++) {
15428                            ResolveInfo ri = receivers.get(i);
15429                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15430                                ComponentName cn = new ComponentName(
15431                                        ri.activityInfo.packageName, ri.activityInfo.name);
15432                                if (singleUserReceivers == null) {
15433                                    singleUserReceivers = new HashSet<ComponentName>();
15434                                }
15435                                singleUserReceivers.add(cn);
15436                            }
15437                        }
15438                    }
15439                    // Add the new results to the existing results, tracking
15440                    // and de-dupping single user receivers.
15441                    for (int i=0; i<newReceivers.size(); i++) {
15442                        ResolveInfo ri = newReceivers.get(i);
15443                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15444                            ComponentName cn = new ComponentName(
15445                                    ri.activityInfo.packageName, ri.activityInfo.name);
15446                            if (singleUserReceivers == null) {
15447                                singleUserReceivers = new HashSet<ComponentName>();
15448                            }
15449                            if (!singleUserReceivers.contains(cn)) {
15450                                singleUserReceivers.add(cn);
15451                                receivers.add(ri);
15452                            }
15453                        } else {
15454                            receivers.add(ri);
15455                        }
15456                    }
15457                }
15458            }
15459        } catch (RemoteException ex) {
15460            // pm is in same process, this will never happen.
15461        }
15462        return receivers;
15463    }
15464
15465    private final int broadcastIntentLocked(ProcessRecord callerApp,
15466            String callerPackage, Intent intent, String resolvedType,
15467            IIntentReceiver resultTo, int resultCode, String resultData,
15468            Bundle map, String requiredPermission, int appOp,
15469            boolean ordered, boolean sticky, int callingPid, int callingUid,
15470            int userId) {
15471        intent = new Intent(intent);
15472
15473        // By default broadcasts do not go to stopped apps.
15474        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15475
15476        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15477            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15478            + " ordered=" + ordered + " userid=" + userId);
15479        if ((resultTo != null) && !ordered) {
15480            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15481        }
15482
15483        userId = handleIncomingUser(callingPid, callingUid, userId,
15484                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15485
15486        // Make sure that the user who is receiving this broadcast is running.
15487        // If not, we will just skip it.
15488
15489        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15490            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15491                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15492                Slog.w(TAG, "Skipping broadcast of " + intent
15493                        + ": user " + userId + " is stopped");
15494                return ActivityManager.BROADCAST_SUCCESS;
15495            }
15496        }
15497
15498        /*
15499         * Prevent non-system code (defined here to be non-persistent
15500         * processes) from sending protected broadcasts.
15501         */
15502        int callingAppId = UserHandle.getAppId(callingUid);
15503        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15504            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15505            || callingAppId == Process.NFC_UID || callingUid == 0) {
15506            // Always okay.
15507        } else if (callerApp == null || !callerApp.persistent) {
15508            try {
15509                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15510                        intent.getAction())) {
15511                    String msg = "Permission Denial: not allowed to send broadcast "
15512                            + intent.getAction() + " from pid="
15513                            + callingPid + ", uid=" + callingUid;
15514                    Slog.w(TAG, msg);
15515                    throw new SecurityException(msg);
15516                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15517                    // Special case for compatibility: we don't want apps to send this,
15518                    // but historically it has not been protected and apps may be using it
15519                    // to poke their own app widget.  So, instead of making it protected,
15520                    // just limit it to the caller.
15521                    if (callerApp == null) {
15522                        String msg = "Permission Denial: not allowed to send broadcast "
15523                                + intent.getAction() + " from unknown caller.";
15524                        Slog.w(TAG, msg);
15525                        throw new SecurityException(msg);
15526                    } else if (intent.getComponent() != null) {
15527                        // They are good enough to send to an explicit component...  verify
15528                        // it is being sent to the calling app.
15529                        if (!intent.getComponent().getPackageName().equals(
15530                                callerApp.info.packageName)) {
15531                            String msg = "Permission Denial: not allowed to send broadcast "
15532                                    + intent.getAction() + " to "
15533                                    + intent.getComponent().getPackageName() + " from "
15534                                    + callerApp.info.packageName;
15535                            Slog.w(TAG, msg);
15536                            throw new SecurityException(msg);
15537                        }
15538                    } else {
15539                        // Limit broadcast to their own package.
15540                        intent.setPackage(callerApp.info.packageName);
15541                    }
15542                }
15543            } catch (RemoteException e) {
15544                Slog.w(TAG, "Remote exception", e);
15545                return ActivityManager.BROADCAST_SUCCESS;
15546            }
15547        }
15548
15549        // Handle special intents: if this broadcast is from the package
15550        // manager about a package being removed, we need to remove all of
15551        // its activities from the history stack.
15552        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15553                intent.getAction());
15554        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15555                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15556                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15557                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15558                || uidRemoved) {
15559            if (checkComponentPermission(
15560                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15561                    callingPid, callingUid, -1, true)
15562                    == PackageManager.PERMISSION_GRANTED) {
15563                if (uidRemoved) {
15564                    final Bundle intentExtras = intent.getExtras();
15565                    final int uid = intentExtras != null
15566                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15567                    if (uid >= 0) {
15568                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15569                        synchronized (bs) {
15570                            bs.removeUidStatsLocked(uid);
15571                        }
15572                        mAppOpsService.uidRemoved(uid);
15573                    }
15574                } else {
15575                    // If resources are unavailable just force stop all
15576                    // those packages and flush the attribute cache as well.
15577                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15578                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15579                        if (list != null && (list.length > 0)) {
15580                            for (String pkg : list) {
15581                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15582                                        "storage unmount");
15583                            }
15584                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15585                            sendPackageBroadcastLocked(
15586                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15587                        }
15588                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15589                            intent.getAction())) {
15590                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15591                    } else {
15592                        Uri data = intent.getData();
15593                        String ssp;
15594                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15595                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15596                                    intent.getAction());
15597                            boolean fullUninstall = removed &&
15598                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15599                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15600                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15601                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15602                                        false, fullUninstall, userId,
15603                                        removed ? "pkg removed" : "pkg changed");
15604                            }
15605                            if (removed) {
15606                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15607                                        new String[] {ssp}, userId);
15608                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15609                                    mAppOpsService.packageRemoved(
15610                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15611
15612                                    // Remove all permissions granted from/to this package
15613                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15614                                }
15615                            }
15616                        }
15617                    }
15618                }
15619            } else {
15620                String msg = "Permission Denial: " + intent.getAction()
15621                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15622                        + ", uid=" + callingUid + ")"
15623                        + " requires "
15624                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15625                Slog.w(TAG, msg);
15626                throw new SecurityException(msg);
15627            }
15628
15629        // Special case for adding a package: by default turn on compatibility
15630        // mode.
15631        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15632            Uri data = intent.getData();
15633            String ssp;
15634            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15635                mCompatModePackages.handlePackageAddedLocked(ssp,
15636                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15637            }
15638        }
15639
15640        /*
15641         * If this is the time zone changed action, queue up a message that will reset the timezone
15642         * of all currently running processes. This message will get queued up before the broadcast
15643         * happens.
15644         */
15645        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15646            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15647        }
15648
15649        /*
15650         * If the user set the time, let all running processes know.
15651         */
15652        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15653            final int is24Hour = intent.getBooleanExtra(
15654                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15655            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15656            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15657            synchronized (stats) {
15658                stats.noteCurrentTimeChangedLocked();
15659            }
15660        }
15661
15662        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15663            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15664        }
15665
15666        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15667            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15668            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15669        }
15670
15671        // Add to the sticky list if requested.
15672        if (sticky) {
15673            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15674                    callingPid, callingUid)
15675                    != PackageManager.PERMISSION_GRANTED) {
15676                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15677                        + callingPid + ", uid=" + callingUid
15678                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15679                Slog.w(TAG, msg);
15680                throw new SecurityException(msg);
15681            }
15682            if (requiredPermission != null) {
15683                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15684                        + " and enforce permission " + requiredPermission);
15685                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15686            }
15687            if (intent.getComponent() != null) {
15688                throw new SecurityException(
15689                        "Sticky broadcasts can't target a specific component");
15690            }
15691            // We use userId directly here, since the "all" target is maintained
15692            // as a separate set of sticky broadcasts.
15693            if (userId != UserHandle.USER_ALL) {
15694                // But first, if this is not a broadcast to all users, then
15695                // make sure it doesn't conflict with an existing broadcast to
15696                // all users.
15697                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15698                        UserHandle.USER_ALL);
15699                if (stickies != null) {
15700                    ArrayList<Intent> list = stickies.get(intent.getAction());
15701                    if (list != null) {
15702                        int N = list.size();
15703                        int i;
15704                        for (i=0; i<N; i++) {
15705                            if (intent.filterEquals(list.get(i))) {
15706                                throw new IllegalArgumentException(
15707                                        "Sticky broadcast " + intent + " for user "
15708                                        + userId + " conflicts with existing global broadcast");
15709                            }
15710                        }
15711                    }
15712                }
15713            }
15714            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15715            if (stickies == null) {
15716                stickies = new ArrayMap<String, ArrayList<Intent>>();
15717                mStickyBroadcasts.put(userId, stickies);
15718            }
15719            ArrayList<Intent> list = stickies.get(intent.getAction());
15720            if (list == null) {
15721                list = new ArrayList<Intent>();
15722                stickies.put(intent.getAction(), list);
15723            }
15724            int N = list.size();
15725            int i;
15726            for (i=0; i<N; i++) {
15727                if (intent.filterEquals(list.get(i))) {
15728                    // This sticky already exists, replace it.
15729                    list.set(i, new Intent(intent));
15730                    break;
15731                }
15732            }
15733            if (i >= N) {
15734                list.add(new Intent(intent));
15735            }
15736        }
15737
15738        int[] users;
15739        if (userId == UserHandle.USER_ALL) {
15740            // Caller wants broadcast to go to all started users.
15741            users = mStartedUserArray;
15742        } else {
15743            // Caller wants broadcast to go to one specific user.
15744            users = new int[] {userId};
15745        }
15746
15747        // Figure out who all will receive this broadcast.
15748        List receivers = null;
15749        List<BroadcastFilter> registeredReceivers = null;
15750        // Need to resolve the intent to interested receivers...
15751        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15752                 == 0) {
15753            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15754        }
15755        if (intent.getComponent() == null) {
15756            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15757                // Query one target user at a time, excluding shell-restricted users
15758                UserManagerService ums = getUserManagerLocked();
15759                for (int i = 0; i < users.length; i++) {
15760                    if (ums.hasUserRestriction(
15761                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15762                        continue;
15763                    }
15764                    List<BroadcastFilter> registeredReceiversForUser =
15765                            mReceiverResolver.queryIntent(intent,
15766                                    resolvedType, false, users[i]);
15767                    if (registeredReceivers == null) {
15768                        registeredReceivers = registeredReceiversForUser;
15769                    } else if (registeredReceiversForUser != null) {
15770                        registeredReceivers.addAll(registeredReceiversForUser);
15771                    }
15772                }
15773            } else {
15774                registeredReceivers = mReceiverResolver.queryIntent(intent,
15775                        resolvedType, false, userId);
15776            }
15777        }
15778
15779        final boolean replacePending =
15780                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15781
15782        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15783                + " replacePending=" + replacePending);
15784
15785        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15786        if (!ordered && NR > 0) {
15787            // If we are not serializing this broadcast, then send the
15788            // registered receivers separately so they don't wait for the
15789            // components to be launched.
15790            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15791            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15792                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15793                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15794                    ordered, sticky, false, userId);
15795            if (DEBUG_BROADCAST) Slog.v(
15796                    TAG, "Enqueueing parallel broadcast " + r);
15797            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15798            if (!replaced) {
15799                queue.enqueueParallelBroadcastLocked(r);
15800                queue.scheduleBroadcastsLocked();
15801            }
15802            registeredReceivers = null;
15803            NR = 0;
15804        }
15805
15806        // Merge into one list.
15807        int ir = 0;
15808        if (receivers != null) {
15809            // A special case for PACKAGE_ADDED: do not allow the package
15810            // being added to see this broadcast.  This prevents them from
15811            // using this as a back door to get run as soon as they are
15812            // installed.  Maybe in the future we want to have a special install
15813            // broadcast or such for apps, but we'd like to deliberately make
15814            // this decision.
15815            String skipPackages[] = null;
15816            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15817                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15818                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15819                Uri data = intent.getData();
15820                if (data != null) {
15821                    String pkgName = data.getSchemeSpecificPart();
15822                    if (pkgName != null) {
15823                        skipPackages = new String[] { pkgName };
15824                    }
15825                }
15826            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15827                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15828            }
15829            if (skipPackages != null && (skipPackages.length > 0)) {
15830                for (String skipPackage : skipPackages) {
15831                    if (skipPackage != null) {
15832                        int NT = receivers.size();
15833                        for (int it=0; it<NT; it++) {
15834                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15835                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15836                                receivers.remove(it);
15837                                it--;
15838                                NT--;
15839                            }
15840                        }
15841                    }
15842                }
15843            }
15844
15845            int NT = receivers != null ? receivers.size() : 0;
15846            int it = 0;
15847            ResolveInfo curt = null;
15848            BroadcastFilter curr = null;
15849            while (it < NT && ir < NR) {
15850                if (curt == null) {
15851                    curt = (ResolveInfo)receivers.get(it);
15852                }
15853                if (curr == null) {
15854                    curr = registeredReceivers.get(ir);
15855                }
15856                if (curr.getPriority() >= curt.priority) {
15857                    // Insert this broadcast record into the final list.
15858                    receivers.add(it, curr);
15859                    ir++;
15860                    curr = null;
15861                    it++;
15862                    NT++;
15863                } else {
15864                    // Skip to the next ResolveInfo in the final list.
15865                    it++;
15866                    curt = null;
15867                }
15868            }
15869        }
15870        while (ir < NR) {
15871            if (receivers == null) {
15872                receivers = new ArrayList();
15873            }
15874            receivers.add(registeredReceivers.get(ir));
15875            ir++;
15876        }
15877
15878        if ((receivers != null && receivers.size() > 0)
15879                || resultTo != null) {
15880            BroadcastQueue queue = broadcastQueueForIntent(intent);
15881            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15882                    callerPackage, callingPid, callingUid, resolvedType,
15883                    requiredPermission, appOp, receivers, resultTo, resultCode,
15884                    resultData, map, ordered, sticky, false, userId);
15885            if (DEBUG_BROADCAST) Slog.v(
15886                    TAG, "Enqueueing ordered broadcast " + r
15887                    + ": prev had " + queue.mOrderedBroadcasts.size());
15888            if (DEBUG_BROADCAST) {
15889                int seq = r.intent.getIntExtra("seq", -1);
15890                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15891            }
15892            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15893            if (!replaced) {
15894                queue.enqueueOrderedBroadcastLocked(r);
15895                queue.scheduleBroadcastsLocked();
15896            }
15897        }
15898
15899        return ActivityManager.BROADCAST_SUCCESS;
15900    }
15901
15902    final Intent verifyBroadcastLocked(Intent intent) {
15903        // Refuse possible leaked file descriptors
15904        if (intent != null && intent.hasFileDescriptors() == true) {
15905            throw new IllegalArgumentException("File descriptors passed in Intent");
15906        }
15907
15908        int flags = intent.getFlags();
15909
15910        if (!mProcessesReady) {
15911            // if the caller really truly claims to know what they're doing, go
15912            // ahead and allow the broadcast without launching any receivers
15913            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15914                intent = new Intent(intent);
15915                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15916            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15917                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15918                        + " before boot completion");
15919                throw new IllegalStateException("Cannot broadcast before boot completed");
15920            }
15921        }
15922
15923        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15924            throw new IllegalArgumentException(
15925                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15926        }
15927
15928        return intent;
15929    }
15930
15931    public final int broadcastIntent(IApplicationThread caller,
15932            Intent intent, String resolvedType, IIntentReceiver resultTo,
15933            int resultCode, String resultData, Bundle map,
15934            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15935        enforceNotIsolatedCaller("broadcastIntent");
15936        synchronized(this) {
15937            intent = verifyBroadcastLocked(intent);
15938
15939            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15940            final int callingPid = Binder.getCallingPid();
15941            final int callingUid = Binder.getCallingUid();
15942            final long origId = Binder.clearCallingIdentity();
15943            int res = broadcastIntentLocked(callerApp,
15944                    callerApp != null ? callerApp.info.packageName : null,
15945                    intent, resolvedType, resultTo,
15946                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15947                    callingPid, callingUid, userId);
15948            Binder.restoreCallingIdentity(origId);
15949            return res;
15950        }
15951    }
15952
15953    int broadcastIntentInPackage(String packageName, int uid,
15954            Intent intent, String resolvedType, IIntentReceiver resultTo,
15955            int resultCode, String resultData, Bundle map,
15956            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15957        synchronized(this) {
15958            intent = verifyBroadcastLocked(intent);
15959
15960            final long origId = Binder.clearCallingIdentity();
15961            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15962                    resultTo, resultCode, resultData, map, requiredPermission,
15963                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15964            Binder.restoreCallingIdentity(origId);
15965            return res;
15966        }
15967    }
15968
15969    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15970        // Refuse possible leaked file descriptors
15971        if (intent != null && intent.hasFileDescriptors() == true) {
15972            throw new IllegalArgumentException("File descriptors passed in Intent");
15973        }
15974
15975        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15976                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15977
15978        synchronized(this) {
15979            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15980                    != PackageManager.PERMISSION_GRANTED) {
15981                String msg = "Permission Denial: unbroadcastIntent() from pid="
15982                        + Binder.getCallingPid()
15983                        + ", uid=" + Binder.getCallingUid()
15984                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15985                Slog.w(TAG, msg);
15986                throw new SecurityException(msg);
15987            }
15988            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15989            if (stickies != null) {
15990                ArrayList<Intent> list = stickies.get(intent.getAction());
15991                if (list != null) {
15992                    int N = list.size();
15993                    int i;
15994                    for (i=0; i<N; i++) {
15995                        if (intent.filterEquals(list.get(i))) {
15996                            list.remove(i);
15997                            break;
15998                        }
15999                    }
16000                    if (list.size() <= 0) {
16001                        stickies.remove(intent.getAction());
16002                    }
16003                }
16004                if (stickies.size() <= 0) {
16005                    mStickyBroadcasts.remove(userId);
16006                }
16007            }
16008        }
16009    }
16010
16011    void backgroundServicesFinishedLocked(int userId) {
16012        for (BroadcastQueue queue : mBroadcastQueues) {
16013            queue.backgroundServicesFinishedLocked(userId);
16014        }
16015    }
16016
16017    public void finishReceiver(IBinder who, int resultCode, String resultData,
16018            Bundle resultExtras, boolean resultAbort, int flags) {
16019        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16020
16021        // Refuse possible leaked file descriptors
16022        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16023            throw new IllegalArgumentException("File descriptors passed in Bundle");
16024        }
16025
16026        final long origId = Binder.clearCallingIdentity();
16027        try {
16028            boolean doNext = false;
16029            BroadcastRecord r;
16030
16031            synchronized(this) {
16032                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16033                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16034                r = queue.getMatchingOrderedReceiver(who);
16035                if (r != null) {
16036                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16037                        resultData, resultExtras, resultAbort, true);
16038                }
16039            }
16040
16041            if (doNext) {
16042                r.queue.processNextBroadcast(false);
16043            }
16044            trimApplications();
16045        } finally {
16046            Binder.restoreCallingIdentity(origId);
16047        }
16048    }
16049
16050    // =========================================================
16051    // INSTRUMENTATION
16052    // =========================================================
16053
16054    public boolean startInstrumentation(ComponentName className,
16055            String profileFile, int flags, Bundle arguments,
16056            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16057            int userId, String abiOverride) {
16058        enforceNotIsolatedCaller("startInstrumentation");
16059        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16060                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16061        // Refuse possible leaked file descriptors
16062        if (arguments != null && arguments.hasFileDescriptors()) {
16063            throw new IllegalArgumentException("File descriptors passed in Bundle");
16064        }
16065
16066        synchronized(this) {
16067            InstrumentationInfo ii = null;
16068            ApplicationInfo ai = null;
16069            try {
16070                ii = mContext.getPackageManager().getInstrumentationInfo(
16071                    className, STOCK_PM_FLAGS);
16072                ai = AppGlobals.getPackageManager().getApplicationInfo(
16073                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16074            } catch (PackageManager.NameNotFoundException e) {
16075            } catch (RemoteException e) {
16076            }
16077            if (ii == null) {
16078                reportStartInstrumentationFailure(watcher, className,
16079                        "Unable to find instrumentation info for: " + className);
16080                return false;
16081            }
16082            if (ai == null) {
16083                reportStartInstrumentationFailure(watcher, className,
16084                        "Unable to find instrumentation target package: " + ii.targetPackage);
16085                return false;
16086            }
16087
16088            int match = mContext.getPackageManager().checkSignatures(
16089                    ii.targetPackage, ii.packageName);
16090            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16091                String msg = "Permission Denial: starting instrumentation "
16092                        + className + " from pid="
16093                        + Binder.getCallingPid()
16094                        + ", uid=" + Binder.getCallingPid()
16095                        + " not allowed because package " + ii.packageName
16096                        + " does not have a signature matching the target "
16097                        + ii.targetPackage;
16098                reportStartInstrumentationFailure(watcher, className, msg);
16099                throw new SecurityException(msg);
16100            }
16101
16102            final long origId = Binder.clearCallingIdentity();
16103            // Instrumentation can kill and relaunch even persistent processes
16104            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16105                    "start instr");
16106            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16107            app.instrumentationClass = className;
16108            app.instrumentationInfo = ai;
16109            app.instrumentationProfileFile = profileFile;
16110            app.instrumentationArguments = arguments;
16111            app.instrumentationWatcher = watcher;
16112            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16113            app.instrumentationResultClass = className;
16114            Binder.restoreCallingIdentity(origId);
16115        }
16116
16117        return true;
16118    }
16119
16120    /**
16121     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16122     * error to the logs, but if somebody is watching, send the report there too.  This enables
16123     * the "am" command to report errors with more information.
16124     *
16125     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16126     * @param cn The component name of the instrumentation.
16127     * @param report The error report.
16128     */
16129    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16130            ComponentName cn, String report) {
16131        Slog.w(TAG, report);
16132        try {
16133            if (watcher != null) {
16134                Bundle results = new Bundle();
16135                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16136                results.putString("Error", report);
16137                watcher.instrumentationStatus(cn, -1, results);
16138            }
16139        } catch (RemoteException e) {
16140            Slog.w(TAG, e);
16141        }
16142    }
16143
16144    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16145        if (app.instrumentationWatcher != null) {
16146            try {
16147                // NOTE:  IInstrumentationWatcher *must* be oneway here
16148                app.instrumentationWatcher.instrumentationFinished(
16149                    app.instrumentationClass,
16150                    resultCode,
16151                    results);
16152            } catch (RemoteException e) {
16153            }
16154        }
16155        if (app.instrumentationUiAutomationConnection != null) {
16156            try {
16157                app.instrumentationUiAutomationConnection.shutdown();
16158            } catch (RemoteException re) {
16159                /* ignore */
16160            }
16161            // Only a UiAutomation can set this flag and now that
16162            // it is finished we make sure it is reset to its default.
16163            mUserIsMonkey = false;
16164        }
16165        app.instrumentationWatcher = null;
16166        app.instrumentationUiAutomationConnection = null;
16167        app.instrumentationClass = null;
16168        app.instrumentationInfo = null;
16169        app.instrumentationProfileFile = null;
16170        app.instrumentationArguments = null;
16171
16172        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16173                "finished inst");
16174    }
16175
16176    public void finishInstrumentation(IApplicationThread target,
16177            int resultCode, Bundle results) {
16178        int userId = UserHandle.getCallingUserId();
16179        // Refuse possible leaked file descriptors
16180        if (results != null && results.hasFileDescriptors()) {
16181            throw new IllegalArgumentException("File descriptors passed in Intent");
16182        }
16183
16184        synchronized(this) {
16185            ProcessRecord app = getRecordForAppLocked(target);
16186            if (app == null) {
16187                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16188                return;
16189            }
16190            final long origId = Binder.clearCallingIdentity();
16191            finishInstrumentationLocked(app, resultCode, results);
16192            Binder.restoreCallingIdentity(origId);
16193        }
16194    }
16195
16196    // =========================================================
16197    // CONFIGURATION
16198    // =========================================================
16199
16200    public ConfigurationInfo getDeviceConfigurationInfo() {
16201        ConfigurationInfo config = new ConfigurationInfo();
16202        synchronized (this) {
16203            config.reqTouchScreen = mConfiguration.touchscreen;
16204            config.reqKeyboardType = mConfiguration.keyboard;
16205            config.reqNavigation = mConfiguration.navigation;
16206            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16207                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16208                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16209            }
16210            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16211                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16212                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16213            }
16214            config.reqGlEsVersion = GL_ES_VERSION;
16215        }
16216        return config;
16217    }
16218
16219    ActivityStack getFocusedStack() {
16220        return mStackSupervisor.getFocusedStack();
16221    }
16222
16223    public Configuration getConfiguration() {
16224        Configuration ci;
16225        synchronized(this) {
16226            ci = new Configuration(mConfiguration);
16227        }
16228        return ci;
16229    }
16230
16231    public void updatePersistentConfiguration(Configuration values) {
16232        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16233                "updateConfiguration()");
16234        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16235                "updateConfiguration()");
16236        if (values == null) {
16237            throw new NullPointerException("Configuration must not be null");
16238        }
16239
16240        synchronized(this) {
16241            final long origId = Binder.clearCallingIdentity();
16242            updateConfigurationLocked(values, null, true, false);
16243            Binder.restoreCallingIdentity(origId);
16244        }
16245    }
16246
16247    public void updateConfiguration(Configuration values) {
16248        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16249                "updateConfiguration()");
16250
16251        synchronized(this) {
16252            if (values == null && mWindowManager != null) {
16253                // sentinel: fetch the current configuration from the window manager
16254                values = mWindowManager.computeNewConfiguration();
16255            }
16256
16257            if (mWindowManager != null) {
16258                mProcessList.applyDisplaySize(mWindowManager);
16259            }
16260
16261            final long origId = Binder.clearCallingIdentity();
16262            if (values != null) {
16263                Settings.System.clearConfiguration(values);
16264            }
16265            updateConfigurationLocked(values, null, false, false);
16266            Binder.restoreCallingIdentity(origId);
16267        }
16268    }
16269
16270    /**
16271     * Do either or both things: (1) change the current configuration, and (2)
16272     * make sure the given activity is running with the (now) current
16273     * configuration.  Returns true if the activity has been left running, or
16274     * false if <var>starting</var> is being destroyed to match the new
16275     * configuration.
16276     * @param persistent TODO
16277     */
16278    boolean updateConfigurationLocked(Configuration values,
16279            ActivityRecord starting, boolean persistent, boolean initLocale) {
16280        int changes = 0;
16281
16282        if (values != null) {
16283            Configuration newConfig = new Configuration(mConfiguration);
16284            changes = newConfig.updateFrom(values);
16285            if (changes != 0) {
16286                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16287                    Slog.i(TAG, "Updating configuration to: " + values);
16288                }
16289
16290                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16291
16292                if (values.locale != null && !initLocale) {
16293                    saveLocaleLocked(values.locale,
16294                                     !values.locale.equals(mConfiguration.locale),
16295                                     values.userSetLocale);
16296                }
16297
16298                mConfigurationSeq++;
16299                if (mConfigurationSeq <= 0) {
16300                    mConfigurationSeq = 1;
16301                }
16302                newConfig.seq = mConfigurationSeq;
16303                mConfiguration = newConfig;
16304                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16305                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16306                //mUsageStatsService.noteStartConfig(newConfig);
16307
16308                final Configuration configCopy = new Configuration(mConfiguration);
16309
16310                // TODO: If our config changes, should we auto dismiss any currently
16311                // showing dialogs?
16312                mShowDialogs = shouldShowDialogs(newConfig);
16313
16314                AttributeCache ac = AttributeCache.instance();
16315                if (ac != null) {
16316                    ac.updateConfiguration(configCopy);
16317                }
16318
16319                // Make sure all resources in our process are updated
16320                // right now, so that anyone who is going to retrieve
16321                // resource values after we return will be sure to get
16322                // the new ones.  This is especially important during
16323                // boot, where the first config change needs to guarantee
16324                // all resources have that config before following boot
16325                // code is executed.
16326                mSystemThread.applyConfigurationToResources(configCopy);
16327
16328                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16329                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16330                    msg.obj = new Configuration(configCopy);
16331                    mHandler.sendMessage(msg);
16332                }
16333
16334                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16335                    ProcessRecord app = mLruProcesses.get(i);
16336                    try {
16337                        if (app.thread != null) {
16338                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16339                                    + app.processName + " new config " + mConfiguration);
16340                            app.thread.scheduleConfigurationChanged(configCopy);
16341                        }
16342                    } catch (Exception e) {
16343                    }
16344                }
16345                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16346                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16347                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16348                        | Intent.FLAG_RECEIVER_FOREGROUND);
16349                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16350                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16351                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16352                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16353                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16354                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16355                    broadcastIntentLocked(null, null, intent,
16356                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16357                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16358                }
16359            }
16360        }
16361
16362        boolean kept = true;
16363        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16364        // mainStack is null during startup.
16365        if (mainStack != null) {
16366            if (changes != 0 && starting == null) {
16367                // If the configuration changed, and the caller is not already
16368                // in the process of starting an activity, then find the top
16369                // activity to check if its configuration needs to change.
16370                starting = mainStack.topRunningActivityLocked(null);
16371            }
16372
16373            if (starting != null) {
16374                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16375                // And we need to make sure at this point that all other activities
16376                // are made visible with the correct configuration.
16377                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16378            }
16379        }
16380
16381        if (values != null && mWindowManager != null) {
16382            mWindowManager.setNewConfiguration(mConfiguration);
16383        }
16384
16385        return kept;
16386    }
16387
16388    /**
16389     * Decide based on the configuration whether we should shouw the ANR,
16390     * crash, etc dialogs.  The idea is that if there is no affordnace to
16391     * press the on-screen buttons, we shouldn't show the dialog.
16392     *
16393     * A thought: SystemUI might also want to get told about this, the Power
16394     * dialog / global actions also might want different behaviors.
16395     */
16396    private static final boolean shouldShowDialogs(Configuration config) {
16397        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16398                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16399    }
16400
16401    /**
16402     * Save the locale.  You must be inside a synchronized (this) block.
16403     */
16404    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16405        if(isDiff) {
16406            SystemProperties.set("user.language", l.getLanguage());
16407            SystemProperties.set("user.region", l.getCountry());
16408        }
16409
16410        if(isPersist) {
16411            SystemProperties.set("persist.sys.language", l.getLanguage());
16412            SystemProperties.set("persist.sys.country", l.getCountry());
16413            SystemProperties.set("persist.sys.localevar", l.getVariant());
16414
16415            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16416        }
16417    }
16418
16419    @Override
16420    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16421        synchronized (this) {
16422            ActivityRecord srec = ActivityRecord.forToken(token);
16423            if (srec.task != null && srec.task.stack != null) {
16424                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16425            }
16426        }
16427        return false;
16428    }
16429
16430    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16431            Intent resultData) {
16432
16433        synchronized (this) {
16434            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16435            if (stack != null) {
16436                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16437            }
16438            return false;
16439        }
16440    }
16441
16442    public int getLaunchedFromUid(IBinder activityToken) {
16443        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16444        if (srec == null) {
16445            return -1;
16446        }
16447        return srec.launchedFromUid;
16448    }
16449
16450    public String getLaunchedFromPackage(IBinder activityToken) {
16451        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16452        if (srec == null) {
16453            return null;
16454        }
16455        return srec.launchedFromPackage;
16456    }
16457
16458    // =========================================================
16459    // LIFETIME MANAGEMENT
16460    // =========================================================
16461
16462    // Returns which broadcast queue the app is the current [or imminent] receiver
16463    // on, or 'null' if the app is not an active broadcast recipient.
16464    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16465        BroadcastRecord r = app.curReceiver;
16466        if (r != null) {
16467            return r.queue;
16468        }
16469
16470        // It's not the current receiver, but it might be starting up to become one
16471        synchronized (this) {
16472            for (BroadcastQueue queue : mBroadcastQueues) {
16473                r = queue.mPendingBroadcast;
16474                if (r != null && r.curApp == app) {
16475                    // found it; report which queue it's in
16476                    return queue;
16477                }
16478            }
16479        }
16480
16481        return null;
16482    }
16483
16484    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16485            boolean doingAll, long now) {
16486        if (mAdjSeq == app.adjSeq) {
16487            // This adjustment has already been computed.
16488            return app.curRawAdj;
16489        }
16490
16491        if (app.thread == null) {
16492            app.adjSeq = mAdjSeq;
16493            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16494            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16495            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16496        }
16497
16498        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16499        app.adjSource = null;
16500        app.adjTarget = null;
16501        app.empty = false;
16502        app.cached = false;
16503
16504        final int activitiesSize = app.activities.size();
16505
16506        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16507            // The max adjustment doesn't allow this app to be anything
16508            // below foreground, so it is not worth doing work for it.
16509            app.adjType = "fixed";
16510            app.adjSeq = mAdjSeq;
16511            app.curRawAdj = app.maxAdj;
16512            app.foregroundActivities = false;
16513            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16514            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16515            // System processes can do UI, and when they do we want to have
16516            // them trim their memory after the user leaves the UI.  To
16517            // facilitate this, here we need to determine whether or not it
16518            // is currently showing UI.
16519            app.systemNoUi = true;
16520            if (app == TOP_APP) {
16521                app.systemNoUi = false;
16522            } else if (activitiesSize > 0) {
16523                for (int j = 0; j < activitiesSize; j++) {
16524                    final ActivityRecord r = app.activities.get(j);
16525                    if (r.visible) {
16526                        app.systemNoUi = false;
16527                    }
16528                }
16529            }
16530            if (!app.systemNoUi) {
16531                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16532            }
16533            return (app.curAdj=app.maxAdj);
16534        }
16535
16536        app.systemNoUi = false;
16537
16538        // Determine the importance of the process, starting with most
16539        // important to least, and assign an appropriate OOM adjustment.
16540        int adj;
16541        int schedGroup;
16542        int procState;
16543        boolean foregroundActivities = false;
16544        BroadcastQueue queue;
16545        if (app == TOP_APP) {
16546            // The last app on the list is the foreground app.
16547            adj = ProcessList.FOREGROUND_APP_ADJ;
16548            schedGroup = Process.THREAD_GROUP_DEFAULT;
16549            app.adjType = "top-activity";
16550            foregroundActivities = true;
16551            procState = ActivityManager.PROCESS_STATE_TOP;
16552        } else if (app.instrumentationClass != null) {
16553            // Don't want to kill running instrumentation.
16554            adj = ProcessList.FOREGROUND_APP_ADJ;
16555            schedGroup = Process.THREAD_GROUP_DEFAULT;
16556            app.adjType = "instrumentation";
16557            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16558        } else if ((queue = isReceivingBroadcast(app)) != null) {
16559            // An app that is currently receiving a broadcast also
16560            // counts as being in the foreground for OOM killer purposes.
16561            // It's placed in a sched group based on the nature of the
16562            // broadcast as reflected by which queue it's active in.
16563            adj = ProcessList.FOREGROUND_APP_ADJ;
16564            schedGroup = (queue == mFgBroadcastQueue)
16565                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16566            app.adjType = "broadcast";
16567            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16568        } else if (app.executingServices.size() > 0) {
16569            // An app that is currently executing a service callback also
16570            // counts as being in the foreground.
16571            adj = ProcessList.FOREGROUND_APP_ADJ;
16572            schedGroup = app.execServicesFg ?
16573                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16574            app.adjType = "exec-service";
16575            procState = ActivityManager.PROCESS_STATE_SERVICE;
16576            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16577        } else {
16578            // As far as we know the process is empty.  We may change our mind later.
16579            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16580            // At this point we don't actually know the adjustment.  Use the cached adj
16581            // value that the caller wants us to.
16582            adj = cachedAdj;
16583            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16584            app.cached = true;
16585            app.empty = true;
16586            app.adjType = "cch-empty";
16587        }
16588
16589        // Examine all activities if not already foreground.
16590        if (!foregroundActivities && activitiesSize > 0) {
16591            for (int j = 0; j < activitiesSize; j++) {
16592                final ActivityRecord r = app.activities.get(j);
16593                if (r.app != app) {
16594                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16595                            + app + "?!?");
16596                    continue;
16597                }
16598                if (r.visible) {
16599                    // App has a visible activity; only upgrade adjustment.
16600                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16601                        adj = ProcessList.VISIBLE_APP_ADJ;
16602                        app.adjType = "visible";
16603                    }
16604                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16605                        procState = ActivityManager.PROCESS_STATE_TOP;
16606                    }
16607                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16608                    app.cached = false;
16609                    app.empty = false;
16610                    foregroundActivities = true;
16611                    break;
16612                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16613                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16614                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16615                        app.adjType = "pausing";
16616                    }
16617                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16618                        procState = ActivityManager.PROCESS_STATE_TOP;
16619                    }
16620                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16621                    app.cached = false;
16622                    app.empty = false;
16623                    foregroundActivities = true;
16624                } else if (r.state == ActivityState.STOPPING) {
16625                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16626                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16627                        app.adjType = "stopping";
16628                    }
16629                    // For the process state, we will at this point consider the
16630                    // process to be cached.  It will be cached either as an activity
16631                    // or empty depending on whether the activity is finishing.  We do
16632                    // this so that we can treat the process as cached for purposes of
16633                    // memory trimming (determing current memory level, trim command to
16634                    // send to process) since there can be an arbitrary number of stopping
16635                    // processes and they should soon all go into the cached state.
16636                    if (!r.finishing) {
16637                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16638                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16639                        }
16640                    }
16641                    app.cached = false;
16642                    app.empty = false;
16643                    foregroundActivities = true;
16644                } else {
16645                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16646                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16647                        app.adjType = "cch-act";
16648                    }
16649                }
16650            }
16651        }
16652
16653        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16654            if (app.foregroundServices) {
16655                // The user is aware of this app, so make it visible.
16656                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16657                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16658                app.cached = false;
16659                app.adjType = "fg-service";
16660                schedGroup = Process.THREAD_GROUP_DEFAULT;
16661            } else if (app.forcingToForeground != null) {
16662                // The user is aware of this app, so make it visible.
16663                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16664                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16665                app.cached = false;
16666                app.adjType = "force-fg";
16667                app.adjSource = app.forcingToForeground;
16668                schedGroup = Process.THREAD_GROUP_DEFAULT;
16669            }
16670        }
16671
16672        if (app == mHeavyWeightProcess) {
16673            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16674                // We don't want to kill the current heavy-weight process.
16675                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16676                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16677                app.cached = false;
16678                app.adjType = "heavy";
16679            }
16680            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16681                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16682            }
16683        }
16684
16685        if (app == mHomeProcess) {
16686            if (adj > ProcessList.HOME_APP_ADJ) {
16687                // This process is hosting what we currently consider to be the
16688                // home app, so we don't want to let it go into the background.
16689                adj = ProcessList.HOME_APP_ADJ;
16690                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16691                app.cached = false;
16692                app.adjType = "home";
16693            }
16694            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16695                procState = ActivityManager.PROCESS_STATE_HOME;
16696            }
16697        }
16698
16699        if (app == mPreviousProcess && app.activities.size() > 0) {
16700            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16701                // This was the previous process that showed UI to the user.
16702                // We want to try to keep it around more aggressively, to give
16703                // a good experience around switching between two apps.
16704                adj = ProcessList.PREVIOUS_APP_ADJ;
16705                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16706                app.cached = false;
16707                app.adjType = "previous";
16708            }
16709            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16710                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16711            }
16712        }
16713
16714        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16715                + " reason=" + app.adjType);
16716
16717        // By default, we use the computed adjustment.  It may be changed if
16718        // there are applications dependent on our services or providers, but
16719        // this gives us a baseline and makes sure we don't get into an
16720        // infinite recursion.
16721        app.adjSeq = mAdjSeq;
16722        app.curRawAdj = adj;
16723        app.hasStartedServices = false;
16724
16725        if (mBackupTarget != null && app == mBackupTarget.app) {
16726            // If possible we want to avoid killing apps while they're being backed up
16727            if (adj > ProcessList.BACKUP_APP_ADJ) {
16728                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16729                adj = ProcessList.BACKUP_APP_ADJ;
16730                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16731                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16732                }
16733                app.adjType = "backup";
16734                app.cached = false;
16735            }
16736            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16737                procState = ActivityManager.PROCESS_STATE_BACKUP;
16738            }
16739        }
16740
16741        boolean mayBeTop = false;
16742
16743        for (int is = app.services.size()-1;
16744                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16745                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16746                        || procState > ActivityManager.PROCESS_STATE_TOP);
16747                is--) {
16748            ServiceRecord s = app.services.valueAt(is);
16749            if (s.startRequested) {
16750                app.hasStartedServices = true;
16751                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16752                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16753                }
16754                if (app.hasShownUi && app != mHomeProcess) {
16755                    // If this process has shown some UI, let it immediately
16756                    // go to the LRU list because it may be pretty heavy with
16757                    // UI stuff.  We'll tag it with a label just to help
16758                    // debug and understand what is going on.
16759                    if (adj > ProcessList.SERVICE_ADJ) {
16760                        app.adjType = "cch-started-ui-services";
16761                    }
16762                } else {
16763                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16764                        // This service has seen some activity within
16765                        // recent memory, so we will keep its process ahead
16766                        // of the background processes.
16767                        if (adj > ProcessList.SERVICE_ADJ) {
16768                            adj = ProcessList.SERVICE_ADJ;
16769                            app.adjType = "started-services";
16770                            app.cached = false;
16771                        }
16772                    }
16773                    // If we have let the service slide into the background
16774                    // state, still have some text describing what it is doing
16775                    // even though the service no longer has an impact.
16776                    if (adj > ProcessList.SERVICE_ADJ) {
16777                        app.adjType = "cch-started-services";
16778                    }
16779                }
16780            }
16781            for (int conni = s.connections.size()-1;
16782                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16783                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16784                            || procState > ActivityManager.PROCESS_STATE_TOP);
16785                    conni--) {
16786                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16787                for (int i = 0;
16788                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16789                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16790                                || procState > ActivityManager.PROCESS_STATE_TOP);
16791                        i++) {
16792                    // XXX should compute this based on the max of
16793                    // all connected clients.
16794                    ConnectionRecord cr = clist.get(i);
16795                    if (cr.binding.client == app) {
16796                        // Binding to ourself is not interesting.
16797                        continue;
16798                    }
16799                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16800                        ProcessRecord client = cr.binding.client;
16801                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16802                                TOP_APP, doingAll, now);
16803                        int clientProcState = client.curProcState;
16804                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16805                            // If the other app is cached for any reason, for purposes here
16806                            // we are going to consider it empty.  The specific cached state
16807                            // doesn't propagate except under certain conditions.
16808                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16809                        }
16810                        String adjType = null;
16811                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16812                            // Not doing bind OOM management, so treat
16813                            // this guy more like a started service.
16814                            if (app.hasShownUi && app != mHomeProcess) {
16815                                // If this process has shown some UI, let it immediately
16816                                // go to the LRU list because it may be pretty heavy with
16817                                // UI stuff.  We'll tag it with a label just to help
16818                                // debug and understand what is going on.
16819                                if (adj > clientAdj) {
16820                                    adjType = "cch-bound-ui-services";
16821                                }
16822                                app.cached = false;
16823                                clientAdj = adj;
16824                                clientProcState = procState;
16825                            } else {
16826                                if (now >= (s.lastActivity
16827                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16828                                    // This service has not seen activity within
16829                                    // recent memory, so allow it to drop to the
16830                                    // LRU list if there is no other reason to keep
16831                                    // it around.  We'll also tag it with a label just
16832                                    // to help debug and undertand what is going on.
16833                                    if (adj > clientAdj) {
16834                                        adjType = "cch-bound-services";
16835                                    }
16836                                    clientAdj = adj;
16837                                }
16838                            }
16839                        }
16840                        if (adj > clientAdj) {
16841                            // If this process has recently shown UI, and
16842                            // the process that is binding to it is less
16843                            // important than being visible, then we don't
16844                            // care about the binding as much as we care
16845                            // about letting this process get into the LRU
16846                            // list to be killed and restarted if needed for
16847                            // memory.
16848                            if (app.hasShownUi && app != mHomeProcess
16849                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16850                                adjType = "cch-bound-ui-services";
16851                            } else {
16852                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16853                                        |Context.BIND_IMPORTANT)) != 0) {
16854                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16855                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16856                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16857                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16858                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16859                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16860                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16861                                    adj = clientAdj;
16862                                } else {
16863                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16864                                        adj = ProcessList.VISIBLE_APP_ADJ;
16865                                    }
16866                                }
16867                                if (!client.cached) {
16868                                    app.cached = false;
16869                                }
16870                                adjType = "service";
16871                            }
16872                        }
16873                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16874                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16875                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16876                            }
16877                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16878                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16879                                    // Special handling of clients who are in the top state.
16880                                    // We *may* want to consider this process to be in the
16881                                    // top state as well, but only if there is not another
16882                                    // reason for it to be running.  Being on the top is a
16883                                    // special state, meaning you are specifically running
16884                                    // for the current top app.  If the process is already
16885                                    // running in the background for some other reason, it
16886                                    // is more important to continue considering it to be
16887                                    // in the background state.
16888                                    mayBeTop = true;
16889                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16890                                } else {
16891                                    // Special handling for above-top states (persistent
16892                                    // processes).  These should not bring the current process
16893                                    // into the top state, since they are not on top.  Instead
16894                                    // give them the best state after that.
16895                                    clientProcState =
16896                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16897                                }
16898                            }
16899                        } else {
16900                            if (clientProcState <
16901                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16902                                clientProcState =
16903                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16904                            }
16905                        }
16906                        if (procState > clientProcState) {
16907                            procState = clientProcState;
16908                        }
16909                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16910                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16911                            app.pendingUiClean = true;
16912                        }
16913                        if (adjType != null) {
16914                            app.adjType = adjType;
16915                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16916                                    .REASON_SERVICE_IN_USE;
16917                            app.adjSource = cr.binding.client;
16918                            app.adjSourceProcState = clientProcState;
16919                            app.adjTarget = s.name;
16920                        }
16921                    }
16922                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16923                        app.treatLikeActivity = true;
16924                    }
16925                    final ActivityRecord a = cr.activity;
16926                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16927                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16928                                (a.visible || a.state == ActivityState.RESUMED
16929                                 || a.state == ActivityState.PAUSING)) {
16930                            adj = ProcessList.FOREGROUND_APP_ADJ;
16931                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16932                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16933                            }
16934                            app.cached = false;
16935                            app.adjType = "service";
16936                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16937                                    .REASON_SERVICE_IN_USE;
16938                            app.adjSource = a;
16939                            app.adjSourceProcState = procState;
16940                            app.adjTarget = s.name;
16941                        }
16942                    }
16943                }
16944            }
16945        }
16946
16947        for (int provi = app.pubProviders.size()-1;
16948                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16949                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16950                        || procState > ActivityManager.PROCESS_STATE_TOP);
16951                provi--) {
16952            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16953            for (int i = cpr.connections.size()-1;
16954                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16955                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16956                            || procState > ActivityManager.PROCESS_STATE_TOP);
16957                    i--) {
16958                ContentProviderConnection conn = cpr.connections.get(i);
16959                ProcessRecord client = conn.client;
16960                if (client == app) {
16961                    // Being our own client is not interesting.
16962                    continue;
16963                }
16964                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16965                int clientProcState = client.curProcState;
16966                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16967                    // If the other app is cached for any reason, for purposes here
16968                    // we are going to consider it empty.
16969                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16970                }
16971                if (adj > clientAdj) {
16972                    if (app.hasShownUi && app != mHomeProcess
16973                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16974                        app.adjType = "cch-ui-provider";
16975                    } else {
16976                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16977                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16978                        app.adjType = "provider";
16979                    }
16980                    app.cached &= client.cached;
16981                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16982                            .REASON_PROVIDER_IN_USE;
16983                    app.adjSource = client;
16984                    app.adjSourceProcState = clientProcState;
16985                    app.adjTarget = cpr.name;
16986                }
16987                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16988                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16989                        // Special handling of clients who are in the top state.
16990                        // We *may* want to consider this process to be in the
16991                        // top state as well, but only if there is not another
16992                        // reason for it to be running.  Being on the top is a
16993                        // special state, meaning you are specifically running
16994                        // for the current top app.  If the process is already
16995                        // running in the background for some other reason, it
16996                        // is more important to continue considering it to be
16997                        // in the background state.
16998                        mayBeTop = true;
16999                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17000                    } else {
17001                        // Special handling for above-top states (persistent
17002                        // processes).  These should not bring the current process
17003                        // into the top state, since they are not on top.  Instead
17004                        // give them the best state after that.
17005                        clientProcState =
17006                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17007                    }
17008                }
17009                if (procState > clientProcState) {
17010                    procState = clientProcState;
17011                }
17012                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17013                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17014                }
17015            }
17016            // If the provider has external (non-framework) process
17017            // dependencies, ensure that its adjustment is at least
17018            // FOREGROUND_APP_ADJ.
17019            if (cpr.hasExternalProcessHandles()) {
17020                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17021                    adj = ProcessList.FOREGROUND_APP_ADJ;
17022                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17023                    app.cached = false;
17024                    app.adjType = "provider";
17025                    app.adjTarget = cpr.name;
17026                }
17027                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17028                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17029                }
17030            }
17031        }
17032
17033        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17034            // A client of one of our services or providers is in the top state.  We
17035            // *may* want to be in the top state, but not if we are already running in
17036            // the background for some other reason.  For the decision here, we are going
17037            // to pick out a few specific states that we want to remain in when a client
17038            // is top (states that tend to be longer-term) and otherwise allow it to go
17039            // to the top state.
17040            switch (procState) {
17041                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17042                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17043                case ActivityManager.PROCESS_STATE_SERVICE:
17044                    // These all are longer-term states, so pull them up to the top
17045                    // of the background states, but not all the way to the top state.
17046                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17047                    break;
17048                default:
17049                    // Otherwise, top is a better choice, so take it.
17050                    procState = ActivityManager.PROCESS_STATE_TOP;
17051                    break;
17052            }
17053        }
17054
17055        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17056            if (app.hasClientActivities) {
17057                // This is a cached process, but with client activities.  Mark it so.
17058                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17059                app.adjType = "cch-client-act";
17060            } else if (app.treatLikeActivity) {
17061                // This is a cached process, but somebody wants us to treat it like it has
17062                // an activity, okay!
17063                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17064                app.adjType = "cch-as-act";
17065            }
17066        }
17067
17068        if (adj == ProcessList.SERVICE_ADJ) {
17069            if (doingAll) {
17070                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17071                mNewNumServiceProcs++;
17072                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17073                if (!app.serviceb) {
17074                    // This service isn't far enough down on the LRU list to
17075                    // normally be a B service, but if we are low on RAM and it
17076                    // is large we want to force it down since we would prefer to
17077                    // keep launcher over it.
17078                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17079                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17080                        app.serviceHighRam = true;
17081                        app.serviceb = true;
17082                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17083                    } else {
17084                        mNewNumAServiceProcs++;
17085                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17086                    }
17087                } else {
17088                    app.serviceHighRam = false;
17089                }
17090            }
17091            if (app.serviceb) {
17092                adj = ProcessList.SERVICE_B_ADJ;
17093            }
17094        }
17095
17096        app.curRawAdj = adj;
17097
17098        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17099        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17100        if (adj > app.maxAdj) {
17101            adj = app.maxAdj;
17102            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17103                schedGroup = Process.THREAD_GROUP_DEFAULT;
17104            }
17105        }
17106
17107        // Do final modification to adj.  Everything we do between here and applying
17108        // the final setAdj must be done in this function, because we will also use
17109        // it when computing the final cached adj later.  Note that we don't need to
17110        // worry about this for max adj above, since max adj will always be used to
17111        // keep it out of the cached vaues.
17112        app.curAdj = app.modifyRawOomAdj(adj);
17113        app.curSchedGroup = schedGroup;
17114        app.curProcState = procState;
17115        app.foregroundActivities = foregroundActivities;
17116
17117        return app.curRawAdj;
17118    }
17119
17120    /**
17121     * Schedule PSS collection of a process.
17122     */
17123    void requestPssLocked(ProcessRecord proc, int procState) {
17124        if (mPendingPssProcesses.contains(proc)) {
17125            return;
17126        }
17127        if (mPendingPssProcesses.size() == 0) {
17128            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17129        }
17130        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17131        proc.pssProcState = procState;
17132        mPendingPssProcesses.add(proc);
17133    }
17134
17135    /**
17136     * Schedule PSS collection of all processes.
17137     */
17138    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17139        if (!always) {
17140            if (now < (mLastFullPssTime +
17141                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17142                return;
17143            }
17144        }
17145        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17146        mLastFullPssTime = now;
17147        mFullPssPending = true;
17148        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17149        mPendingPssProcesses.clear();
17150        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17151            ProcessRecord app = mLruProcesses.get(i);
17152            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17153                app.pssProcState = app.setProcState;
17154                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17155                        isSleeping(), now);
17156                mPendingPssProcesses.add(app);
17157            }
17158        }
17159        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17160    }
17161
17162    /**
17163     * Ask a given process to GC right now.
17164     */
17165    final void performAppGcLocked(ProcessRecord app) {
17166        try {
17167            app.lastRequestedGc = SystemClock.uptimeMillis();
17168            if (app.thread != null) {
17169                if (app.reportLowMemory) {
17170                    app.reportLowMemory = false;
17171                    app.thread.scheduleLowMemory();
17172                } else {
17173                    app.thread.processInBackground();
17174                }
17175            }
17176        } catch (Exception e) {
17177            // whatever.
17178        }
17179    }
17180
17181    /**
17182     * Returns true if things are idle enough to perform GCs.
17183     */
17184    private final boolean canGcNowLocked() {
17185        boolean processingBroadcasts = false;
17186        for (BroadcastQueue q : mBroadcastQueues) {
17187            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17188                processingBroadcasts = true;
17189            }
17190        }
17191        return !processingBroadcasts
17192                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17193    }
17194
17195    /**
17196     * Perform GCs on all processes that are waiting for it, but only
17197     * if things are idle.
17198     */
17199    final void performAppGcsLocked() {
17200        final int N = mProcessesToGc.size();
17201        if (N <= 0) {
17202            return;
17203        }
17204        if (canGcNowLocked()) {
17205            while (mProcessesToGc.size() > 0) {
17206                ProcessRecord proc = mProcessesToGc.remove(0);
17207                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17208                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17209                            <= SystemClock.uptimeMillis()) {
17210                        // To avoid spamming the system, we will GC processes one
17211                        // at a time, waiting a few seconds between each.
17212                        performAppGcLocked(proc);
17213                        scheduleAppGcsLocked();
17214                        return;
17215                    } else {
17216                        // It hasn't been long enough since we last GCed this
17217                        // process...  put it in the list to wait for its time.
17218                        addProcessToGcListLocked(proc);
17219                        break;
17220                    }
17221                }
17222            }
17223
17224            scheduleAppGcsLocked();
17225        }
17226    }
17227
17228    /**
17229     * If all looks good, perform GCs on all processes waiting for them.
17230     */
17231    final void performAppGcsIfAppropriateLocked() {
17232        if (canGcNowLocked()) {
17233            performAppGcsLocked();
17234            return;
17235        }
17236        // Still not idle, wait some more.
17237        scheduleAppGcsLocked();
17238    }
17239
17240    /**
17241     * Schedule the execution of all pending app GCs.
17242     */
17243    final void scheduleAppGcsLocked() {
17244        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17245
17246        if (mProcessesToGc.size() > 0) {
17247            // Schedule a GC for the time to the next process.
17248            ProcessRecord proc = mProcessesToGc.get(0);
17249            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17250
17251            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17252            long now = SystemClock.uptimeMillis();
17253            if (when < (now+GC_TIMEOUT)) {
17254                when = now + GC_TIMEOUT;
17255            }
17256            mHandler.sendMessageAtTime(msg, when);
17257        }
17258    }
17259
17260    /**
17261     * Add a process to the array of processes waiting to be GCed.  Keeps the
17262     * list in sorted order by the last GC time.  The process can't already be
17263     * on the list.
17264     */
17265    final void addProcessToGcListLocked(ProcessRecord proc) {
17266        boolean added = false;
17267        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17268            if (mProcessesToGc.get(i).lastRequestedGc <
17269                    proc.lastRequestedGc) {
17270                added = true;
17271                mProcessesToGc.add(i+1, proc);
17272                break;
17273            }
17274        }
17275        if (!added) {
17276            mProcessesToGc.add(0, proc);
17277        }
17278    }
17279
17280    /**
17281     * Set up to ask a process to GC itself.  This will either do it
17282     * immediately, or put it on the list of processes to gc the next
17283     * time things are idle.
17284     */
17285    final void scheduleAppGcLocked(ProcessRecord app) {
17286        long now = SystemClock.uptimeMillis();
17287        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17288            return;
17289        }
17290        if (!mProcessesToGc.contains(app)) {
17291            addProcessToGcListLocked(app);
17292            scheduleAppGcsLocked();
17293        }
17294    }
17295
17296    final void checkExcessivePowerUsageLocked(boolean doKills) {
17297        updateCpuStatsNow();
17298
17299        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17300        boolean doWakeKills = doKills;
17301        boolean doCpuKills = doKills;
17302        if (mLastPowerCheckRealtime == 0) {
17303            doWakeKills = false;
17304        }
17305        if (mLastPowerCheckUptime == 0) {
17306            doCpuKills = false;
17307        }
17308        if (stats.isScreenOn()) {
17309            doWakeKills = false;
17310        }
17311        final long curRealtime = SystemClock.elapsedRealtime();
17312        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17313        final long curUptime = SystemClock.uptimeMillis();
17314        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17315        mLastPowerCheckRealtime = curRealtime;
17316        mLastPowerCheckUptime = curUptime;
17317        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17318            doWakeKills = false;
17319        }
17320        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17321            doCpuKills = false;
17322        }
17323        int i = mLruProcesses.size();
17324        while (i > 0) {
17325            i--;
17326            ProcessRecord app = mLruProcesses.get(i);
17327            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17328                long wtime;
17329                synchronized (stats) {
17330                    wtime = stats.getProcessWakeTime(app.info.uid,
17331                            app.pid, curRealtime);
17332                }
17333                long wtimeUsed = wtime - app.lastWakeTime;
17334                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17335                if (DEBUG_POWER) {
17336                    StringBuilder sb = new StringBuilder(128);
17337                    sb.append("Wake for ");
17338                    app.toShortString(sb);
17339                    sb.append(": over ");
17340                    TimeUtils.formatDuration(realtimeSince, sb);
17341                    sb.append(" used ");
17342                    TimeUtils.formatDuration(wtimeUsed, sb);
17343                    sb.append(" (");
17344                    sb.append((wtimeUsed*100)/realtimeSince);
17345                    sb.append("%)");
17346                    Slog.i(TAG, sb.toString());
17347                    sb.setLength(0);
17348                    sb.append("CPU for ");
17349                    app.toShortString(sb);
17350                    sb.append(": over ");
17351                    TimeUtils.formatDuration(uptimeSince, sb);
17352                    sb.append(" used ");
17353                    TimeUtils.formatDuration(cputimeUsed, sb);
17354                    sb.append(" (");
17355                    sb.append((cputimeUsed*100)/uptimeSince);
17356                    sb.append("%)");
17357                    Slog.i(TAG, sb.toString());
17358                }
17359                // If a process has held a wake lock for more
17360                // than 50% of the time during this period,
17361                // that sounds bad.  Kill!
17362                if (doWakeKills && realtimeSince > 0
17363                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17364                    synchronized (stats) {
17365                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17366                                realtimeSince, wtimeUsed);
17367                    }
17368                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17369                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17370                } else if (doCpuKills && uptimeSince > 0
17371                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17372                    synchronized (stats) {
17373                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17374                                uptimeSince, cputimeUsed);
17375                    }
17376                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17377                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17378                } else {
17379                    app.lastWakeTime = wtime;
17380                    app.lastCpuTime = app.curCpuTime;
17381                }
17382            }
17383        }
17384    }
17385
17386    private final boolean applyOomAdjLocked(ProcessRecord app,
17387            ProcessRecord TOP_APP, boolean doingAll, long now) {
17388        boolean success = true;
17389
17390        if (app.curRawAdj != app.setRawAdj) {
17391            app.setRawAdj = app.curRawAdj;
17392        }
17393
17394        int changes = 0;
17395
17396        if (app.curAdj != app.setAdj) {
17397            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17398            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17399                TAG, "Set " + app.pid + " " + app.processName +
17400                " adj " + app.curAdj + ": " + app.adjType);
17401            app.setAdj = app.curAdj;
17402        }
17403
17404        if (app.setSchedGroup != app.curSchedGroup) {
17405            app.setSchedGroup = app.curSchedGroup;
17406            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17407                    "Setting process group of " + app.processName
17408                    + " to " + app.curSchedGroup);
17409            if (app.waitingToKill != null &&
17410                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17411                app.kill(app.waitingToKill, true);
17412                success = false;
17413            } else {
17414                if (true) {
17415                    long oldId = Binder.clearCallingIdentity();
17416                    try {
17417                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17418                    } catch (Exception e) {
17419                        Slog.w(TAG, "Failed setting process group of " + app.pid
17420                                + " to " + app.curSchedGroup);
17421                        e.printStackTrace();
17422                    } finally {
17423                        Binder.restoreCallingIdentity(oldId);
17424                    }
17425                } else {
17426                    if (app.thread != null) {
17427                        try {
17428                            app.thread.setSchedulingGroup(app.curSchedGroup);
17429                        } catch (RemoteException e) {
17430                        }
17431                    }
17432                }
17433                Process.setSwappiness(app.pid,
17434                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17435            }
17436        }
17437        if (app.repForegroundActivities != app.foregroundActivities) {
17438            app.repForegroundActivities = app.foregroundActivities;
17439            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17440        }
17441        if (app.repProcState != app.curProcState) {
17442            app.repProcState = app.curProcState;
17443            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17444            if (app.thread != null) {
17445                try {
17446                    if (false) {
17447                        //RuntimeException h = new RuntimeException("here");
17448                        Slog.i(TAG, "Sending new process state " + app.repProcState
17449                                + " to " + app /*, h*/);
17450                    }
17451                    app.thread.setProcessState(app.repProcState);
17452                } catch (RemoteException e) {
17453                }
17454            }
17455        }
17456        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17457                app.setProcState)) {
17458            app.lastStateTime = now;
17459            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17460                    isSleeping(), now);
17461            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17462                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17463                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17464                    + (app.nextPssTime-now) + ": " + app);
17465        } else {
17466            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17467                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17468                requestPssLocked(app, app.setProcState);
17469                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17470                        isSleeping(), now);
17471            } else if (false && DEBUG_PSS) {
17472                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17473            }
17474        }
17475        if (app.setProcState != app.curProcState) {
17476            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17477                    "Proc state change of " + app.processName
17478                    + " to " + app.curProcState);
17479            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17480            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17481            if (setImportant && !curImportant) {
17482                // This app is no longer something we consider important enough to allow to
17483                // use arbitrary amounts of battery power.  Note
17484                // its current wake lock time to later know to kill it if
17485                // it is not behaving well.
17486                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17487                synchronized (stats) {
17488                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17489                            app.pid, SystemClock.elapsedRealtime());
17490                }
17491                app.lastCpuTime = app.curCpuTime;
17492
17493            }
17494            app.setProcState = app.curProcState;
17495            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17496                app.notCachedSinceIdle = false;
17497            }
17498            if (!doingAll) {
17499                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17500            } else {
17501                app.procStateChanged = true;
17502            }
17503        }
17504
17505        if (changes != 0) {
17506            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17507            int i = mPendingProcessChanges.size()-1;
17508            ProcessChangeItem item = null;
17509            while (i >= 0) {
17510                item = mPendingProcessChanges.get(i);
17511                if (item.pid == app.pid) {
17512                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17513                    break;
17514                }
17515                i--;
17516            }
17517            if (i < 0) {
17518                // No existing item in pending changes; need a new one.
17519                final int NA = mAvailProcessChanges.size();
17520                if (NA > 0) {
17521                    item = mAvailProcessChanges.remove(NA-1);
17522                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17523                } else {
17524                    item = new ProcessChangeItem();
17525                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17526                }
17527                item.changes = 0;
17528                item.pid = app.pid;
17529                item.uid = app.info.uid;
17530                if (mPendingProcessChanges.size() == 0) {
17531                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17532                            "*** Enqueueing dispatch processes changed!");
17533                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17534                }
17535                mPendingProcessChanges.add(item);
17536            }
17537            item.changes |= changes;
17538            item.processState = app.repProcState;
17539            item.foregroundActivities = app.repForegroundActivities;
17540            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17541                    + Integer.toHexString(System.identityHashCode(item))
17542                    + " " + app.toShortString() + ": changes=" + item.changes
17543                    + " procState=" + item.processState
17544                    + " foreground=" + item.foregroundActivities
17545                    + " type=" + app.adjType + " source=" + app.adjSource
17546                    + " target=" + app.adjTarget);
17547        }
17548
17549        return success;
17550    }
17551
17552    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17553        if (proc.thread != null) {
17554            if (proc.baseProcessTracker != null) {
17555                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17556            }
17557            if (proc.repProcState >= 0) {
17558                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17559                        proc.repProcState);
17560            }
17561        }
17562    }
17563
17564    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17565            ProcessRecord TOP_APP, boolean doingAll, long now) {
17566        if (app.thread == null) {
17567            return false;
17568        }
17569
17570        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17571
17572        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17573    }
17574
17575    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17576            boolean oomAdj) {
17577        if (isForeground != proc.foregroundServices) {
17578            proc.foregroundServices = isForeground;
17579            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17580                    proc.info.uid);
17581            if (isForeground) {
17582                if (curProcs == null) {
17583                    curProcs = new ArrayList<ProcessRecord>();
17584                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17585                }
17586                if (!curProcs.contains(proc)) {
17587                    curProcs.add(proc);
17588                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17589                            proc.info.packageName, proc.info.uid);
17590                }
17591            } else {
17592                if (curProcs != null) {
17593                    if (curProcs.remove(proc)) {
17594                        mBatteryStatsService.noteEvent(
17595                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17596                                proc.info.packageName, proc.info.uid);
17597                        if (curProcs.size() <= 0) {
17598                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17599                        }
17600                    }
17601                }
17602            }
17603            if (oomAdj) {
17604                updateOomAdjLocked();
17605            }
17606        }
17607    }
17608
17609    private final ActivityRecord resumedAppLocked() {
17610        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17611        String pkg;
17612        int uid;
17613        if (act != null) {
17614            pkg = act.packageName;
17615            uid = act.info.applicationInfo.uid;
17616        } else {
17617            pkg = null;
17618            uid = -1;
17619        }
17620        // Has the UID or resumed package name changed?
17621        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17622                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17623            if (mCurResumedPackage != null) {
17624                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17625                        mCurResumedPackage, mCurResumedUid);
17626            }
17627            mCurResumedPackage = pkg;
17628            mCurResumedUid = uid;
17629            if (mCurResumedPackage != null) {
17630                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17631                        mCurResumedPackage, mCurResumedUid);
17632            }
17633        }
17634        return act;
17635    }
17636
17637    final boolean updateOomAdjLocked(ProcessRecord app) {
17638        final ActivityRecord TOP_ACT = resumedAppLocked();
17639        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17640        final boolean wasCached = app.cached;
17641
17642        mAdjSeq++;
17643
17644        // This is the desired cached adjusment we want to tell it to use.
17645        // If our app is currently cached, we know it, and that is it.  Otherwise,
17646        // we don't know it yet, and it needs to now be cached we will then
17647        // need to do a complete oom adj.
17648        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17649                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17650        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17651                SystemClock.uptimeMillis());
17652        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17653            // Changed to/from cached state, so apps after it in the LRU
17654            // list may also be changed.
17655            updateOomAdjLocked();
17656        }
17657        return success;
17658    }
17659
17660    final void updateOomAdjLocked() {
17661        final ActivityRecord TOP_ACT = resumedAppLocked();
17662        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17663        final long now = SystemClock.uptimeMillis();
17664        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17665        final int N = mLruProcesses.size();
17666
17667        if (false) {
17668            RuntimeException e = new RuntimeException();
17669            e.fillInStackTrace();
17670            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17671        }
17672
17673        mAdjSeq++;
17674        mNewNumServiceProcs = 0;
17675        mNewNumAServiceProcs = 0;
17676
17677        final int emptyProcessLimit;
17678        final int cachedProcessLimit;
17679        if (mProcessLimit <= 0) {
17680            emptyProcessLimit = cachedProcessLimit = 0;
17681        } else if (mProcessLimit == 1) {
17682            emptyProcessLimit = 1;
17683            cachedProcessLimit = 0;
17684        } else {
17685            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17686            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17687        }
17688
17689        // Let's determine how many processes we have running vs.
17690        // how many slots we have for background processes; we may want
17691        // to put multiple processes in a slot of there are enough of
17692        // them.
17693        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17694                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17695        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17696        if (numEmptyProcs > cachedProcessLimit) {
17697            // If there are more empty processes than our limit on cached
17698            // processes, then use the cached process limit for the factor.
17699            // This ensures that the really old empty processes get pushed
17700            // down to the bottom, so if we are running low on memory we will
17701            // have a better chance at keeping around more cached processes
17702            // instead of a gazillion empty processes.
17703            numEmptyProcs = cachedProcessLimit;
17704        }
17705        int emptyFactor = numEmptyProcs/numSlots;
17706        if (emptyFactor < 1) emptyFactor = 1;
17707        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17708        if (cachedFactor < 1) cachedFactor = 1;
17709        int stepCached = 0;
17710        int stepEmpty = 0;
17711        int numCached = 0;
17712        int numEmpty = 0;
17713        int numTrimming = 0;
17714
17715        mNumNonCachedProcs = 0;
17716        mNumCachedHiddenProcs = 0;
17717
17718        // First update the OOM adjustment for each of the
17719        // application processes based on their current state.
17720        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17721        int nextCachedAdj = curCachedAdj+1;
17722        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17723        int nextEmptyAdj = curEmptyAdj+2;
17724        for (int i=N-1; i>=0; i--) {
17725            ProcessRecord app = mLruProcesses.get(i);
17726            if (!app.killedByAm && app.thread != null) {
17727                app.procStateChanged = false;
17728                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17729
17730                // If we haven't yet assigned the final cached adj
17731                // to the process, do that now.
17732                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17733                    switch (app.curProcState) {
17734                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17735                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17736                            // This process is a cached process holding activities...
17737                            // assign it the next cached value for that type, and then
17738                            // step that cached level.
17739                            app.curRawAdj = curCachedAdj;
17740                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17741                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17742                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17743                                    + ")");
17744                            if (curCachedAdj != nextCachedAdj) {
17745                                stepCached++;
17746                                if (stepCached >= cachedFactor) {
17747                                    stepCached = 0;
17748                                    curCachedAdj = nextCachedAdj;
17749                                    nextCachedAdj += 2;
17750                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17751                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17752                                    }
17753                                }
17754                            }
17755                            break;
17756                        default:
17757                            // For everything else, assign next empty cached process
17758                            // level and bump that up.  Note that this means that
17759                            // long-running services that have dropped down to the
17760                            // cached level will be treated as empty (since their process
17761                            // state is still as a service), which is what we want.
17762                            app.curRawAdj = curEmptyAdj;
17763                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17764                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17765                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17766                                    + ")");
17767                            if (curEmptyAdj != nextEmptyAdj) {
17768                                stepEmpty++;
17769                                if (stepEmpty >= emptyFactor) {
17770                                    stepEmpty = 0;
17771                                    curEmptyAdj = nextEmptyAdj;
17772                                    nextEmptyAdj += 2;
17773                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17774                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17775                                    }
17776                                }
17777                            }
17778                            break;
17779                    }
17780                }
17781
17782                applyOomAdjLocked(app, TOP_APP, true, now);
17783
17784                // Count the number of process types.
17785                switch (app.curProcState) {
17786                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17787                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17788                        mNumCachedHiddenProcs++;
17789                        numCached++;
17790                        if (numCached > cachedProcessLimit) {
17791                            app.kill("cached #" + numCached, true);
17792                        }
17793                        break;
17794                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17795                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17796                                && app.lastActivityTime < oldTime) {
17797                            app.kill("empty for "
17798                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17799                                    / 1000) + "s", true);
17800                        } else {
17801                            numEmpty++;
17802                            if (numEmpty > emptyProcessLimit) {
17803                                app.kill("empty #" + numEmpty, true);
17804                            }
17805                        }
17806                        break;
17807                    default:
17808                        mNumNonCachedProcs++;
17809                        break;
17810                }
17811
17812                if (app.isolated && app.services.size() <= 0) {
17813                    // If this is an isolated process, and there are no
17814                    // services running in it, then the process is no longer
17815                    // needed.  We agressively kill these because we can by
17816                    // definition not re-use the same process again, and it is
17817                    // good to avoid having whatever code was running in them
17818                    // left sitting around after no longer needed.
17819                    app.kill("isolated not needed", true);
17820                }
17821
17822                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17823                        && !app.killedByAm) {
17824                    numTrimming++;
17825                }
17826            }
17827        }
17828
17829        mNumServiceProcs = mNewNumServiceProcs;
17830
17831        // Now determine the memory trimming level of background processes.
17832        // Unfortunately we need to start at the back of the list to do this
17833        // properly.  We only do this if the number of background apps we
17834        // are managing to keep around is less than half the maximum we desire;
17835        // if we are keeping a good number around, we'll let them use whatever
17836        // memory they want.
17837        final int numCachedAndEmpty = numCached + numEmpty;
17838        int memFactor;
17839        if (numCached <= ProcessList.TRIM_CACHED_APPS
17840                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17841            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17842                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17843            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17844                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17845            } else {
17846                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17847            }
17848        } else {
17849            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17850        }
17851        // We always allow the memory level to go up (better).  We only allow it to go
17852        // down if we are in a state where that is allowed, *and* the total number of processes
17853        // has gone down since last time.
17854        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17855                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17856                + " last=" + mLastNumProcesses);
17857        if (memFactor > mLastMemoryLevel) {
17858            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17859                memFactor = mLastMemoryLevel;
17860                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17861            }
17862        }
17863        mLastMemoryLevel = memFactor;
17864        mLastNumProcesses = mLruProcesses.size();
17865        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17866        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17867        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17868            if (mLowRamStartTime == 0) {
17869                mLowRamStartTime = now;
17870            }
17871            int step = 0;
17872            int fgTrimLevel;
17873            switch (memFactor) {
17874                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17875                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17876                    break;
17877                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17878                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17879                    break;
17880                default:
17881                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17882                    break;
17883            }
17884            int factor = numTrimming/3;
17885            int minFactor = 2;
17886            if (mHomeProcess != null) minFactor++;
17887            if (mPreviousProcess != null) minFactor++;
17888            if (factor < minFactor) factor = minFactor;
17889            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17890            for (int i=N-1; i>=0; i--) {
17891                ProcessRecord app = mLruProcesses.get(i);
17892                if (allChanged || app.procStateChanged) {
17893                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17894                    app.procStateChanged = false;
17895                }
17896                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17897                        && !app.killedByAm) {
17898                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17899                        try {
17900                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17901                                    "Trimming memory of " + app.processName
17902                                    + " to " + curLevel);
17903                            app.thread.scheduleTrimMemory(curLevel);
17904                        } catch (RemoteException e) {
17905                        }
17906                        if (false) {
17907                            // For now we won't do this; our memory trimming seems
17908                            // to be good enough at this point that destroying
17909                            // activities causes more harm than good.
17910                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17911                                    && app != mHomeProcess && app != mPreviousProcess) {
17912                                // Need to do this on its own message because the stack may not
17913                                // be in a consistent state at this point.
17914                                // For these apps we will also finish their activities
17915                                // to help them free memory.
17916                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17917                            }
17918                        }
17919                    }
17920                    app.trimMemoryLevel = curLevel;
17921                    step++;
17922                    if (step >= factor) {
17923                        step = 0;
17924                        switch (curLevel) {
17925                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17926                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17927                                break;
17928                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17929                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17930                                break;
17931                        }
17932                    }
17933                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17934                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17935                            && app.thread != null) {
17936                        try {
17937                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17938                                    "Trimming memory of heavy-weight " + app.processName
17939                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17940                            app.thread.scheduleTrimMemory(
17941                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17942                        } catch (RemoteException e) {
17943                        }
17944                    }
17945                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17946                } else {
17947                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17948                            || app.systemNoUi) && app.pendingUiClean) {
17949                        // If this application is now in the background and it
17950                        // had done UI, then give it the special trim level to
17951                        // have it free UI resources.
17952                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17953                        if (app.trimMemoryLevel < level && app.thread != null) {
17954                            try {
17955                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17956                                        "Trimming memory of bg-ui " + app.processName
17957                                        + " to " + level);
17958                                app.thread.scheduleTrimMemory(level);
17959                            } catch (RemoteException e) {
17960                            }
17961                        }
17962                        app.pendingUiClean = false;
17963                    }
17964                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17965                        try {
17966                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17967                                    "Trimming memory of fg " + app.processName
17968                                    + " to " + fgTrimLevel);
17969                            app.thread.scheduleTrimMemory(fgTrimLevel);
17970                        } catch (RemoteException e) {
17971                        }
17972                    }
17973                    app.trimMemoryLevel = fgTrimLevel;
17974                }
17975            }
17976        } else {
17977            if (mLowRamStartTime != 0) {
17978                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17979                mLowRamStartTime = 0;
17980            }
17981            for (int i=N-1; i>=0; i--) {
17982                ProcessRecord app = mLruProcesses.get(i);
17983                if (allChanged || app.procStateChanged) {
17984                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17985                    app.procStateChanged = false;
17986                }
17987                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17988                        || app.systemNoUi) && app.pendingUiClean) {
17989                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17990                            && app.thread != null) {
17991                        try {
17992                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17993                                    "Trimming memory of ui hidden " + app.processName
17994                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17995                            app.thread.scheduleTrimMemory(
17996                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17997                        } catch (RemoteException e) {
17998                        }
17999                    }
18000                    app.pendingUiClean = false;
18001                }
18002                app.trimMemoryLevel = 0;
18003            }
18004        }
18005
18006        if (mAlwaysFinishActivities) {
18007            // Need to do this on its own message because the stack may not
18008            // be in a consistent state at this point.
18009            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18010        }
18011
18012        if (allChanged) {
18013            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18014        }
18015
18016        if (mProcessStats.shouldWriteNowLocked(now)) {
18017            mHandler.post(new Runnable() {
18018                @Override public void run() {
18019                    synchronized (ActivityManagerService.this) {
18020                        mProcessStats.writeStateAsyncLocked();
18021                    }
18022                }
18023            });
18024        }
18025
18026        if (DEBUG_OOM_ADJ) {
18027            if (false) {
18028                RuntimeException here = new RuntimeException("here");
18029                here.fillInStackTrace();
18030                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18031            } else {
18032                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18033            }
18034        }
18035    }
18036
18037    final void trimApplications() {
18038        synchronized (this) {
18039            int i;
18040
18041            // First remove any unused application processes whose package
18042            // has been removed.
18043            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18044                final ProcessRecord app = mRemovedProcesses.get(i);
18045                if (app.activities.size() == 0
18046                        && app.curReceiver == null && app.services.size() == 0) {
18047                    Slog.i(
18048                        TAG, "Exiting empty application process "
18049                        + app.processName + " ("
18050                        + (app.thread != null ? app.thread.asBinder() : null)
18051                        + ")\n");
18052                    if (app.pid > 0 && app.pid != MY_PID) {
18053                        app.kill("empty", false);
18054                    } else {
18055                        try {
18056                            app.thread.scheduleExit();
18057                        } catch (Exception e) {
18058                            // Ignore exceptions.
18059                        }
18060                    }
18061                    cleanUpApplicationRecordLocked(app, false, true, -1);
18062                    mRemovedProcesses.remove(i);
18063
18064                    if (app.persistent) {
18065                        addAppLocked(app.info, false, null /* ABI override */);
18066                    }
18067                }
18068            }
18069
18070            // Now update the oom adj for all processes.
18071            updateOomAdjLocked();
18072        }
18073    }
18074
18075    /** This method sends the specified signal to each of the persistent apps */
18076    public void signalPersistentProcesses(int sig) throws RemoteException {
18077        if (sig != Process.SIGNAL_USR1) {
18078            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18079        }
18080
18081        synchronized (this) {
18082            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18083                    != PackageManager.PERMISSION_GRANTED) {
18084                throw new SecurityException("Requires permission "
18085                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18086            }
18087
18088            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18089                ProcessRecord r = mLruProcesses.get(i);
18090                if (r.thread != null && r.persistent) {
18091                    Process.sendSignal(r.pid, sig);
18092                }
18093            }
18094        }
18095    }
18096
18097    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18098        if (proc == null || proc == mProfileProc) {
18099            proc = mProfileProc;
18100            profileType = mProfileType;
18101            clearProfilerLocked();
18102        }
18103        if (proc == null) {
18104            return;
18105        }
18106        try {
18107            proc.thread.profilerControl(false, null, profileType);
18108        } catch (RemoteException e) {
18109            throw new IllegalStateException("Process disappeared");
18110        }
18111    }
18112
18113    private void clearProfilerLocked() {
18114        if (mProfileFd != null) {
18115            try {
18116                mProfileFd.close();
18117            } catch (IOException e) {
18118            }
18119        }
18120        mProfileApp = null;
18121        mProfileProc = null;
18122        mProfileFile = null;
18123        mProfileType = 0;
18124        mAutoStopProfiler = false;
18125        mSamplingInterval = 0;
18126    }
18127
18128    public boolean profileControl(String process, int userId, boolean start,
18129            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18130
18131        try {
18132            synchronized (this) {
18133                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18134                // its own permission.
18135                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18136                        != PackageManager.PERMISSION_GRANTED) {
18137                    throw new SecurityException("Requires permission "
18138                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18139                }
18140
18141                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18142                    throw new IllegalArgumentException("null profile info or fd");
18143                }
18144
18145                ProcessRecord proc = null;
18146                if (process != null) {
18147                    proc = findProcessLocked(process, userId, "profileControl");
18148                }
18149
18150                if (start && (proc == null || proc.thread == null)) {
18151                    throw new IllegalArgumentException("Unknown process: " + process);
18152                }
18153
18154                if (start) {
18155                    stopProfilerLocked(null, 0);
18156                    setProfileApp(proc.info, proc.processName, profilerInfo);
18157                    mProfileProc = proc;
18158                    mProfileType = profileType;
18159                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18160                    try {
18161                        fd = fd.dup();
18162                    } catch (IOException e) {
18163                        fd = null;
18164                    }
18165                    profilerInfo.profileFd = fd;
18166                    proc.thread.profilerControl(start, profilerInfo, profileType);
18167                    fd = null;
18168                    mProfileFd = null;
18169                } else {
18170                    stopProfilerLocked(proc, profileType);
18171                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18172                        try {
18173                            profilerInfo.profileFd.close();
18174                        } catch (IOException e) {
18175                        }
18176                    }
18177                }
18178
18179                return true;
18180            }
18181        } catch (RemoteException e) {
18182            throw new IllegalStateException("Process disappeared");
18183        } finally {
18184            if (profilerInfo != null && profilerInfo.profileFd != null) {
18185                try {
18186                    profilerInfo.profileFd.close();
18187                } catch (IOException e) {
18188                }
18189            }
18190        }
18191    }
18192
18193    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18194        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18195                userId, true, ALLOW_FULL_ONLY, callName, null);
18196        ProcessRecord proc = null;
18197        try {
18198            int pid = Integer.parseInt(process);
18199            synchronized (mPidsSelfLocked) {
18200                proc = mPidsSelfLocked.get(pid);
18201            }
18202        } catch (NumberFormatException e) {
18203        }
18204
18205        if (proc == null) {
18206            ArrayMap<String, SparseArray<ProcessRecord>> all
18207                    = mProcessNames.getMap();
18208            SparseArray<ProcessRecord> procs = all.get(process);
18209            if (procs != null && procs.size() > 0) {
18210                proc = procs.valueAt(0);
18211                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18212                    for (int i=1; i<procs.size(); i++) {
18213                        ProcessRecord thisProc = procs.valueAt(i);
18214                        if (thisProc.userId == userId) {
18215                            proc = thisProc;
18216                            break;
18217                        }
18218                    }
18219                }
18220            }
18221        }
18222
18223        return proc;
18224    }
18225
18226    public boolean dumpHeap(String process, int userId, boolean managed,
18227            String path, ParcelFileDescriptor fd) throws RemoteException {
18228
18229        try {
18230            synchronized (this) {
18231                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18232                // its own permission (same as profileControl).
18233                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18234                        != PackageManager.PERMISSION_GRANTED) {
18235                    throw new SecurityException("Requires permission "
18236                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18237                }
18238
18239                if (fd == null) {
18240                    throw new IllegalArgumentException("null fd");
18241                }
18242
18243                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18244                if (proc == null || proc.thread == null) {
18245                    throw new IllegalArgumentException("Unknown process: " + process);
18246                }
18247
18248                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18249                if (!isDebuggable) {
18250                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18251                        throw new SecurityException("Process not debuggable: " + proc);
18252                    }
18253                }
18254
18255                proc.thread.dumpHeap(managed, path, fd);
18256                fd = null;
18257                return true;
18258            }
18259        } catch (RemoteException e) {
18260            throw new IllegalStateException("Process disappeared");
18261        } finally {
18262            if (fd != null) {
18263                try {
18264                    fd.close();
18265                } catch (IOException e) {
18266                }
18267            }
18268        }
18269    }
18270
18271    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18272    public void monitor() {
18273        synchronized (this) { }
18274    }
18275
18276    void onCoreSettingsChange(Bundle settings) {
18277        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18278            ProcessRecord processRecord = mLruProcesses.get(i);
18279            try {
18280                if (processRecord.thread != null) {
18281                    processRecord.thread.setCoreSettings(settings);
18282                }
18283            } catch (RemoteException re) {
18284                /* ignore */
18285            }
18286        }
18287    }
18288
18289    // Multi-user methods
18290
18291    /**
18292     * Start user, if its not already running, but don't bring it to foreground.
18293     */
18294    @Override
18295    public boolean startUserInBackground(final int userId) {
18296        return startUser(userId, /* foreground */ false);
18297    }
18298
18299    /**
18300     * Start user, if its not already running, and bring it to foreground.
18301     */
18302    boolean startUserInForeground(final int userId, Dialog dlg) {
18303        boolean result = startUser(userId, /* foreground */ true);
18304        dlg.dismiss();
18305        return result;
18306    }
18307
18308    /**
18309     * Refreshes the list of users related to the current user when either a
18310     * user switch happens or when a new related user is started in the
18311     * background.
18312     */
18313    private void updateCurrentProfileIdsLocked() {
18314        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18315                mCurrentUserId, false /* enabledOnly */);
18316        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18317        for (int i = 0; i < currentProfileIds.length; i++) {
18318            currentProfileIds[i] = profiles.get(i).id;
18319        }
18320        mCurrentProfileIds = currentProfileIds;
18321
18322        synchronized (mUserProfileGroupIdsSelfLocked) {
18323            mUserProfileGroupIdsSelfLocked.clear();
18324            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18325            for (int i = 0; i < users.size(); i++) {
18326                UserInfo user = users.get(i);
18327                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18328                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18329                }
18330            }
18331        }
18332    }
18333
18334    private Set getProfileIdsLocked(int userId) {
18335        Set userIds = new HashSet<Integer>();
18336        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18337                userId, false /* enabledOnly */);
18338        for (UserInfo user : profiles) {
18339            userIds.add(Integer.valueOf(user.id));
18340        }
18341        return userIds;
18342    }
18343
18344    @Override
18345    public boolean switchUser(final int userId) {
18346        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18347        String userName;
18348        synchronized (this) {
18349            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18350            if (userInfo == null) {
18351                Slog.w(TAG, "No user info for user #" + userId);
18352                return false;
18353            }
18354            if (userInfo.isManagedProfile()) {
18355                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18356                return false;
18357            }
18358            userName = userInfo.name;
18359            mTargetUserId = userId;
18360        }
18361        mHandler.removeMessages(START_USER_SWITCH_MSG);
18362        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18363        return true;
18364    }
18365
18366    private void showUserSwitchDialog(int userId, String userName) {
18367        // The dialog will show and then initiate the user switch by calling startUserInForeground
18368        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18369                true /* above system */);
18370        d.show();
18371    }
18372
18373    private boolean startUser(final int userId, final boolean foreground) {
18374        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18375                != PackageManager.PERMISSION_GRANTED) {
18376            String msg = "Permission Denial: switchUser() from pid="
18377                    + Binder.getCallingPid()
18378                    + ", uid=" + Binder.getCallingUid()
18379                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18380            Slog.w(TAG, msg);
18381            throw new SecurityException(msg);
18382        }
18383
18384        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18385
18386        final long ident = Binder.clearCallingIdentity();
18387        try {
18388            synchronized (this) {
18389                final int oldUserId = mCurrentUserId;
18390                if (oldUserId == userId) {
18391                    return true;
18392                }
18393
18394                mStackSupervisor.setLockTaskModeLocked(null, false);
18395
18396                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18397                if (userInfo == null) {
18398                    Slog.w(TAG, "No user info for user #" + userId);
18399                    return false;
18400                }
18401                if (foreground && userInfo.isManagedProfile()) {
18402                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18403                    return false;
18404                }
18405
18406                if (foreground) {
18407                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18408                            R.anim.screen_user_enter);
18409                }
18410
18411                boolean needStart = false;
18412
18413                // If the user we are switching to is not currently started, then
18414                // we need to start it now.
18415                if (mStartedUsers.get(userId) == null) {
18416                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18417                    updateStartedUserArrayLocked();
18418                    needStart = true;
18419                }
18420
18421                final Integer userIdInt = Integer.valueOf(userId);
18422                mUserLru.remove(userIdInt);
18423                mUserLru.add(userIdInt);
18424
18425                if (foreground) {
18426                    mCurrentUserId = userId;
18427                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18428                    updateCurrentProfileIdsLocked();
18429                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18430                    // Once the internal notion of the active user has switched, we lock the device
18431                    // with the option to show the user switcher on the keyguard.
18432                    mWindowManager.lockNow(null);
18433                } else {
18434                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18435                    updateCurrentProfileIdsLocked();
18436                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18437                    mUserLru.remove(currentUserIdInt);
18438                    mUserLru.add(currentUserIdInt);
18439                }
18440
18441                final UserStartedState uss = mStartedUsers.get(userId);
18442
18443                // Make sure user is in the started state.  If it is currently
18444                // stopping, we need to knock that off.
18445                if (uss.mState == UserStartedState.STATE_STOPPING) {
18446                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18447                    // so we can just fairly silently bring the user back from
18448                    // the almost-dead.
18449                    uss.mState = UserStartedState.STATE_RUNNING;
18450                    updateStartedUserArrayLocked();
18451                    needStart = true;
18452                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18453                    // This means ACTION_SHUTDOWN has been sent, so we will
18454                    // need to treat this as a new boot of the user.
18455                    uss.mState = UserStartedState.STATE_BOOTING;
18456                    updateStartedUserArrayLocked();
18457                    needStart = true;
18458                }
18459
18460                if (uss.mState == UserStartedState.STATE_BOOTING) {
18461                    // Booting up a new user, need to tell system services about it.
18462                    // Note that this is on the same handler as scheduling of broadcasts,
18463                    // which is important because it needs to go first.
18464                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18465                }
18466
18467                if (foreground) {
18468                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18469                            oldUserId));
18470                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18471                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18472                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18473                            oldUserId, userId, uss));
18474                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18475                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18476                }
18477
18478                if (needStart) {
18479                    // Send USER_STARTED broadcast
18480                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18481                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18482                            | Intent.FLAG_RECEIVER_FOREGROUND);
18483                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18484                    broadcastIntentLocked(null, null, intent,
18485                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18486                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18487                }
18488
18489                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18490                    if (userId != UserHandle.USER_OWNER) {
18491                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18492                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18493                        broadcastIntentLocked(null, null, intent, null,
18494                                new IIntentReceiver.Stub() {
18495                                    public void performReceive(Intent intent, int resultCode,
18496                                            String data, Bundle extras, boolean ordered,
18497                                            boolean sticky, int sendingUser) {
18498                                        onUserInitialized(uss, foreground, oldUserId, userId);
18499                                    }
18500                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18501                                true, false, MY_PID, Process.SYSTEM_UID,
18502                                userId);
18503                        uss.initializing = true;
18504                    } else {
18505                        getUserManagerLocked().makeInitialized(userInfo.id);
18506                    }
18507                }
18508
18509                if (foreground) {
18510                    if (!uss.initializing) {
18511                        moveUserToForeground(uss, oldUserId, userId);
18512                    }
18513                } else {
18514                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18515                }
18516
18517                if (needStart) {
18518                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18519                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18520                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18521                    broadcastIntentLocked(null, null, intent,
18522                            null, new IIntentReceiver.Stub() {
18523                                @Override
18524                                public void performReceive(Intent intent, int resultCode, String data,
18525                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18526                                        throws RemoteException {
18527                                }
18528                            }, 0, null, null,
18529                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18530                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18531                }
18532            }
18533        } finally {
18534            Binder.restoreCallingIdentity(ident);
18535        }
18536
18537        return true;
18538    }
18539
18540    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18541        long ident = Binder.clearCallingIdentity();
18542        try {
18543            Intent intent;
18544            if (oldUserId >= 0) {
18545                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18546                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18547                int count = profiles.size();
18548                for (int i = 0; i < count; i++) {
18549                    int profileUserId = profiles.get(i).id;
18550                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18551                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18552                            | Intent.FLAG_RECEIVER_FOREGROUND);
18553                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18554                    broadcastIntentLocked(null, null, intent,
18555                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18556                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18557                }
18558            }
18559            if (newUserId >= 0) {
18560                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18561                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18562                int count = profiles.size();
18563                for (int i = 0; i < count; i++) {
18564                    int profileUserId = profiles.get(i).id;
18565                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18566                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18567                            | Intent.FLAG_RECEIVER_FOREGROUND);
18568                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18569                    broadcastIntentLocked(null, null, intent,
18570                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18571                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18572                }
18573                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18574                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18575                        | Intent.FLAG_RECEIVER_FOREGROUND);
18576                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18577                broadcastIntentLocked(null, null, intent,
18578                        null, null, 0, null, null,
18579                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18580                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18581            }
18582        } finally {
18583            Binder.restoreCallingIdentity(ident);
18584        }
18585    }
18586
18587    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18588            final int newUserId) {
18589        final int N = mUserSwitchObservers.beginBroadcast();
18590        if (N > 0) {
18591            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18592                int mCount = 0;
18593                @Override
18594                public void sendResult(Bundle data) throws RemoteException {
18595                    synchronized (ActivityManagerService.this) {
18596                        if (mCurUserSwitchCallback == this) {
18597                            mCount++;
18598                            if (mCount == N) {
18599                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18600                            }
18601                        }
18602                    }
18603                }
18604            };
18605            synchronized (this) {
18606                uss.switching = true;
18607                mCurUserSwitchCallback = callback;
18608            }
18609            for (int i=0; i<N; i++) {
18610                try {
18611                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18612                            newUserId, callback);
18613                } catch (RemoteException e) {
18614                }
18615            }
18616        } else {
18617            synchronized (this) {
18618                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18619            }
18620        }
18621        mUserSwitchObservers.finishBroadcast();
18622    }
18623
18624    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18625        synchronized (this) {
18626            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18627            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18628        }
18629    }
18630
18631    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18632        mCurUserSwitchCallback = null;
18633        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18634        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18635                oldUserId, newUserId, uss));
18636    }
18637
18638    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18639        synchronized (this) {
18640            if (foreground) {
18641                moveUserToForeground(uss, oldUserId, newUserId);
18642            }
18643        }
18644
18645        completeSwitchAndInitalize(uss, newUserId, true, false);
18646    }
18647
18648    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18649        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18650        if (homeInFront) {
18651            startHomeActivityLocked(newUserId);
18652        } else {
18653            mStackSupervisor.resumeTopActivitiesLocked();
18654        }
18655        EventLogTags.writeAmSwitchUser(newUserId);
18656        getUserManagerLocked().userForeground(newUserId);
18657        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18658    }
18659
18660    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18661        completeSwitchAndInitalize(uss, newUserId, false, true);
18662    }
18663
18664    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18665            boolean clearInitializing, boolean clearSwitching) {
18666        boolean unfrozen = false;
18667        synchronized (this) {
18668            if (clearInitializing) {
18669                uss.initializing = false;
18670                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18671            }
18672            if (clearSwitching) {
18673                uss.switching = false;
18674            }
18675            if (!uss.switching && !uss.initializing) {
18676                mWindowManager.stopFreezingScreen();
18677                unfrozen = true;
18678            }
18679        }
18680        if (unfrozen) {
18681            final int N = mUserSwitchObservers.beginBroadcast();
18682            for (int i=0; i<N; i++) {
18683                try {
18684                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18685                } catch (RemoteException e) {
18686                }
18687            }
18688            mUserSwitchObservers.finishBroadcast();
18689        }
18690    }
18691
18692    void scheduleStartProfilesLocked() {
18693        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18694            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18695                    DateUtils.SECOND_IN_MILLIS);
18696        }
18697    }
18698
18699    void startProfilesLocked() {
18700        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18701        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18702                mCurrentUserId, false /* enabledOnly */);
18703        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18704        for (UserInfo user : profiles) {
18705            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18706                    && user.id != mCurrentUserId) {
18707                toStart.add(user);
18708            }
18709        }
18710        final int n = toStart.size();
18711        int i = 0;
18712        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18713            startUserInBackground(toStart.get(i).id);
18714        }
18715        if (i < n) {
18716            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18717        }
18718    }
18719
18720    void finishUserBoot(UserStartedState uss) {
18721        synchronized (this) {
18722            if (uss.mState == UserStartedState.STATE_BOOTING
18723                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18724                uss.mState = UserStartedState.STATE_RUNNING;
18725                final int userId = uss.mHandle.getIdentifier();
18726                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18727                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18728                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18729                broadcastIntentLocked(null, null, intent,
18730                        null, null, 0, null, null,
18731                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18732                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18733            }
18734        }
18735    }
18736
18737    void finishUserSwitch(UserStartedState uss) {
18738        synchronized (this) {
18739            finishUserBoot(uss);
18740
18741            startProfilesLocked();
18742
18743            int num = mUserLru.size();
18744            int i = 0;
18745            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18746                Integer oldUserId = mUserLru.get(i);
18747                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18748                if (oldUss == null) {
18749                    // Shouldn't happen, but be sane if it does.
18750                    mUserLru.remove(i);
18751                    num--;
18752                    continue;
18753                }
18754                if (oldUss.mState == UserStartedState.STATE_STOPPING
18755                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18756                    // This user is already stopping, doesn't count.
18757                    num--;
18758                    i++;
18759                    continue;
18760                }
18761                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18762                    // Owner and current can't be stopped, but count as running.
18763                    i++;
18764                    continue;
18765                }
18766                // This is a user to be stopped.
18767                stopUserLocked(oldUserId, null);
18768                num--;
18769                i++;
18770            }
18771        }
18772    }
18773
18774    @Override
18775    public int stopUser(final int userId, final IStopUserCallback callback) {
18776        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18777                != PackageManager.PERMISSION_GRANTED) {
18778            String msg = "Permission Denial: switchUser() from pid="
18779                    + Binder.getCallingPid()
18780                    + ", uid=" + Binder.getCallingUid()
18781                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18782            Slog.w(TAG, msg);
18783            throw new SecurityException(msg);
18784        }
18785        if (userId <= 0) {
18786            throw new IllegalArgumentException("Can't stop primary user " + userId);
18787        }
18788        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18789        synchronized (this) {
18790            return stopUserLocked(userId, callback);
18791        }
18792    }
18793
18794    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18795        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18796        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18797            return ActivityManager.USER_OP_IS_CURRENT;
18798        }
18799
18800        final UserStartedState uss = mStartedUsers.get(userId);
18801        if (uss == null) {
18802            // User is not started, nothing to do...  but we do need to
18803            // callback if requested.
18804            if (callback != null) {
18805                mHandler.post(new Runnable() {
18806                    @Override
18807                    public void run() {
18808                        try {
18809                            callback.userStopped(userId);
18810                        } catch (RemoteException e) {
18811                        }
18812                    }
18813                });
18814            }
18815            return ActivityManager.USER_OP_SUCCESS;
18816        }
18817
18818        if (callback != null) {
18819            uss.mStopCallbacks.add(callback);
18820        }
18821
18822        if (uss.mState != UserStartedState.STATE_STOPPING
18823                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18824            uss.mState = UserStartedState.STATE_STOPPING;
18825            updateStartedUserArrayLocked();
18826
18827            long ident = Binder.clearCallingIdentity();
18828            try {
18829                // We are going to broadcast ACTION_USER_STOPPING and then
18830                // once that is done send a final ACTION_SHUTDOWN and then
18831                // stop the user.
18832                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18833                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18834                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18835                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18836                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18837                // This is the result receiver for the final shutdown broadcast.
18838                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18839                    @Override
18840                    public void performReceive(Intent intent, int resultCode, String data,
18841                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18842                        finishUserStop(uss);
18843                    }
18844                };
18845                // This is the result receiver for the initial stopping broadcast.
18846                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18847                    @Override
18848                    public void performReceive(Intent intent, int resultCode, String data,
18849                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18850                        // On to the next.
18851                        synchronized (ActivityManagerService.this) {
18852                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18853                                // Whoops, we are being started back up.  Abort, abort!
18854                                return;
18855                            }
18856                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18857                        }
18858                        mBatteryStatsService.noteEvent(
18859                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18860                                Integer.toString(userId), userId);
18861                        mSystemServiceManager.stopUser(userId);
18862                        broadcastIntentLocked(null, null, shutdownIntent,
18863                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18864                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18865                    }
18866                };
18867                // Kick things off.
18868                broadcastIntentLocked(null, null, stoppingIntent,
18869                        null, stoppingReceiver, 0, null, null,
18870                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18871                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18872            } finally {
18873                Binder.restoreCallingIdentity(ident);
18874            }
18875        }
18876
18877        return ActivityManager.USER_OP_SUCCESS;
18878    }
18879
18880    void finishUserStop(UserStartedState uss) {
18881        final int userId = uss.mHandle.getIdentifier();
18882        boolean stopped;
18883        ArrayList<IStopUserCallback> callbacks;
18884        synchronized (this) {
18885            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18886            if (mStartedUsers.get(userId) != uss) {
18887                stopped = false;
18888            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18889                stopped = false;
18890            } else {
18891                stopped = true;
18892                // User can no longer run.
18893                mStartedUsers.remove(userId);
18894                mUserLru.remove(Integer.valueOf(userId));
18895                updateStartedUserArrayLocked();
18896
18897                // Clean up all state and processes associated with the user.
18898                // Kill all the processes for the user.
18899                forceStopUserLocked(userId, "finish user");
18900            }
18901
18902            // Explicitly remove the old information in mRecentTasks.
18903            removeRecentTasksForUserLocked(userId);
18904        }
18905
18906        for (int i=0; i<callbacks.size(); i++) {
18907            try {
18908                if (stopped) callbacks.get(i).userStopped(userId);
18909                else callbacks.get(i).userStopAborted(userId);
18910            } catch (RemoteException e) {
18911            }
18912        }
18913
18914        if (stopped) {
18915            mSystemServiceManager.cleanupUser(userId);
18916            synchronized (this) {
18917                mStackSupervisor.removeUserLocked(userId);
18918            }
18919        }
18920    }
18921
18922    @Override
18923    public UserInfo getCurrentUser() {
18924        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18925                != PackageManager.PERMISSION_GRANTED) && (
18926                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18927                != PackageManager.PERMISSION_GRANTED)) {
18928            String msg = "Permission Denial: getCurrentUser() from pid="
18929                    + Binder.getCallingPid()
18930                    + ", uid=" + Binder.getCallingUid()
18931                    + " requires " + INTERACT_ACROSS_USERS;
18932            Slog.w(TAG, msg);
18933            throw new SecurityException(msg);
18934        }
18935        synchronized (this) {
18936            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18937            return getUserManagerLocked().getUserInfo(userId);
18938        }
18939    }
18940
18941    int getCurrentUserIdLocked() {
18942        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18943    }
18944
18945    @Override
18946    public boolean isUserRunning(int userId, boolean orStopped) {
18947        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18948                != PackageManager.PERMISSION_GRANTED) {
18949            String msg = "Permission Denial: isUserRunning() from pid="
18950                    + Binder.getCallingPid()
18951                    + ", uid=" + Binder.getCallingUid()
18952                    + " requires " + INTERACT_ACROSS_USERS;
18953            Slog.w(TAG, msg);
18954            throw new SecurityException(msg);
18955        }
18956        synchronized (this) {
18957            return isUserRunningLocked(userId, orStopped);
18958        }
18959    }
18960
18961    boolean isUserRunningLocked(int userId, boolean orStopped) {
18962        UserStartedState state = mStartedUsers.get(userId);
18963        if (state == null) {
18964            return false;
18965        }
18966        if (orStopped) {
18967            return true;
18968        }
18969        return state.mState != UserStartedState.STATE_STOPPING
18970                && state.mState != UserStartedState.STATE_SHUTDOWN;
18971    }
18972
18973    @Override
18974    public int[] getRunningUserIds() {
18975        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18976                != PackageManager.PERMISSION_GRANTED) {
18977            String msg = "Permission Denial: isUserRunning() from pid="
18978                    + Binder.getCallingPid()
18979                    + ", uid=" + Binder.getCallingUid()
18980                    + " requires " + INTERACT_ACROSS_USERS;
18981            Slog.w(TAG, msg);
18982            throw new SecurityException(msg);
18983        }
18984        synchronized (this) {
18985            return mStartedUserArray;
18986        }
18987    }
18988
18989    private void updateStartedUserArrayLocked() {
18990        int num = 0;
18991        for (int i=0; i<mStartedUsers.size();  i++) {
18992            UserStartedState uss = mStartedUsers.valueAt(i);
18993            // This list does not include stopping users.
18994            if (uss.mState != UserStartedState.STATE_STOPPING
18995                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18996                num++;
18997            }
18998        }
18999        mStartedUserArray = new int[num];
19000        num = 0;
19001        for (int i=0; i<mStartedUsers.size();  i++) {
19002            UserStartedState uss = mStartedUsers.valueAt(i);
19003            if (uss.mState != UserStartedState.STATE_STOPPING
19004                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19005                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19006                num++;
19007            }
19008        }
19009    }
19010
19011    @Override
19012    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19013        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19014                != PackageManager.PERMISSION_GRANTED) {
19015            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19016                    + Binder.getCallingPid()
19017                    + ", uid=" + Binder.getCallingUid()
19018                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19019            Slog.w(TAG, msg);
19020            throw new SecurityException(msg);
19021        }
19022
19023        mUserSwitchObservers.register(observer);
19024    }
19025
19026    @Override
19027    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19028        mUserSwitchObservers.unregister(observer);
19029    }
19030
19031    private boolean userExists(int userId) {
19032        if (userId == 0) {
19033            return true;
19034        }
19035        UserManagerService ums = getUserManagerLocked();
19036        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19037    }
19038
19039    int[] getUsersLocked() {
19040        UserManagerService ums = getUserManagerLocked();
19041        return ums != null ? ums.getUserIds() : new int[] { 0 };
19042    }
19043
19044    UserManagerService getUserManagerLocked() {
19045        if (mUserManager == null) {
19046            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19047            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19048        }
19049        return mUserManager;
19050    }
19051
19052    private int applyUserId(int uid, int userId) {
19053        return UserHandle.getUid(userId, uid);
19054    }
19055
19056    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19057        if (info == null) return null;
19058        ApplicationInfo newInfo = new ApplicationInfo(info);
19059        newInfo.uid = applyUserId(info.uid, userId);
19060        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19061                + info.packageName;
19062        return newInfo;
19063    }
19064
19065    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19066        if (aInfo == null
19067                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19068            return aInfo;
19069        }
19070
19071        ActivityInfo info = new ActivityInfo(aInfo);
19072        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19073        return info;
19074    }
19075
19076    private final class LocalService extends ActivityManagerInternal {
19077        @Override
19078        public void goingToSleep() {
19079            ActivityManagerService.this.goingToSleep();
19080        }
19081
19082        @Override
19083        public void wakingUp() {
19084            ActivityManagerService.this.wakingUp();
19085        }
19086
19087        @Override
19088        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19089                String processName, String abiOverride, int uid, Runnable crashHandler) {
19090            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19091                    processName, abiOverride, uid, crashHandler);
19092        }
19093    }
19094
19095    /**
19096     * An implementation of IAppTask, that allows an app to manage its own tasks via
19097     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19098     * only the process that calls getAppTasks() can call the AppTask methods.
19099     */
19100    class AppTaskImpl extends IAppTask.Stub {
19101        private int mTaskId;
19102        private int mCallingUid;
19103
19104        public AppTaskImpl(int taskId, int callingUid) {
19105            mTaskId = taskId;
19106            mCallingUid = callingUid;
19107        }
19108
19109        private void checkCaller() {
19110            if (mCallingUid != Binder.getCallingUid()) {
19111                throw new SecurityException("Caller " + mCallingUid
19112                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19113            }
19114        }
19115
19116        @Override
19117        public void finishAndRemoveTask() {
19118            checkCaller();
19119
19120            synchronized (ActivityManagerService.this) {
19121                long origId = Binder.clearCallingIdentity();
19122                try {
19123                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19124                    if (tr == null) {
19125                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19126                    }
19127                    // Only kill the process if we are not a new document
19128                    int flags = tr.getBaseIntent().getFlags();
19129                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19130                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19131                    removeTaskByIdLocked(mTaskId,
19132                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19133                } finally {
19134                    Binder.restoreCallingIdentity(origId);
19135                }
19136            }
19137        }
19138
19139        @Override
19140        public ActivityManager.RecentTaskInfo getTaskInfo() {
19141            checkCaller();
19142
19143            synchronized (ActivityManagerService.this) {
19144                long origId = Binder.clearCallingIdentity();
19145                try {
19146                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19147                    if (tr == null) {
19148                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19149                    }
19150                    return createRecentTaskInfoFromTaskRecord(tr);
19151                } finally {
19152                    Binder.restoreCallingIdentity(origId);
19153                }
19154            }
19155        }
19156
19157        @Override
19158        public void moveToFront() {
19159            checkCaller();
19160
19161            final TaskRecord tr;
19162            synchronized (ActivityManagerService.this) {
19163                tr = recentTaskForIdLocked(mTaskId);
19164                if (tr == null) {
19165                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19166                }
19167                if (tr.getRootActivity() != null) {
19168                    moveTaskToFrontLocked(tr.taskId, 0, null);
19169                    return;
19170                }
19171            }
19172
19173            startActivityFromRecentsInner(tr.taskId, null);
19174        }
19175
19176        @Override
19177        public int startActivity(IBinder whoThread, String callingPackage,
19178                Intent intent, String resolvedType, Bundle options) {
19179            checkCaller();
19180
19181            int callingUser = UserHandle.getCallingUserId();
19182            TaskRecord tr;
19183            IApplicationThread appThread;
19184            synchronized (ActivityManagerService.this) {
19185                tr = recentTaskForIdLocked(mTaskId);
19186                if (tr == null) {
19187                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19188                }
19189                appThread = ApplicationThreadNative.asInterface(whoThread);
19190                if (appThread == null) {
19191                    throw new IllegalArgumentException("Bad app thread " + appThread);
19192                }
19193            }
19194            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19195                    resolvedType, null, null, null, null, 0, 0, null, null,
19196                    null, options, callingUser, null, tr);
19197        }
19198
19199        @Override
19200        public void setExcludeFromRecents(boolean exclude) {
19201            checkCaller();
19202
19203            synchronized (ActivityManagerService.this) {
19204                long origId = Binder.clearCallingIdentity();
19205                try {
19206                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19207                    if (tr == null) {
19208                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19209                    }
19210                    Intent intent = tr.getBaseIntent();
19211                    if (exclude) {
19212                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19213                    } else {
19214                        intent.setFlags(intent.getFlags()
19215                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19216                    }
19217                } finally {
19218                    Binder.restoreCallingIdentity(origId);
19219                }
19220            }
19221        }
19222    }
19223}
19224