ActivityManagerService.java revision 8de4311c51229efbe2f2d0afbf298982c5cadd96
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.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageEvents;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
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    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2204        mBatteryStatsService.getActiveStatistics().readLocked();
2205        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2206        mOnBattery = DEBUG_POWER ? true
2207                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2208        mBatteryStatsService.getActiveStatistics().setCallback(this);
2209
2210        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2211
2212        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2213
2214        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2215
2216        // User 0 is the first and only user that runs at boot.
2217        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2218        mUserLru.add(Integer.valueOf(0));
2219        updateStartedUserArrayLocked();
2220
2221        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2222            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2223
2224        mConfiguration.setToDefaults();
2225        mConfiguration.setLocale(Locale.getDefault());
2226
2227        mConfigurationSeq = mConfiguration.seq = 1;
2228        mProcessCpuTracker.init();
2229
2230        mHasRecents = mContext.getResources().getBoolean(
2231                com.android.internal.R.bool.config_hasRecents);
2232
2233        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2234        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2235        mStackSupervisor = new ActivityStackSupervisor(this);
2236        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2237
2238        mProcessCpuThread = new Thread("CpuTracker") {
2239            @Override
2240            public void run() {
2241                while (true) {
2242                    try {
2243                        try {
2244                            synchronized(this) {
2245                                final long now = SystemClock.uptimeMillis();
2246                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2247                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2248                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2249                                //        + ", write delay=" + nextWriteDelay);
2250                                if (nextWriteDelay < nextCpuDelay) {
2251                                    nextCpuDelay = nextWriteDelay;
2252                                }
2253                                if (nextCpuDelay > 0) {
2254                                    mProcessCpuMutexFree.set(true);
2255                                    this.wait(nextCpuDelay);
2256                                }
2257                            }
2258                        } catch (InterruptedException e) {
2259                        }
2260                        updateCpuStatsNow();
2261                    } catch (Exception e) {
2262                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2263                    }
2264                }
2265            }
2266        };
2267
2268        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2269
2270        Watchdog.getInstance().addMonitor(this);
2271        Watchdog.getInstance().addThread(mHandler);
2272    }
2273
2274    public void setSystemServiceManager(SystemServiceManager mgr) {
2275        mSystemServiceManager = mgr;
2276    }
2277
2278    private void start() {
2279        Process.removeAllProcessGroups();
2280        mProcessCpuThread.start();
2281
2282        mBatteryStatsService.publish(mContext);
2283        mAppOpsService.publish(mContext);
2284        Slog.d("AppOps", "AppOpsService published");
2285        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2286    }
2287
2288    public void initPowerManagement() {
2289        mStackSupervisor.initPowerManagement();
2290        mBatteryStatsService.initPowerManagement();
2291    }
2292
2293    @Override
2294    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2295            throws RemoteException {
2296        if (code == SYSPROPS_TRANSACTION) {
2297            // We need to tell all apps about the system property change.
2298            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2299            synchronized(this) {
2300                final int NP = mProcessNames.getMap().size();
2301                for (int ip=0; ip<NP; ip++) {
2302                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2303                    final int NA = apps.size();
2304                    for (int ia=0; ia<NA; ia++) {
2305                        ProcessRecord app = apps.valueAt(ia);
2306                        if (app.thread != null) {
2307                            procs.add(app.thread.asBinder());
2308                        }
2309                    }
2310                }
2311            }
2312
2313            int N = procs.size();
2314            for (int i=0; i<N; i++) {
2315                Parcel data2 = Parcel.obtain();
2316                try {
2317                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2318                } catch (RemoteException e) {
2319                }
2320                data2.recycle();
2321            }
2322        }
2323        try {
2324            return super.onTransact(code, data, reply, flags);
2325        } catch (RuntimeException e) {
2326            // The activity manager only throws security exceptions, so let's
2327            // log all others.
2328            if (!(e instanceof SecurityException)) {
2329                Slog.wtf(TAG, "Activity Manager Crash", e);
2330            }
2331            throw e;
2332        }
2333    }
2334
2335    void updateCpuStats() {
2336        final long now = SystemClock.uptimeMillis();
2337        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2338            return;
2339        }
2340        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2341            synchronized (mProcessCpuThread) {
2342                mProcessCpuThread.notify();
2343            }
2344        }
2345    }
2346
2347    void updateCpuStatsNow() {
2348        synchronized (mProcessCpuThread) {
2349            mProcessCpuMutexFree.set(false);
2350            final long now = SystemClock.uptimeMillis();
2351            boolean haveNewCpuStats = false;
2352
2353            if (MONITOR_CPU_USAGE &&
2354                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2355                mLastCpuTime.set(now);
2356                haveNewCpuStats = true;
2357                mProcessCpuTracker.update();
2358                //Slog.i(TAG, mProcessCpu.printCurrentState());
2359                //Slog.i(TAG, "Total CPU usage: "
2360                //        + mProcessCpu.getTotalCpuPercent() + "%");
2361
2362                // Slog the cpu usage if the property is set.
2363                if ("true".equals(SystemProperties.get("events.cpu"))) {
2364                    int user = mProcessCpuTracker.getLastUserTime();
2365                    int system = mProcessCpuTracker.getLastSystemTime();
2366                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2367                    int irq = mProcessCpuTracker.getLastIrqTime();
2368                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2369                    int idle = mProcessCpuTracker.getLastIdleTime();
2370
2371                    int total = user + system + iowait + irq + softIrq + idle;
2372                    if (total == 0) total = 1;
2373
2374                    EventLog.writeEvent(EventLogTags.CPU,
2375                            ((user+system+iowait+irq+softIrq) * 100) / total,
2376                            (user * 100) / total,
2377                            (system * 100) / total,
2378                            (iowait * 100) / total,
2379                            (irq * 100) / total,
2380                            (softIrq * 100) / total);
2381                }
2382            }
2383
2384            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2385            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2386            synchronized(bstats) {
2387                synchronized(mPidsSelfLocked) {
2388                    if (haveNewCpuStats) {
2389                        if (mOnBattery) {
2390                            int perc = bstats.startAddingCpuLocked();
2391                            int totalUTime = 0;
2392                            int totalSTime = 0;
2393                            final int N = mProcessCpuTracker.countStats();
2394                            for (int i=0; i<N; i++) {
2395                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2396                                if (!st.working) {
2397                                    continue;
2398                                }
2399                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2400                                int otherUTime = (st.rel_utime*perc)/100;
2401                                int otherSTime = (st.rel_stime*perc)/100;
2402                                totalUTime += otherUTime;
2403                                totalSTime += otherSTime;
2404                                if (pr != null) {
2405                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2406                                    if (ps == null || !ps.isActive()) {
2407                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2408                                                pr.info.uid, pr.processName);
2409                                    }
2410                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2411                                            st.rel_stime-otherSTime);
2412                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2413                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2414                                } else {
2415                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2416                                    if (ps == null || !ps.isActive()) {
2417                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2418                                                bstats.mapUid(st.uid), st.name);
2419                                    }
2420                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2421                                            st.rel_stime-otherSTime);
2422                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2423                                }
2424                            }
2425                            bstats.finishAddingCpuLocked(perc, totalUTime,
2426                                    totalSTime, cpuSpeedTimes);
2427                        }
2428                    }
2429                }
2430
2431                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2432                    mLastWriteTime = now;
2433                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2434                }
2435            }
2436        }
2437    }
2438
2439    @Override
2440    public void batteryNeedsCpuUpdate() {
2441        updateCpuStatsNow();
2442    }
2443
2444    @Override
2445    public void batteryPowerChanged(boolean onBattery) {
2446        // When plugging in, update the CPU stats first before changing
2447        // the plug state.
2448        updateCpuStatsNow();
2449        synchronized (this) {
2450            synchronized(mPidsSelfLocked) {
2451                mOnBattery = DEBUG_POWER ? true : onBattery;
2452            }
2453        }
2454    }
2455
2456    /**
2457     * Initialize the application bind args. These are passed to each
2458     * process when the bindApplication() IPC is sent to the process. They're
2459     * lazily setup to make sure the services are running when they're asked for.
2460     */
2461    private HashMap<String, IBinder> getCommonServicesLocked() {
2462        if (mAppBindArgs == null) {
2463            mAppBindArgs = new HashMap<String, IBinder>();
2464
2465            // Setup the application init args
2466            mAppBindArgs.put("package", ServiceManager.getService("package"));
2467            mAppBindArgs.put("window", ServiceManager.getService("window"));
2468            mAppBindArgs.put(Context.ALARM_SERVICE,
2469                    ServiceManager.getService(Context.ALARM_SERVICE));
2470        }
2471        return mAppBindArgs;
2472    }
2473
2474    final void setFocusedActivityLocked(ActivityRecord r) {
2475        if (mFocusedActivity != r) {
2476            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2477            mFocusedActivity = r;
2478            if (r.task != null && r.task.voiceInteractor != null) {
2479                startRunningVoiceLocked();
2480            } else {
2481                finishRunningVoiceLocked();
2482            }
2483            mStackSupervisor.setFocusedStack(r);
2484            if (r != null) {
2485                mWindowManager.setFocusedApp(r.appToken, true);
2486            }
2487            applyUpdateLockStateLocked(r);
2488        }
2489    }
2490
2491    final void clearFocusedActivity(ActivityRecord r) {
2492        if (mFocusedActivity == r) {
2493            mFocusedActivity = null;
2494        }
2495    }
2496
2497    @Override
2498    public void setFocusedStack(int stackId) {
2499        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2500        synchronized (ActivityManagerService.this) {
2501            ActivityStack stack = mStackSupervisor.getStack(stackId);
2502            if (stack != null) {
2503                ActivityRecord r = stack.topRunningActivityLocked(null);
2504                if (r != null) {
2505                    setFocusedActivityLocked(r);
2506                }
2507            }
2508        }
2509    }
2510
2511    @Override
2512    public void notifyActivityDrawn(IBinder token) {
2513        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2514        synchronized (this) {
2515            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2516            if (r != null) {
2517                r.task.stack.notifyActivityDrawnLocked(r);
2518            }
2519        }
2520    }
2521
2522    final void applyUpdateLockStateLocked(ActivityRecord r) {
2523        // Modifications to the UpdateLock state are done on our handler, outside
2524        // the activity manager's locks.  The new state is determined based on the
2525        // state *now* of the relevant activity record.  The object is passed to
2526        // the handler solely for logging detail, not to be consulted/modified.
2527        final boolean nextState = r != null && r.immersive;
2528        mHandler.sendMessage(
2529                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2530    }
2531
2532    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2533        Message msg = Message.obtain();
2534        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2535        msg.obj = r.task.askedCompatMode ? null : r;
2536        mHandler.sendMessage(msg);
2537    }
2538
2539    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2540            String what, Object obj, ProcessRecord srcApp) {
2541        app.lastActivityTime = now;
2542
2543        if (app.activities.size() > 0) {
2544            // Don't want to touch dependent processes that are hosting activities.
2545            return index;
2546        }
2547
2548        int lrui = mLruProcesses.lastIndexOf(app);
2549        if (lrui < 0) {
2550            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2551                    + what + " " + obj + " from " + srcApp);
2552            return index;
2553        }
2554
2555        if (lrui >= index) {
2556            // Don't want to cause this to move dependent processes *back* in the
2557            // list as if they were less frequently used.
2558            return index;
2559        }
2560
2561        if (lrui >= mLruProcessActivityStart) {
2562            // Don't want to touch dependent processes that are hosting activities.
2563            return index;
2564        }
2565
2566        mLruProcesses.remove(lrui);
2567        if (index > 0) {
2568            index--;
2569        }
2570        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2571                + " in LRU list: " + app);
2572        mLruProcesses.add(index, app);
2573        return index;
2574    }
2575
2576    final void removeLruProcessLocked(ProcessRecord app) {
2577        int lrui = mLruProcesses.lastIndexOf(app);
2578        if (lrui >= 0) {
2579            if (lrui <= mLruProcessActivityStart) {
2580                mLruProcessActivityStart--;
2581            }
2582            if (lrui <= mLruProcessServiceStart) {
2583                mLruProcessServiceStart--;
2584            }
2585            mLruProcesses.remove(lrui);
2586        }
2587    }
2588
2589    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2590            ProcessRecord client) {
2591        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2592                || app.treatLikeActivity;
2593        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2594        if (!activityChange && hasActivity) {
2595            // The process has activities, so we are only allowing activity-based adjustments
2596            // to move it.  It should be kept in the front of the list with other
2597            // processes that have activities, and we don't want those to change their
2598            // order except due to activity operations.
2599            return;
2600        }
2601
2602        mLruSeq++;
2603        final long now = SystemClock.uptimeMillis();
2604        app.lastActivityTime = now;
2605
2606        // First a quick reject: if the app is already at the position we will
2607        // put it, then there is nothing to do.
2608        if (hasActivity) {
2609            final int N = mLruProcesses.size();
2610            if (N > 0 && mLruProcesses.get(N-1) == app) {
2611                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2612                return;
2613            }
2614        } else {
2615            if (mLruProcessServiceStart > 0
2616                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2617                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2618                return;
2619            }
2620        }
2621
2622        int lrui = mLruProcesses.lastIndexOf(app);
2623
2624        if (app.persistent && lrui >= 0) {
2625            // We don't care about the position of persistent processes, as long as
2626            // they are in the list.
2627            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2628            return;
2629        }
2630
2631        /* In progress: compute new position first, so we can avoid doing work
2632           if the process is not actually going to move.  Not yet working.
2633        int addIndex;
2634        int nextIndex;
2635        boolean inActivity = false, inService = false;
2636        if (hasActivity) {
2637            // Process has activities, put it at the very tipsy-top.
2638            addIndex = mLruProcesses.size();
2639            nextIndex = mLruProcessServiceStart;
2640            inActivity = true;
2641        } else if (hasService) {
2642            // Process has services, put it at the top of the service list.
2643            addIndex = mLruProcessActivityStart;
2644            nextIndex = mLruProcessServiceStart;
2645            inActivity = true;
2646            inService = true;
2647        } else  {
2648            // Process not otherwise of interest, it goes to the top of the non-service area.
2649            addIndex = mLruProcessServiceStart;
2650            if (client != null) {
2651                int clientIndex = mLruProcesses.lastIndexOf(client);
2652                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2653                        + app);
2654                if (clientIndex >= 0 && addIndex > clientIndex) {
2655                    addIndex = clientIndex;
2656                }
2657            }
2658            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2659        }
2660
2661        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2662                + mLruProcessActivityStart + "): " + app);
2663        */
2664
2665        if (lrui >= 0) {
2666            if (lrui < mLruProcessActivityStart) {
2667                mLruProcessActivityStart--;
2668            }
2669            if (lrui < mLruProcessServiceStart) {
2670                mLruProcessServiceStart--;
2671            }
2672            /*
2673            if (addIndex > lrui) {
2674                addIndex--;
2675            }
2676            if (nextIndex > lrui) {
2677                nextIndex--;
2678            }
2679            */
2680            mLruProcesses.remove(lrui);
2681        }
2682
2683        /*
2684        mLruProcesses.add(addIndex, app);
2685        if (inActivity) {
2686            mLruProcessActivityStart++;
2687        }
2688        if (inService) {
2689            mLruProcessActivityStart++;
2690        }
2691        */
2692
2693        int nextIndex;
2694        if (hasActivity) {
2695            final int N = mLruProcesses.size();
2696            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2697                // Process doesn't have activities, but has clients with
2698                // activities...  move it up, but one below the top (the top
2699                // should always have a real activity).
2700                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2701                mLruProcesses.add(N-1, app);
2702                // To keep it from spamming the LRU list (by making a bunch of clients),
2703                // we will push down any other entries owned by the app.
2704                final int uid = app.info.uid;
2705                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2706                    ProcessRecord subProc = mLruProcesses.get(i);
2707                    if (subProc.info.uid == uid) {
2708                        // We want to push this one down the list.  If the process after
2709                        // it is for the same uid, however, don't do so, because we don't
2710                        // want them internally to be re-ordered.
2711                        if (mLruProcesses.get(i-1).info.uid != uid) {
2712                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2713                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2714                            ProcessRecord tmp = mLruProcesses.get(i);
2715                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2716                            mLruProcesses.set(i-1, tmp);
2717                            i--;
2718                        }
2719                    } else {
2720                        // A gap, we can stop here.
2721                        break;
2722                    }
2723                }
2724            } else {
2725                // Process has activities, put it at the very tipsy-top.
2726                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2727                mLruProcesses.add(app);
2728            }
2729            nextIndex = mLruProcessServiceStart;
2730        } else if (hasService) {
2731            // Process has services, put it at the top of the service list.
2732            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2733            mLruProcesses.add(mLruProcessActivityStart, app);
2734            nextIndex = mLruProcessServiceStart;
2735            mLruProcessActivityStart++;
2736        } else  {
2737            // Process not otherwise of interest, it goes to the top of the non-service area.
2738            int index = mLruProcessServiceStart;
2739            if (client != null) {
2740                // If there is a client, don't allow the process to be moved up higher
2741                // in the list than that client.
2742                int clientIndex = mLruProcesses.lastIndexOf(client);
2743                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2744                        + " when updating " + app);
2745                if (clientIndex <= lrui) {
2746                    // Don't allow the client index restriction to push it down farther in the
2747                    // list than it already is.
2748                    clientIndex = lrui;
2749                }
2750                if (clientIndex >= 0 && index > clientIndex) {
2751                    index = clientIndex;
2752                }
2753            }
2754            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2755            mLruProcesses.add(index, app);
2756            nextIndex = index-1;
2757            mLruProcessActivityStart++;
2758            mLruProcessServiceStart++;
2759        }
2760
2761        // If the app is currently using a content provider or service,
2762        // bump those processes as well.
2763        for (int j=app.connections.size()-1; j>=0; j--) {
2764            ConnectionRecord cr = app.connections.valueAt(j);
2765            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2766                    && cr.binding.service.app != null
2767                    && cr.binding.service.app.lruSeq != mLruSeq
2768                    && !cr.binding.service.app.persistent) {
2769                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2770                        "service connection", cr, app);
2771            }
2772        }
2773        for (int j=app.conProviders.size()-1; j>=0; j--) {
2774            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2775            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2776                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2777                        "provider reference", cpr, app);
2778            }
2779        }
2780    }
2781
2782    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2783        if (uid == Process.SYSTEM_UID) {
2784            // The system gets to run in any process.  If there are multiple
2785            // processes with the same uid, just pick the first (this
2786            // should never happen).
2787            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2788            if (procs == null) return null;
2789            final int N = procs.size();
2790            for (int i = 0; i < N; i++) {
2791                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2792            }
2793        }
2794        ProcessRecord proc = mProcessNames.get(processName, uid);
2795        if (false && proc != null && !keepIfLarge
2796                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2797                && proc.lastCachedPss >= 4000) {
2798            // Turn this condition on to cause killing to happen regularly, for testing.
2799            if (proc.baseProcessTracker != null) {
2800                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2801            }
2802            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2803                    + "k from cached");
2804        } else if (proc != null && !keepIfLarge
2805                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2806                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2807            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2808            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2809                if (proc.baseProcessTracker != null) {
2810                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2811                }
2812                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2813                        + "k from cached");
2814            }
2815        }
2816        return proc;
2817    }
2818
2819    void ensurePackageDexOpt(String packageName) {
2820        IPackageManager pm = AppGlobals.getPackageManager();
2821        try {
2822            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2823                mDidDexOpt = true;
2824            }
2825        } catch (RemoteException e) {
2826        }
2827    }
2828
2829    boolean isNextTransitionForward() {
2830        int transit = mWindowManager.getPendingAppTransition();
2831        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2832                || transit == AppTransition.TRANSIT_TASK_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2834    }
2835
2836    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2837            String processName, String abiOverride, int uid, Runnable crashHandler) {
2838        synchronized(this) {
2839            ApplicationInfo info = new ApplicationInfo();
2840            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2841            // For isolated processes, the former contains the parent's uid and the latter the
2842            // actual uid of the isolated process.
2843            // In the special case introduced by this method (which is, starting an isolated
2844            // process directly from the SystemServer without an actual parent app process) the
2845            // closest thing to a parent's uid is SYSTEM_UID.
2846            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2847            // the |isolated| logic in the ProcessRecord constructor.
2848            info.uid = Process.SYSTEM_UID;
2849            info.processName = processName;
2850            info.className = entryPoint;
2851            info.packageName = "android";
2852            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2853                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2854                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2855                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2856                    crashHandler);
2857            return proc != null ? proc.pid : 0;
2858        }
2859    }
2860
2861    final ProcessRecord startProcessLocked(String processName,
2862            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2863            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2864            boolean isolated, boolean keepIfLarge) {
2865        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2866                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2867                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2868                null /* crashHandler */);
2869    }
2870
2871    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2872            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2873            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2874            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2875        ProcessRecord app;
2876        if (!isolated) {
2877            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2878        } else {
2879            // If this is an isolated process, it can't re-use an existing process.
2880            app = null;
2881        }
2882        // We don't have to do anything more if:
2883        // (1) There is an existing application record; and
2884        // (2) The caller doesn't think it is dead, OR there is no thread
2885        //     object attached to it so we know it couldn't have crashed; and
2886        // (3) There is a pid assigned to it, so it is either starting or
2887        //     already running.
2888        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2889                + " app=" + app + " knownToBeDead=" + knownToBeDead
2890                + " thread=" + (app != null ? app.thread : null)
2891                + " pid=" + (app != null ? app.pid : -1));
2892        if (app != null && app.pid > 0) {
2893            if (!knownToBeDead || app.thread == null) {
2894                // We already have the app running, or are waiting for it to
2895                // come up (we have a pid but not yet its thread), so keep it.
2896                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2897                // If this is a new package in the process, add the package to the list
2898                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899                return app;
2900            }
2901
2902            // An application record is attached to a previous process,
2903            // clean it up now.
2904            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2905            Process.killProcessGroup(app.info.uid, app.pid);
2906            handleAppDiedLocked(app, true, true);
2907        }
2908
2909        String hostingNameStr = hostingName != null
2910                ? hostingName.flattenToShortString() : null;
2911
2912        if (!isolated) {
2913            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2914                // If we are in the background, then check to see if this process
2915                // is bad.  If so, we will just silently fail.
2916                if (mBadProcesses.get(info.processName, info.uid) != null) {
2917                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2918                            + "/" + info.processName);
2919                    return null;
2920                }
2921            } else {
2922                // When the user is explicitly starting a process, then clear its
2923                // crash count so that we won't make it bad until they see at
2924                // least one crash dialog again, and make the process good again
2925                // if it had been bad.
2926                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2927                        + "/" + info.processName);
2928                mProcessCrashTimes.remove(info.processName, info.uid);
2929                if (mBadProcesses.get(info.processName, info.uid) != null) {
2930                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2931                            UserHandle.getUserId(info.uid), info.uid,
2932                            info.processName);
2933                    mBadProcesses.remove(info.processName, info.uid);
2934                    if (app != null) {
2935                        app.bad = false;
2936                    }
2937                }
2938            }
2939        }
2940
2941        if (app == null) {
2942            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2943            app.crashHandler = crashHandler;
2944            if (app == null) {
2945                Slog.w(TAG, "Failed making new process record for "
2946                        + processName + "/" + info.uid + " isolated=" + isolated);
2947                return null;
2948            }
2949            mProcessNames.put(processName, app.uid, app);
2950            if (isolated) {
2951                mIsolatedProcesses.put(app.uid, app);
2952            }
2953        } else {
2954            // If this is a new package in the process, add the package to the list
2955            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2956        }
2957
2958        // If the system is not ready yet, then hold off on starting this
2959        // process until it is.
2960        if (!mProcessesReady
2961                && !isAllowedWhileBooting(info)
2962                && !allowWhileBooting) {
2963            if (!mProcessesOnHold.contains(app)) {
2964                mProcessesOnHold.add(app);
2965            }
2966            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2967            return app;
2968        }
2969
2970        startProcessLocked(
2971                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2972        return (app.pid != 0) ? app : null;
2973    }
2974
2975    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2976        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2977    }
2978
2979    private final void startProcessLocked(ProcessRecord app,
2980            String hostingType, String hostingNameStr) {
2981        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2982                null /* entryPoint */, null /* entryPointArgs */);
2983    }
2984
2985    private final void startProcessLocked(ProcessRecord app, String hostingType,
2986            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2987        if (app.pid > 0 && app.pid != MY_PID) {
2988            synchronized (mPidsSelfLocked) {
2989                mPidsSelfLocked.remove(app.pid);
2990                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2991            }
2992            app.setPid(0);
2993        }
2994
2995        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2996                "startProcessLocked removing on hold: " + app);
2997        mProcessesOnHold.remove(app);
2998
2999        updateCpuStats();
3000
3001        try {
3002            int uid = app.uid;
3003
3004            int[] gids = null;
3005            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3006            if (!app.isolated) {
3007                int[] permGids = null;
3008                try {
3009                    final PackageManager pm = mContext.getPackageManager();
3010                    permGids = pm.getPackageGids(app.info.packageName);
3011
3012                    if (Environment.isExternalStorageEmulated()) {
3013                        if (pm.checkPermission(
3014                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3015                                app.info.packageName) == PERMISSION_GRANTED) {
3016                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3017                        } else {
3018                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3019                        }
3020                    }
3021                } catch (PackageManager.NameNotFoundException e) {
3022                    Slog.w(TAG, "Unable to retrieve gids", e);
3023                }
3024
3025                /*
3026                 * Add shared application and profile GIDs so applications can share some
3027                 * resources like shared libraries and access user-wide resources
3028                 */
3029                if (permGids == null) {
3030                    gids = new int[2];
3031                } else {
3032                    gids = new int[permGids.length + 2];
3033                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3034                }
3035                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3036                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3037            }
3038            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3039                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3040                        && mTopComponent != null
3041                        && app.processName.equals(mTopComponent.getPackageName())) {
3042                    uid = 0;
3043                }
3044                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3045                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3046                    uid = 0;
3047                }
3048            }
3049            int debugFlags = 0;
3050            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3051                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3052                // Also turn on CheckJNI for debuggable apps. It's quite
3053                // awkward to turn on otherwise.
3054                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3055            }
3056            // Run the app in safe mode if its manifest requests so or the
3057            // system is booted in safe mode.
3058            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3059                mSafeMode == true) {
3060                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3061            }
3062            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3063                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3064            }
3065            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3066                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3067            }
3068            if ("1".equals(SystemProperties.get("debug.assert"))) {
3069                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3070            }
3071
3072            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3073            if (requiredAbi == null) {
3074                requiredAbi = Build.SUPPORTED_ABIS[0];
3075            }
3076
3077            // Start the process.  It will either succeed and return a result containing
3078            // the PID of the new process, or else throw a RuntimeException.
3079            boolean isActivityProcess = (entryPoint == null);
3080            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3081            Process.ProcessStartResult startResult = Process.start(entryPoint,
3082                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3083                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3084
3085            if (app.isolated) {
3086                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3087            }
3088            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3089
3090            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3091                    UserHandle.getUserId(uid), startResult.pid, uid,
3092                    app.processName, hostingType,
3093                    hostingNameStr != null ? hostingNameStr : "");
3094
3095            if (app.persistent) {
3096                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3097            }
3098
3099            StringBuilder buf = mStringBuilder;
3100            buf.setLength(0);
3101            buf.append("Start proc ");
3102            buf.append(app.processName);
3103            if (!isActivityProcess) {
3104                buf.append(" [");
3105                buf.append(entryPoint);
3106                buf.append("]");
3107            }
3108            buf.append(" for ");
3109            buf.append(hostingType);
3110            if (hostingNameStr != null) {
3111                buf.append(" ");
3112                buf.append(hostingNameStr);
3113            }
3114            buf.append(": pid=");
3115            buf.append(startResult.pid);
3116            buf.append(" uid=");
3117            buf.append(uid);
3118            buf.append(" gids={");
3119            if (gids != null) {
3120                for (int gi=0; gi<gids.length; gi++) {
3121                    if (gi != 0) buf.append(", ");
3122                    buf.append(gids[gi]);
3123
3124                }
3125            }
3126            buf.append("}");
3127            if (requiredAbi != null) {
3128                buf.append(" abi=");
3129                buf.append(requiredAbi);
3130            }
3131            Slog.i(TAG, buf.toString());
3132            app.setPid(startResult.pid);
3133            app.usingWrapper = startResult.usingWrapper;
3134            app.removed = false;
3135            app.killedByAm = false;
3136            synchronized (mPidsSelfLocked) {
3137                this.mPidsSelfLocked.put(startResult.pid, app);
3138                if (isActivityProcess) {
3139                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3140                    msg.obj = app;
3141                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3142                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3143                }
3144            }
3145        } catch (RuntimeException e) {
3146            // XXX do better error recovery.
3147            app.setPid(0);
3148            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3149            if (app.isolated) {
3150                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3151            }
3152            Slog.e(TAG, "Failure starting process " + app.processName, e);
3153        }
3154    }
3155
3156    void updateUsageStats(ActivityRecord component, boolean resumed) {
3157        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3158        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3159        if (resumed) {
3160            if (mUsageStatsService != null) {
3161                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3162                        System.currentTimeMillis(),
3163                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3164            }
3165            synchronized (stats) {
3166                stats.noteActivityResumedLocked(component.app.uid);
3167            }
3168        } else {
3169            if (mUsageStatsService != null) {
3170                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3171                        System.currentTimeMillis(),
3172                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3173            }
3174            synchronized (stats) {
3175                stats.noteActivityPausedLocked(component.app.uid);
3176            }
3177        }
3178    }
3179
3180    Intent getHomeIntent() {
3181        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3182        intent.setComponent(mTopComponent);
3183        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3184            intent.addCategory(Intent.CATEGORY_HOME);
3185        }
3186        return intent;
3187    }
3188
3189    boolean startHomeActivityLocked(int userId) {
3190        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3191                && mTopAction == null) {
3192            // We are running in factory test mode, but unable to find
3193            // the factory test app, so just sit around displaying the
3194            // error message and don't try to start anything.
3195            return false;
3196        }
3197        Intent intent = getHomeIntent();
3198        ActivityInfo aInfo =
3199            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3200        if (aInfo != null) {
3201            intent.setComponent(new ComponentName(
3202                    aInfo.applicationInfo.packageName, aInfo.name));
3203            // Don't do this if the home app is currently being
3204            // instrumented.
3205            aInfo = new ActivityInfo(aInfo);
3206            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3207            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3208                    aInfo.applicationInfo.uid, true);
3209            if (app == null || app.instrumentationClass == null) {
3210                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3211                mStackSupervisor.startHomeActivity(intent, aInfo);
3212            }
3213        }
3214
3215        return true;
3216    }
3217
3218    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3219        ActivityInfo ai = null;
3220        ComponentName comp = intent.getComponent();
3221        try {
3222            if (comp != null) {
3223                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3224            } else {
3225                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3226                        intent,
3227                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3228                            flags, userId);
3229
3230                if (info != null) {
3231                    ai = info.activityInfo;
3232                }
3233            }
3234        } catch (RemoteException e) {
3235            // ignore
3236        }
3237
3238        return ai;
3239    }
3240
3241    /**
3242     * Starts the "new version setup screen" if appropriate.
3243     */
3244    void startSetupActivityLocked() {
3245        // Only do this once per boot.
3246        if (mCheckedForSetup) {
3247            return;
3248        }
3249
3250        // We will show this screen if the current one is a different
3251        // version than the last one shown, and we are not running in
3252        // low-level factory test mode.
3253        final ContentResolver resolver = mContext.getContentResolver();
3254        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3255                Settings.Global.getInt(resolver,
3256                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3257            mCheckedForSetup = true;
3258
3259            // See if we should be showing the platform update setup UI.
3260            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3261            List<ResolveInfo> ris = mContext.getPackageManager()
3262                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3263
3264            // We don't allow third party apps to replace this.
3265            ResolveInfo ri = null;
3266            for (int i=0; ris != null && i<ris.size(); i++) {
3267                if ((ris.get(i).activityInfo.applicationInfo.flags
3268                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3269                    ri = ris.get(i);
3270                    break;
3271                }
3272            }
3273
3274            if (ri != null) {
3275                String vers = ri.activityInfo.metaData != null
3276                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3277                        : null;
3278                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3279                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3280                            Intent.METADATA_SETUP_VERSION);
3281                }
3282                String lastVers = Settings.Secure.getString(
3283                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3284                if (vers != null && !vers.equals(lastVers)) {
3285                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3286                    intent.setComponent(new ComponentName(
3287                            ri.activityInfo.packageName, ri.activityInfo.name));
3288                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3289                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3290                }
3291            }
3292        }
3293    }
3294
3295    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3296        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3297    }
3298
3299    void enforceNotIsolatedCaller(String caller) {
3300        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3301            throw new SecurityException("Isolated process not allowed to call " + caller);
3302        }
3303    }
3304
3305    @Override
3306    public int getFrontActivityScreenCompatMode() {
3307        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3308        synchronized (this) {
3309            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3310        }
3311    }
3312
3313    @Override
3314    public void setFrontActivityScreenCompatMode(int mode) {
3315        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3316                "setFrontActivityScreenCompatMode");
3317        synchronized (this) {
3318            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3319        }
3320    }
3321
3322    @Override
3323    public int getPackageScreenCompatMode(String packageName) {
3324        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3325        synchronized (this) {
3326            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3327        }
3328    }
3329
3330    @Override
3331    public void setPackageScreenCompatMode(String packageName, int mode) {
3332        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3333                "setPackageScreenCompatMode");
3334        synchronized (this) {
3335            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3336        }
3337    }
3338
3339    @Override
3340    public boolean getPackageAskScreenCompat(String packageName) {
3341        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3342        synchronized (this) {
3343            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3344        }
3345    }
3346
3347    @Override
3348    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3349        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3350                "setPackageAskScreenCompat");
3351        synchronized (this) {
3352            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3353        }
3354    }
3355
3356    private void dispatchProcessesChanged() {
3357        int N;
3358        synchronized (this) {
3359            N = mPendingProcessChanges.size();
3360            if (mActiveProcessChanges.length < N) {
3361                mActiveProcessChanges = new ProcessChangeItem[N];
3362            }
3363            mPendingProcessChanges.toArray(mActiveProcessChanges);
3364            mAvailProcessChanges.addAll(mPendingProcessChanges);
3365            mPendingProcessChanges.clear();
3366            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3367        }
3368
3369        int i = mProcessObservers.beginBroadcast();
3370        while (i > 0) {
3371            i--;
3372            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3373            if (observer != null) {
3374                try {
3375                    for (int j=0; j<N; j++) {
3376                        ProcessChangeItem item = mActiveProcessChanges[j];
3377                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3378                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3379                                    + item.pid + " uid=" + item.uid + ": "
3380                                    + item.foregroundActivities);
3381                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3382                                    item.foregroundActivities);
3383                        }
3384                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3385                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3386                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3387                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3388                        }
3389                    }
3390                } catch (RemoteException e) {
3391                }
3392            }
3393        }
3394        mProcessObservers.finishBroadcast();
3395    }
3396
3397    private void dispatchProcessDied(int pid, int uid) {
3398        int i = mProcessObservers.beginBroadcast();
3399        while (i > 0) {
3400            i--;
3401            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3402            if (observer != null) {
3403                try {
3404                    observer.onProcessDied(pid, uid);
3405                } catch (RemoteException e) {
3406                }
3407            }
3408        }
3409        mProcessObservers.finishBroadcast();
3410    }
3411
3412    @Override
3413    public final int startActivity(IApplicationThread caller, String callingPackage,
3414            Intent intent, String resolvedType, IBinder resultTo,
3415            String resultWho, int requestCode, int startFlags,
3416            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3417        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3418                resultWho, requestCode,
3419                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3420    }
3421
3422    @Override
3423    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3424            Intent intent, String resolvedType, IBinder resultTo,
3425            String resultWho, int requestCode, int startFlags,
3426            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivity");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivity", null);
3430        // TODO: Switch to user app stacks here.
3431        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3432                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3433                null, null, options, userId, null);
3434    }
3435
3436    @Override
3437    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo,
3439            String resultWho, int requestCode, int startFlags, String profileFile,
3440            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3441        enforceNotIsolatedCaller("startActivityAndWait");
3442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3443                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3444        WaitResult res = new WaitResult();
3445        // TODO: Switch to user app stacks here.
3446        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3447                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3448                res, null, options, userId, null);
3449        return res;
3450    }
3451
3452    @Override
3453    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo,
3455            String resultWho, int requestCode, int startFlags, Configuration config,
3456            Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivityWithConfig");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3460        // TODO: Switch to user app stacks here.
3461        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3462                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3463                null, null, null, config, options, userId, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startActivityIntentSender(IApplicationThread caller,
3469            IntentSender intent, Intent fillInIntent, String resolvedType,
3470            IBinder resultTo, String resultWho, int requestCode,
3471            int flagsMask, int flagsValues, Bundle options) {
3472        enforceNotIsolatedCaller("startActivityIntentSender");
3473        // Refuse possible leaked file descriptors
3474        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3475            throw new IllegalArgumentException("File descriptors passed in Intent");
3476        }
3477
3478        IIntentSender sender = intent.getTarget();
3479        if (!(sender instanceof PendingIntentRecord)) {
3480            throw new IllegalArgumentException("Bad PendingIntent object");
3481        }
3482
3483        PendingIntentRecord pir = (PendingIntentRecord)sender;
3484
3485        synchronized (this) {
3486            // If this is coming from the currently resumed activity, it is
3487            // effectively saying that app switches are allowed at this point.
3488            final ActivityStack stack = getFocusedStack();
3489            if (stack.mResumedActivity != null &&
3490                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3491                mAppSwitchesAllowedTime = 0;
3492            }
3493        }
3494        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3495                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3496        return ret;
3497    }
3498
3499    @Override
3500    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3501            Intent intent, String resolvedType, IVoiceInteractionSession session,
3502            IVoiceInteractor interactor, int startFlags, String profileFile,
3503            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3504        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3505                != PackageManager.PERMISSION_GRANTED) {
3506            String msg = "Permission Denial: startVoiceActivity() from pid="
3507                    + Binder.getCallingPid()
3508                    + ", uid=" + Binder.getCallingUid()
3509                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3510            Slog.w(TAG, msg);
3511            throw new SecurityException(msg);
3512        }
3513        if (session == null || interactor == null) {
3514            throw new NullPointerException("null session or interactor");
3515        }
3516        userId = handleIncomingUser(callingPid, callingUid, userId,
3517                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3518        // TODO: Switch to user app stacks here.
3519        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3520                resolvedType, session, interactor, null, null, 0, startFlags,
3521                profileFile, profileFd, null, null, options, userId, null);
3522    }
3523
3524    @Override
3525    public boolean startNextMatchingActivity(IBinder callingActivity,
3526            Intent intent, Bundle options) {
3527        // Refuse possible leaked file descriptors
3528        if (intent != null && intent.hasFileDescriptors() == true) {
3529            throw new IllegalArgumentException("File descriptors passed in Intent");
3530        }
3531
3532        synchronized (this) {
3533            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3534            if (r == null) {
3535                ActivityOptions.abort(options);
3536                return false;
3537            }
3538            if (r.app == null || r.app.thread == null) {
3539                // The caller is not running...  d'oh!
3540                ActivityOptions.abort(options);
3541                return false;
3542            }
3543            intent = new Intent(intent);
3544            // The caller is not allowed to change the data.
3545            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3546            // And we are resetting to find the next component...
3547            intent.setComponent(null);
3548
3549            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3550
3551            ActivityInfo aInfo = null;
3552            try {
3553                List<ResolveInfo> resolves =
3554                    AppGlobals.getPackageManager().queryIntentActivities(
3555                            intent, r.resolvedType,
3556                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3557                            UserHandle.getCallingUserId());
3558
3559                // Look for the original activity in the list...
3560                final int N = resolves != null ? resolves.size() : 0;
3561                for (int i=0; i<N; i++) {
3562                    ResolveInfo rInfo = resolves.get(i);
3563                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3564                            && rInfo.activityInfo.name.equals(r.info.name)) {
3565                        // We found the current one...  the next matching is
3566                        // after it.
3567                        i++;
3568                        if (i<N) {
3569                            aInfo = resolves.get(i).activityInfo;
3570                        }
3571                        if (debug) {
3572                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3573                                    + "/" + r.info.name);
3574                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3575                                    + "/" + aInfo.name);
3576                        }
3577                        break;
3578                    }
3579                }
3580            } catch (RemoteException e) {
3581            }
3582
3583            if (aInfo == null) {
3584                // Nobody who is next!
3585                ActivityOptions.abort(options);
3586                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3587                return false;
3588            }
3589
3590            intent.setComponent(new ComponentName(
3591                    aInfo.applicationInfo.packageName, aInfo.name));
3592            intent.setFlags(intent.getFlags()&~(
3593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3596                    Intent.FLAG_ACTIVITY_NEW_TASK));
3597
3598            // Okay now we need to start the new activity, replacing the
3599            // currently running activity.  This is a little tricky because
3600            // we want to start the new one as if the current one is finished,
3601            // but not finish the current one first so that there is no flicker.
3602            // And thus...
3603            final boolean wasFinishing = r.finishing;
3604            r.finishing = true;
3605
3606            // Propagate reply information over to the new activity.
3607            final ActivityRecord resultTo = r.resultTo;
3608            final String resultWho = r.resultWho;
3609            final int requestCode = r.requestCode;
3610            r.resultTo = null;
3611            if (resultTo != null) {
3612                resultTo.removeResultsLocked(r, resultWho, requestCode);
3613            }
3614
3615            final long origId = Binder.clearCallingIdentity();
3616            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3617                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3618                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3619                    options, false, null, null);
3620            Binder.restoreCallingIdentity(origId);
3621
3622            r.finishing = wasFinishing;
3623            if (res != ActivityManager.START_SUCCESS) {
3624                return false;
3625            }
3626            return true;
3627        }
3628    }
3629
3630    @Override
3631    public final int startActivityFromRecents(int taskId, Bundle options) {
3632        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3633            String msg = "Permission Denial: startActivityFromRecents called without " +
3634                    START_TASKS_FROM_RECENTS;
3635            Slog.w(TAG, msg);
3636            throw new SecurityException(msg);
3637        }
3638        final int callingUid;
3639        final String callingPackage;
3640        final Intent intent;
3641        final int userId;
3642        synchronized (this) {
3643            final TaskRecord task = recentTaskForIdLocked(taskId);
3644            if (task == null) {
3645                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3646            }
3647            callingUid = task.mCallingUid;
3648            callingPackage = task.mCallingPackage;
3649            intent = task.intent;
3650            userId = task.userId;
3651        }
3652        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3653                options, userId, null);
3654    }
3655
3656    final int startActivityInPackage(int uid, String callingPackage,
3657            Intent intent, String resolvedType, IBinder resultTo,
3658            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3659                    IActivityContainer container) {
3660
3661        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3662                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3663
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3666                null, null, resultTo, resultWho, requestCode, startFlags,
3667                null, null, null, null, options, userId, container);
3668        return ret;
3669    }
3670
3671    @Override
3672    public final int startActivities(IApplicationThread caller, String callingPackage,
3673            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3674            int userId) {
3675        enforceNotIsolatedCaller("startActivities");
3676        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3677                false, ALLOW_FULL_ONLY, "startActivity", null);
3678        // TODO: Switch to user app stacks here.
3679        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3680                resolvedTypes, resultTo, options, userId);
3681        return ret;
3682    }
3683
3684    final int startActivitiesInPackage(int uid, String callingPackage,
3685            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3686            Bundle options, int userId) {
3687
3688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3689                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3690        // TODO: Switch to user app stacks here.
3691        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3692                resultTo, options, userId);
3693        return ret;
3694    }
3695
3696    //explicitly remove thd old information in mRecentTasks when removing existing user.
3697    private void removeRecentTasksForUserLocked(int userId) {
3698        if(userId <= 0) {
3699            Slog.i(TAG, "Can't remove recent task on user " + userId);
3700            return;
3701        }
3702
3703        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3704            TaskRecord tr = mRecentTasks.get(i);
3705            if (tr.userId == userId) {
3706                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3707                        + " when finishing user" + userId);
3708                tr.disposeThumbnail();
3709                mRecentTasks.remove(i);
3710            }
3711        }
3712
3713        // Remove tasks from persistent storage.
3714        mTaskPersister.wakeup(null, true);
3715    }
3716
3717    final void addRecentTaskLocked(TaskRecord task) {
3718        int N = mRecentTasks.size();
3719        // Quick case: check if the top-most recent task is the same.
3720        if (N > 0 && mRecentTasks.get(0) == task) {
3721            return;
3722        }
3723        // Another quick case: never add voice sessions.
3724        if (task.voiceSession != null) {
3725            return;
3726        }
3727        // Remove any existing entries that are the same kind of task.
3728        final Intent intent = task.intent;
3729        final boolean document = intent != null && intent.isDocument();
3730        final ComponentName comp = intent.getComponent();
3731
3732        int maxRecents = task.maxRecents - 1;
3733        for (int i=0; i<N; i++) {
3734            final TaskRecord tr = mRecentTasks.get(i);
3735            if (task != tr) {
3736                if (task.userId != tr.userId) {
3737                    continue;
3738                }
3739                if (i > MAX_RECENT_BITMAPS) {
3740                    tr.freeLastThumbnail();
3741                }
3742                final Intent trIntent = tr.intent;
3743                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3744                    (intent == null || !intent.filterEquals(trIntent))) {
3745                    continue;
3746                }
3747                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3748                if (document && trIsDocument) {
3749                    // These are the same document activity (not necessarily the same doc).
3750                    if (maxRecents > 0) {
3751                        --maxRecents;
3752                        continue;
3753                    }
3754                    // Hit the maximum number of documents for this task. Fall through
3755                    // and remove this document from recents.
3756                } else if (document || trIsDocument) {
3757                    // Only one of these is a document. Not the droid we're looking for.
3758                    continue;
3759                }
3760            }
3761
3762            // Either task and tr are the same or, their affinities match or their intents match
3763            // and neither of them is a document, or they are documents using the same activity
3764            // and their maxRecents has been reached.
3765            tr.disposeThumbnail();
3766            mRecentTasks.remove(i);
3767            if (task != tr) {
3768                tr.closeRecentsChain();
3769            }
3770            i--;
3771            N--;
3772            if (task.intent == null) {
3773                // If the new recent task we are adding is not fully
3774                // specified, then replace it with the existing recent task.
3775                task = tr;
3776            }
3777            notifyTaskPersisterLocked(tr, false);
3778        }
3779        if (N >= MAX_RECENT_TASKS) {
3780            final TaskRecord tr = mRecentTasks.remove(N - 1);
3781            tr.disposeThumbnail();
3782            tr.closeRecentsChain();
3783        }
3784        mRecentTasks.add(0, task);
3785    }
3786
3787    @Override
3788    public void reportActivityFullyDrawn(IBinder token) {
3789        synchronized (this) {
3790            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3791            if (r == null) {
3792                return;
3793            }
3794            r.reportFullyDrawnLocked();
3795        }
3796    }
3797
3798    @Override
3799    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3800        synchronized (this) {
3801            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3802            if (r == null) {
3803                return;
3804            }
3805            final long origId = Binder.clearCallingIdentity();
3806            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3807            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3808                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3809            if (config != null) {
3810                r.frozenBeforeDestroy = true;
3811                if (!updateConfigurationLocked(config, r, false, false)) {
3812                    mStackSupervisor.resumeTopActivitiesLocked();
3813                }
3814            }
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    @Override
3820    public int getRequestedOrientation(IBinder token) {
3821        synchronized (this) {
3822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3823            if (r == null) {
3824                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3825            }
3826            return mWindowManager.getAppOrientation(r.appToken);
3827        }
3828    }
3829
3830    /**
3831     * This is the internal entry point for handling Activity.finish().
3832     *
3833     * @param token The Binder token referencing the Activity we want to finish.
3834     * @param resultCode Result code, if any, from this Activity.
3835     * @param resultData Result data (Intent), if any, from this Activity.
3836     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3837     *            the root Activity in the task.
3838     *
3839     * @return Returns true if the activity successfully finished, or false if it is still running.
3840     */
3841    @Override
3842    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3843            boolean finishTask) {
3844        // Refuse possible leaked file descriptors
3845        if (resultData != null && resultData.hasFileDescriptors() == true) {
3846            throw new IllegalArgumentException("File descriptors passed in Intent");
3847        }
3848
3849        synchronized(this) {
3850            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3851            if (r == null) {
3852                return true;
3853            }
3854            // Keep track of the root activity of the task before we finish it
3855            TaskRecord tr = r.task;
3856            ActivityRecord rootR = tr.getRootActivity();
3857            // Do not allow task to finish in Lock Task mode.
3858            if (tr == mStackSupervisor.mLockTaskModeTask) {
3859                if (rootR == r) {
3860                    mStackSupervisor.showLockTaskToast();
3861                    return false;
3862                }
3863            }
3864            if (mController != null) {
3865                // Find the first activity that is not finishing.
3866                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3867                if (next != null) {
3868                    // ask watcher if this is allowed
3869                    boolean resumeOK = true;
3870                    try {
3871                        resumeOK = mController.activityResuming(next.packageName);
3872                    } catch (RemoteException e) {
3873                        mController = null;
3874                        Watchdog.getInstance().setActivityController(null);
3875                    }
3876
3877                    if (!resumeOK) {
3878                        return false;
3879                    }
3880                }
3881            }
3882            final long origId = Binder.clearCallingIdentity();
3883            try {
3884                boolean res;
3885                if (finishTask && r == rootR) {
3886                    // If requested, remove the task that is associated to this activity only if it
3887                    // was the root activity in the task.  The result code and data is ignored because
3888                    // we don't support returning them across task boundaries.
3889                    res = removeTaskByIdLocked(tr.taskId, 0);
3890                } else {
3891                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3892                            resultData, "app-request", true);
3893                }
3894                return res;
3895            } finally {
3896                Binder.restoreCallingIdentity(origId);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public final void finishHeavyWeightApp() {
3903        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3904                != PackageManager.PERMISSION_GRANTED) {
3905            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3906                    + Binder.getCallingPid()
3907                    + ", uid=" + Binder.getCallingUid()
3908                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3909            Slog.w(TAG, msg);
3910            throw new SecurityException(msg);
3911        }
3912
3913        synchronized(this) {
3914            if (mHeavyWeightProcess == null) {
3915                return;
3916            }
3917
3918            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3919                    mHeavyWeightProcess.activities);
3920            for (int i=0; i<activities.size(); i++) {
3921                ActivityRecord r = activities.get(i);
3922                if (!r.finishing) {
3923                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3924                            null, "finish-heavy", true);
3925                }
3926            }
3927
3928            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3929                    mHeavyWeightProcess.userId, 0));
3930            mHeavyWeightProcess = null;
3931        }
3932    }
3933
3934    @Override
3935    public void crashApplication(int uid, int initialPid, String packageName,
3936            String message) {
3937        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3938                != PackageManager.PERMISSION_GRANTED) {
3939            String msg = "Permission Denial: crashApplication() from pid="
3940                    + Binder.getCallingPid()
3941                    + ", uid=" + Binder.getCallingUid()
3942                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3943            Slog.w(TAG, msg);
3944            throw new SecurityException(msg);
3945        }
3946
3947        synchronized(this) {
3948            ProcessRecord proc = null;
3949
3950            // Figure out which process to kill.  We don't trust that initialPid
3951            // still has any relation to current pids, so must scan through the
3952            // list.
3953            synchronized (mPidsSelfLocked) {
3954                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3955                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3956                    if (p.uid != uid) {
3957                        continue;
3958                    }
3959                    if (p.pid == initialPid) {
3960                        proc = p;
3961                        break;
3962                    }
3963                    if (p.pkgList.containsKey(packageName)) {
3964                        proc = p;
3965                    }
3966                }
3967            }
3968
3969            if (proc == null) {
3970                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3971                        + " initialPid=" + initialPid
3972                        + " packageName=" + packageName);
3973                return;
3974            }
3975
3976            if (proc.thread != null) {
3977                if (proc.pid == Process.myPid()) {
3978                    Log.w(TAG, "crashApplication: trying to crash self!");
3979                    return;
3980                }
3981                long ident = Binder.clearCallingIdentity();
3982                try {
3983                    proc.thread.scheduleCrash(message);
3984                } catch (RemoteException e) {
3985                }
3986                Binder.restoreCallingIdentity(ident);
3987            }
3988        }
3989    }
3990
3991    @Override
3992    public final void finishSubActivity(IBinder token, String resultWho,
3993            int requestCode) {
3994        synchronized(this) {
3995            final long origId = Binder.clearCallingIdentity();
3996            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3997            if (r != null) {
3998                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3999            }
4000            Binder.restoreCallingIdentity(origId);
4001        }
4002    }
4003
4004    @Override
4005    public boolean finishActivityAffinity(IBinder token) {
4006        synchronized(this) {
4007            final long origId = Binder.clearCallingIdentity();
4008            try {
4009                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4010
4011                ActivityRecord rootR = r.task.getRootActivity();
4012                // Do not allow task to finish in Lock Task mode.
4013                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4014                    if (rootR == r) {
4015                        mStackSupervisor.showLockTaskToast();
4016                        return false;
4017                    }
4018                }
4019                boolean res = false;
4020                if (r != null) {
4021                    res = r.task.stack.finishActivityAffinityLocked(r);
4022                }
4023                return res;
4024            } finally {
4025                Binder.restoreCallingIdentity(origId);
4026            }
4027        }
4028    }
4029
4030    @Override
4031    public void finishVoiceTask(IVoiceInteractionSession session) {
4032        synchronized(this) {
4033            final long origId = Binder.clearCallingIdentity();
4034            try {
4035                mStackSupervisor.finishVoiceTask(session);
4036            } finally {
4037                Binder.restoreCallingIdentity(origId);
4038            }
4039        }
4040
4041    }
4042
4043    @Override
4044    public boolean willActivityBeVisible(IBinder token) {
4045        synchronized(this) {
4046            ActivityStack stack = ActivityRecord.getStackLocked(token);
4047            if (stack != null) {
4048                return stack.willActivityBeVisibleLocked(token);
4049            }
4050            return false;
4051        }
4052    }
4053
4054    @Override
4055    public void overridePendingTransition(IBinder token, String packageName,
4056            int enterAnim, int exitAnim) {
4057        synchronized(this) {
4058            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4059            if (self == null) {
4060                return;
4061            }
4062
4063            final long origId = Binder.clearCallingIdentity();
4064
4065            if (self.state == ActivityState.RESUMED
4066                    || self.state == ActivityState.PAUSING) {
4067                mWindowManager.overridePendingAppTransition(packageName,
4068                        enterAnim, exitAnim, null);
4069            }
4070
4071            Binder.restoreCallingIdentity(origId);
4072        }
4073    }
4074
4075    /**
4076     * Main function for removing an existing process from the activity manager
4077     * as a result of that process going away.  Clears out all connections
4078     * to the process.
4079     */
4080    private final void handleAppDiedLocked(ProcessRecord app,
4081            boolean restarting, boolean allowRestart) {
4082        int pid = app.pid;
4083        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4084        if (!restarting) {
4085            removeLruProcessLocked(app);
4086            if (pid > 0) {
4087                ProcessList.remove(pid);
4088            }
4089        }
4090
4091        if (mProfileProc == app) {
4092            clearProfilerLocked();
4093        }
4094
4095        // Remove this application's activities from active lists.
4096        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4097
4098        app.activities.clear();
4099
4100        if (app.instrumentationClass != null) {
4101            Slog.w(TAG, "Crash of app " + app.processName
4102                  + " running instrumentation " + app.instrumentationClass);
4103            Bundle info = new Bundle();
4104            info.putString("shortMsg", "Process crashed.");
4105            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4106        }
4107
4108        if (!restarting) {
4109            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4110                // If there was nothing to resume, and we are not already
4111                // restarting this process, but there is a visible activity that
4112                // is hosted by the process...  then make sure all visible
4113                // activities are running, taking care of restarting this
4114                // process.
4115                if (hasVisibleActivities) {
4116                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4117                }
4118            }
4119        }
4120    }
4121
4122    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4123        IBinder threadBinder = thread.asBinder();
4124        // Find the application record.
4125        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4126            ProcessRecord rec = mLruProcesses.get(i);
4127            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4128                return i;
4129            }
4130        }
4131        return -1;
4132    }
4133
4134    final ProcessRecord getRecordForAppLocked(
4135            IApplicationThread thread) {
4136        if (thread == null) {
4137            return null;
4138        }
4139
4140        int appIndex = getLRURecordIndexForAppLocked(thread);
4141        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4142    }
4143
4144    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4145        // If there are no longer any background processes running,
4146        // and the app that died was not running instrumentation,
4147        // then tell everyone we are now low on memory.
4148        boolean haveBg = false;
4149        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4150            ProcessRecord rec = mLruProcesses.get(i);
4151            if (rec.thread != null
4152                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4153                haveBg = true;
4154                break;
4155            }
4156        }
4157
4158        if (!haveBg) {
4159            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4160            if (doReport) {
4161                long now = SystemClock.uptimeMillis();
4162                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4163                    doReport = false;
4164                } else {
4165                    mLastMemUsageReportTime = now;
4166                }
4167            }
4168            final ArrayList<ProcessMemInfo> memInfos
4169                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4170            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4171            long now = SystemClock.uptimeMillis();
4172            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4173                ProcessRecord rec = mLruProcesses.get(i);
4174                if (rec == dyingProc || rec.thread == null) {
4175                    continue;
4176                }
4177                if (doReport) {
4178                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4179                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4180                }
4181                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4182                    // The low memory report is overriding any current
4183                    // state for a GC request.  Make sure to do
4184                    // heavy/important/visible/foreground processes first.
4185                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4186                        rec.lastRequestedGc = 0;
4187                    } else {
4188                        rec.lastRequestedGc = rec.lastLowMemory;
4189                    }
4190                    rec.reportLowMemory = true;
4191                    rec.lastLowMemory = now;
4192                    mProcessesToGc.remove(rec);
4193                    addProcessToGcListLocked(rec);
4194                }
4195            }
4196            if (doReport) {
4197                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4198                mHandler.sendMessage(msg);
4199            }
4200            scheduleAppGcsLocked();
4201        }
4202    }
4203
4204    final void appDiedLocked(ProcessRecord app, int pid,
4205            IApplicationThread thread) {
4206
4207        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4208        synchronized (stats) {
4209            stats.noteProcessDiedLocked(app.info.uid, pid);
4210        }
4211
4212        Process.killProcessGroup(app.info.uid, pid);
4213
4214        // Clean up already done if the process has been re-started.
4215        if (app.pid == pid && app.thread != null &&
4216                app.thread.asBinder() == thread.asBinder()) {
4217            boolean doLowMem = app.instrumentationClass == null;
4218            boolean doOomAdj = doLowMem;
4219            if (!app.killedByAm) {
4220                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4221                        + ") has died.");
4222                mAllowLowerMemLevel = true;
4223            } else {
4224                // Note that we always want to do oom adj to update our state with the
4225                // new number of procs.
4226                mAllowLowerMemLevel = false;
4227                doLowMem = false;
4228            }
4229            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4230            if (DEBUG_CLEANUP) Slog.v(
4231                TAG, "Dying app: " + app + ", pid: " + pid
4232                + ", thread: " + thread.asBinder());
4233            handleAppDiedLocked(app, false, true);
4234
4235            if (doOomAdj) {
4236                updateOomAdjLocked();
4237            }
4238            if (doLowMem) {
4239                doLowMemReportIfNeededLocked(app);
4240            }
4241        } else if (app.pid != pid) {
4242            // A new process has already been started.
4243            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4244                    + ") has died and restarted (pid " + app.pid + ").");
4245            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4246        } else if (DEBUG_PROCESSES) {
4247            Slog.d(TAG, "Received spurious death notification for thread "
4248                    + thread.asBinder());
4249        }
4250    }
4251
4252    /**
4253     * If a stack trace dump file is configured, dump process stack traces.
4254     * @param clearTraces causes the dump file to be erased prior to the new
4255     *    traces being written, if true; when false, the new traces will be
4256     *    appended to any existing file content.
4257     * @param firstPids of dalvik VM processes to dump stack traces for first
4258     * @param lastPids of dalvik VM processes to dump stack traces for last
4259     * @param nativeProcs optional list of native process names to dump stack crawls
4260     * @return file containing stack traces, or null if no dump file is configured
4261     */
4262    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4263            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4264        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4265        if (tracesPath == null || tracesPath.length() == 0) {
4266            return null;
4267        }
4268
4269        File tracesFile = new File(tracesPath);
4270        try {
4271            File tracesDir = tracesFile.getParentFile();
4272            if (!tracesDir.exists()) {
4273                tracesFile.mkdirs();
4274                if (!SELinux.restorecon(tracesDir)) {
4275                    return null;
4276                }
4277            }
4278            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4279
4280            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4281            tracesFile.createNewFile();
4282            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4283        } catch (IOException e) {
4284            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4285            return null;
4286        }
4287
4288        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4289        return tracesFile;
4290    }
4291
4292    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4293            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4294        // Use a FileObserver to detect when traces finish writing.
4295        // The order of traces is considered important to maintain for legibility.
4296        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4297            @Override
4298            public synchronized void onEvent(int event, String path) { notify(); }
4299        };
4300
4301        try {
4302            observer.startWatching();
4303
4304            // First collect all of the stacks of the most important pids.
4305            if (firstPids != null) {
4306                try {
4307                    int num = firstPids.size();
4308                    for (int i = 0; i < num; i++) {
4309                        synchronized (observer) {
4310                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4311                            observer.wait(200);  // Wait for write-close, give up after 200msec
4312                        }
4313                    }
4314                } catch (InterruptedException e) {
4315                    Log.wtf(TAG, e);
4316                }
4317            }
4318
4319            // Next collect the stacks of the native pids
4320            if (nativeProcs != null) {
4321                int[] pids = Process.getPidsForCommands(nativeProcs);
4322                if (pids != null) {
4323                    for (int pid : pids) {
4324                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4325                    }
4326                }
4327            }
4328
4329            // Lastly, measure CPU usage.
4330            if (processCpuTracker != null) {
4331                processCpuTracker.init();
4332                System.gc();
4333                processCpuTracker.update();
4334                try {
4335                    synchronized (processCpuTracker) {
4336                        processCpuTracker.wait(500); // measure over 1/2 second.
4337                    }
4338                } catch (InterruptedException e) {
4339                }
4340                processCpuTracker.update();
4341
4342                // We'll take the stack crawls of just the top apps using CPU.
4343                final int N = processCpuTracker.countWorkingStats();
4344                int numProcs = 0;
4345                for (int i=0; i<N && numProcs<5; i++) {
4346                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4347                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4348                        numProcs++;
4349                        try {
4350                            synchronized (observer) {
4351                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4352                                observer.wait(200);  // Wait for write-close, give up after 200msec
4353                            }
4354                        } catch (InterruptedException e) {
4355                            Log.wtf(TAG, e);
4356                        }
4357
4358                    }
4359                }
4360            }
4361        } finally {
4362            observer.stopWatching();
4363        }
4364    }
4365
4366    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4367        if (true || IS_USER_BUILD) {
4368            return;
4369        }
4370        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4371        if (tracesPath == null || tracesPath.length() == 0) {
4372            return;
4373        }
4374
4375        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4376        StrictMode.allowThreadDiskWrites();
4377        try {
4378            final File tracesFile = new File(tracesPath);
4379            final File tracesDir = tracesFile.getParentFile();
4380            final File tracesTmp = new File(tracesDir, "__tmp__");
4381            try {
4382                if (!tracesDir.exists()) {
4383                    tracesFile.mkdirs();
4384                    if (!SELinux.restorecon(tracesDir.getPath())) {
4385                        return;
4386                    }
4387                }
4388                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4389
4390                if (tracesFile.exists()) {
4391                    tracesTmp.delete();
4392                    tracesFile.renameTo(tracesTmp);
4393                }
4394                StringBuilder sb = new StringBuilder();
4395                Time tobj = new Time();
4396                tobj.set(System.currentTimeMillis());
4397                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4398                sb.append(": ");
4399                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4400                sb.append(" since ");
4401                sb.append(msg);
4402                FileOutputStream fos = new FileOutputStream(tracesFile);
4403                fos.write(sb.toString().getBytes());
4404                if (app == null) {
4405                    fos.write("\n*** No application process!".getBytes());
4406                }
4407                fos.close();
4408                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4409            } catch (IOException e) {
4410                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4411                return;
4412            }
4413
4414            if (app != null) {
4415                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4416                firstPids.add(app.pid);
4417                dumpStackTraces(tracesPath, firstPids, null, null, null);
4418            }
4419
4420            File lastTracesFile = null;
4421            File curTracesFile = null;
4422            for (int i=9; i>=0; i--) {
4423                String name = String.format(Locale.US, "slow%02d.txt", i);
4424                curTracesFile = new File(tracesDir, name);
4425                if (curTracesFile.exists()) {
4426                    if (lastTracesFile != null) {
4427                        curTracesFile.renameTo(lastTracesFile);
4428                    } else {
4429                        curTracesFile.delete();
4430                    }
4431                }
4432                lastTracesFile = curTracesFile;
4433            }
4434            tracesFile.renameTo(curTracesFile);
4435            if (tracesTmp.exists()) {
4436                tracesTmp.renameTo(tracesFile);
4437            }
4438        } finally {
4439            StrictMode.setThreadPolicy(oldPolicy);
4440        }
4441    }
4442
4443    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4444            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4445        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4446        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4447
4448        if (mController != null) {
4449            try {
4450                // 0 == continue, -1 = kill process immediately
4451                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4452                if (res < 0 && app.pid != MY_PID) {
4453                    Process.killProcess(app.pid);
4454                    Process.killProcessGroup(app.info.uid, app.pid);
4455                }
4456            } catch (RemoteException e) {
4457                mController = null;
4458                Watchdog.getInstance().setActivityController(null);
4459            }
4460        }
4461
4462        long anrTime = SystemClock.uptimeMillis();
4463        if (MONITOR_CPU_USAGE) {
4464            updateCpuStatsNow();
4465        }
4466
4467        synchronized (this) {
4468            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4469            if (mShuttingDown) {
4470                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4471                return;
4472            } else if (app.notResponding) {
4473                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4474                return;
4475            } else if (app.crashing) {
4476                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4477                return;
4478            }
4479
4480            // In case we come through here for the same app before completing
4481            // this one, mark as anring now so we will bail out.
4482            app.notResponding = true;
4483
4484            // Log the ANR to the event log.
4485            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4486                    app.processName, app.info.flags, annotation);
4487
4488            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4489            firstPids.add(app.pid);
4490
4491            int parentPid = app.pid;
4492            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4493            if (parentPid != app.pid) firstPids.add(parentPid);
4494
4495            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4496
4497            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4498                ProcessRecord r = mLruProcesses.get(i);
4499                if (r != null && r.thread != null) {
4500                    int pid = r.pid;
4501                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4502                        if (r.persistent) {
4503                            firstPids.add(pid);
4504                        } else {
4505                            lastPids.put(pid, Boolean.TRUE);
4506                        }
4507                    }
4508                }
4509            }
4510        }
4511
4512        // Log the ANR to the main log.
4513        StringBuilder info = new StringBuilder();
4514        info.setLength(0);
4515        info.append("ANR in ").append(app.processName);
4516        if (activity != null && activity.shortComponentName != null) {
4517            info.append(" (").append(activity.shortComponentName).append(")");
4518        }
4519        info.append("\n");
4520        info.append("PID: ").append(app.pid).append("\n");
4521        if (annotation != null) {
4522            info.append("Reason: ").append(annotation).append("\n");
4523        }
4524        if (parent != null && parent != activity) {
4525            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4526        }
4527
4528        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4529
4530        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4531                NATIVE_STACKS_OF_INTEREST);
4532
4533        String cpuInfo = null;
4534        if (MONITOR_CPU_USAGE) {
4535            updateCpuStatsNow();
4536            synchronized (mProcessCpuThread) {
4537                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4538            }
4539            info.append(processCpuTracker.printCurrentLoad());
4540            info.append(cpuInfo);
4541        }
4542
4543        info.append(processCpuTracker.printCurrentState(anrTime));
4544
4545        Slog.e(TAG, info.toString());
4546        if (tracesFile == null) {
4547            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4548            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4549        }
4550
4551        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4552                cpuInfo, tracesFile, null);
4553
4554        if (mController != null) {
4555            try {
4556                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4557                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4558                if (res != 0) {
4559                    if (res < 0 && app.pid != MY_PID) {
4560                        Process.killProcess(app.pid);
4561                        Process.killProcessGroup(app.info.uid, app.pid);
4562                    } else {
4563                        synchronized (this) {
4564                            mServices.scheduleServiceTimeoutLocked(app);
4565                        }
4566                    }
4567                    return;
4568                }
4569            } catch (RemoteException e) {
4570                mController = null;
4571                Watchdog.getInstance().setActivityController(null);
4572            }
4573        }
4574
4575        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4576        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4577                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4578
4579        synchronized (this) {
4580            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4581                killUnneededProcessLocked(app, "background ANR");
4582                return;
4583            }
4584
4585            // Set the app's notResponding state, and look up the errorReportReceiver
4586            makeAppNotRespondingLocked(app,
4587                    activity != null ? activity.shortComponentName : null,
4588                    annotation != null ? "ANR " + annotation : "ANR",
4589                    info.toString());
4590
4591            // Bring up the infamous App Not Responding dialog
4592            Message msg = Message.obtain();
4593            HashMap<String, Object> map = new HashMap<String, Object>();
4594            msg.what = SHOW_NOT_RESPONDING_MSG;
4595            msg.obj = map;
4596            msg.arg1 = aboveSystem ? 1 : 0;
4597            map.put("app", app);
4598            if (activity != null) {
4599                map.put("activity", activity);
4600            }
4601
4602            mHandler.sendMessage(msg);
4603        }
4604    }
4605
4606    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4607        if (!mLaunchWarningShown) {
4608            mLaunchWarningShown = true;
4609            mHandler.post(new Runnable() {
4610                @Override
4611                public void run() {
4612                    synchronized (ActivityManagerService.this) {
4613                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4614                        d.show();
4615                        mHandler.postDelayed(new Runnable() {
4616                            @Override
4617                            public void run() {
4618                                synchronized (ActivityManagerService.this) {
4619                                    d.dismiss();
4620                                    mLaunchWarningShown = false;
4621                                }
4622                            }
4623                        }, 4000);
4624                    }
4625                }
4626            });
4627        }
4628    }
4629
4630    @Override
4631    public boolean clearApplicationUserData(final String packageName,
4632            final IPackageDataObserver observer, int userId) {
4633        enforceNotIsolatedCaller("clearApplicationUserData");
4634        int uid = Binder.getCallingUid();
4635        int pid = Binder.getCallingPid();
4636        userId = handleIncomingUser(pid, uid,
4637                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4638        long callingId = Binder.clearCallingIdentity();
4639        try {
4640            IPackageManager pm = AppGlobals.getPackageManager();
4641            int pkgUid = -1;
4642            synchronized(this) {
4643                try {
4644                    pkgUid = pm.getPackageUid(packageName, userId);
4645                } catch (RemoteException e) {
4646                }
4647                if (pkgUid == -1) {
4648                    Slog.w(TAG, "Invalid packageName: " + packageName);
4649                    if (observer != null) {
4650                        try {
4651                            observer.onRemoveCompleted(packageName, false);
4652                        } catch (RemoteException e) {
4653                            Slog.i(TAG, "Observer no longer exists.");
4654                        }
4655                    }
4656                    return false;
4657                }
4658                if (uid == pkgUid || checkComponentPermission(
4659                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4660                        pid, uid, -1, true)
4661                        == PackageManager.PERMISSION_GRANTED) {
4662                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4663                } else {
4664                    throw new SecurityException("PID " + pid + " does not have permission "
4665                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4666                                    + " of package " + packageName);
4667                }
4668
4669                // Remove all tasks match the cleared application package and user
4670                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4671                    final TaskRecord tr = mRecentTasks.get(i);
4672                    final String taskPackageName =
4673                            tr.getBaseIntent().getComponent().getPackageName();
4674                    if (tr.userId != userId) continue;
4675                    if (!taskPackageName.equals(packageName)) continue;
4676                    removeTaskByIdLocked(tr.taskId, 0);
4677                }
4678            }
4679
4680            try {
4681                // Clear application user data
4682                pm.clearApplicationUserData(packageName, observer, userId);
4683
4684                synchronized(this) {
4685                    // Remove all permissions granted from/to this package
4686                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4687                }
4688
4689                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4690                        Uri.fromParts("package", packageName, null));
4691                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4692                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4693                        null, null, 0, null, null, null, false, false, userId);
4694            } catch (RemoteException e) {
4695            }
4696        } finally {
4697            Binder.restoreCallingIdentity(callingId);
4698        }
4699        return true;
4700    }
4701
4702    @Override
4703    public void killBackgroundProcesses(final String packageName, int userId) {
4704        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4705                != PackageManager.PERMISSION_GRANTED &&
4706                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4707                        != PackageManager.PERMISSION_GRANTED) {
4708            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4709                    + Binder.getCallingPid()
4710                    + ", uid=" + Binder.getCallingUid()
4711                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4712            Slog.w(TAG, msg);
4713            throw new SecurityException(msg);
4714        }
4715
4716        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4717                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4718        long callingId = Binder.clearCallingIdentity();
4719        try {
4720            IPackageManager pm = AppGlobals.getPackageManager();
4721            synchronized(this) {
4722                int appId = -1;
4723                try {
4724                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4725                } catch (RemoteException e) {
4726                }
4727                if (appId == -1) {
4728                    Slog.w(TAG, "Invalid packageName: " + packageName);
4729                    return;
4730                }
4731                killPackageProcessesLocked(packageName, appId, userId,
4732                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4733            }
4734        } finally {
4735            Binder.restoreCallingIdentity(callingId);
4736        }
4737    }
4738
4739    @Override
4740    public void killAllBackgroundProcesses() {
4741        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4742                != PackageManager.PERMISSION_GRANTED) {
4743            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4744                    + Binder.getCallingPid()
4745                    + ", uid=" + Binder.getCallingUid()
4746                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4747            Slog.w(TAG, msg);
4748            throw new SecurityException(msg);
4749        }
4750
4751        long callingId = Binder.clearCallingIdentity();
4752        try {
4753            synchronized(this) {
4754                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4755                final int NP = mProcessNames.getMap().size();
4756                for (int ip=0; ip<NP; ip++) {
4757                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4758                    final int NA = apps.size();
4759                    for (int ia=0; ia<NA; ia++) {
4760                        ProcessRecord app = apps.valueAt(ia);
4761                        if (app.persistent) {
4762                            // we don't kill persistent processes
4763                            continue;
4764                        }
4765                        if (app.removed) {
4766                            procs.add(app);
4767                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4768                            app.removed = true;
4769                            procs.add(app);
4770                        }
4771                    }
4772                }
4773
4774                int N = procs.size();
4775                for (int i=0; i<N; i++) {
4776                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4777                }
4778                mAllowLowerMemLevel = true;
4779                updateOomAdjLocked();
4780                doLowMemReportIfNeededLocked(null);
4781            }
4782        } finally {
4783            Binder.restoreCallingIdentity(callingId);
4784        }
4785    }
4786
4787    @Override
4788    public void forceStopPackage(final String packageName, int userId) {
4789        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4790                != PackageManager.PERMISSION_GRANTED) {
4791            String msg = "Permission Denial: forceStopPackage() from pid="
4792                    + Binder.getCallingPid()
4793                    + ", uid=" + Binder.getCallingUid()
4794                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4795            Slog.w(TAG, msg);
4796            throw new SecurityException(msg);
4797        }
4798        final int callingPid = Binder.getCallingPid();
4799        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4800                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4801        long callingId = Binder.clearCallingIdentity();
4802        try {
4803            IPackageManager pm = AppGlobals.getPackageManager();
4804            synchronized(this) {
4805                int[] users = userId == UserHandle.USER_ALL
4806                        ? getUsersLocked() : new int[] { userId };
4807                for (int user : users) {
4808                    int pkgUid = -1;
4809                    try {
4810                        pkgUid = pm.getPackageUid(packageName, user);
4811                    } catch (RemoteException e) {
4812                    }
4813                    if (pkgUid == -1) {
4814                        Slog.w(TAG, "Invalid packageName: " + packageName);
4815                        continue;
4816                    }
4817                    try {
4818                        pm.setPackageStoppedState(packageName, true, user);
4819                    } catch (RemoteException e) {
4820                    } catch (IllegalArgumentException e) {
4821                        Slog.w(TAG, "Failed trying to unstop package "
4822                                + packageName + ": " + e);
4823                    }
4824                    if (isUserRunningLocked(user, false)) {
4825                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4826                    }
4827                }
4828            }
4829        } finally {
4830            Binder.restoreCallingIdentity(callingId);
4831        }
4832    }
4833
4834    @Override
4835    public void addPackageDependency(String packageName) {
4836        synchronized (this) {
4837            int callingPid = Binder.getCallingPid();
4838            if (callingPid == Process.myPid()) {
4839                //  Yeah, um, no.
4840                Slog.w(TAG, "Can't addPackageDependency on system process");
4841                return;
4842            }
4843            ProcessRecord proc;
4844            synchronized (mPidsSelfLocked) {
4845                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4846            }
4847            if (proc != null) {
4848                if (proc.pkgDeps == null) {
4849                    proc.pkgDeps = new ArraySet<String>(1);
4850                }
4851                proc.pkgDeps.add(packageName);
4852            }
4853        }
4854    }
4855
4856    /*
4857     * The pkg name and app id have to be specified.
4858     */
4859    @Override
4860    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4861        if (pkg == null) {
4862            return;
4863        }
4864        // Make sure the uid is valid.
4865        if (appid < 0) {
4866            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4867            return;
4868        }
4869        int callerUid = Binder.getCallingUid();
4870        // Only the system server can kill an application
4871        if (callerUid == Process.SYSTEM_UID) {
4872            // Post an aysnc message to kill the application
4873            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4874            msg.arg1 = appid;
4875            msg.arg2 = 0;
4876            Bundle bundle = new Bundle();
4877            bundle.putString("pkg", pkg);
4878            bundle.putString("reason", reason);
4879            msg.obj = bundle;
4880            mHandler.sendMessage(msg);
4881        } else {
4882            throw new SecurityException(callerUid + " cannot kill pkg: " +
4883                    pkg);
4884        }
4885    }
4886
4887    @Override
4888    public void closeSystemDialogs(String reason) {
4889        enforceNotIsolatedCaller("closeSystemDialogs");
4890
4891        final int pid = Binder.getCallingPid();
4892        final int uid = Binder.getCallingUid();
4893        final long origId = Binder.clearCallingIdentity();
4894        try {
4895            synchronized (this) {
4896                // Only allow this from foreground processes, so that background
4897                // applications can't abuse it to prevent system UI from being shown.
4898                if (uid >= Process.FIRST_APPLICATION_UID) {
4899                    ProcessRecord proc;
4900                    synchronized (mPidsSelfLocked) {
4901                        proc = mPidsSelfLocked.get(pid);
4902                    }
4903                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4904                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4905                                + " from background process " + proc);
4906                        return;
4907                    }
4908                }
4909                closeSystemDialogsLocked(reason);
4910            }
4911        } finally {
4912            Binder.restoreCallingIdentity(origId);
4913        }
4914    }
4915
4916    void closeSystemDialogsLocked(String reason) {
4917        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4918        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4919                | Intent.FLAG_RECEIVER_FOREGROUND);
4920        if (reason != null) {
4921            intent.putExtra("reason", reason);
4922        }
4923        mWindowManager.closeSystemDialogs(reason);
4924
4925        mStackSupervisor.closeSystemDialogsLocked();
4926
4927        broadcastIntentLocked(null, null, intent, null,
4928                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4929                Process.SYSTEM_UID, UserHandle.USER_ALL);
4930    }
4931
4932    @Override
4933    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4934        enforceNotIsolatedCaller("getProcessMemoryInfo");
4935        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4936        for (int i=pids.length-1; i>=0; i--) {
4937            ProcessRecord proc;
4938            int oomAdj;
4939            synchronized (this) {
4940                synchronized (mPidsSelfLocked) {
4941                    proc = mPidsSelfLocked.get(pids[i]);
4942                    oomAdj = proc != null ? proc.setAdj : 0;
4943                }
4944            }
4945            infos[i] = new Debug.MemoryInfo();
4946            Debug.getMemoryInfo(pids[i], infos[i]);
4947            if (proc != null) {
4948                synchronized (this) {
4949                    if (proc.thread != null && proc.setAdj == oomAdj) {
4950                        // Record this for posterity if the process has been stable.
4951                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4952                                infos[i].getTotalUss(), false, proc.pkgList);
4953                    }
4954                }
4955            }
4956        }
4957        return infos;
4958    }
4959
4960    @Override
4961    public long[] getProcessPss(int[] pids) {
4962        enforceNotIsolatedCaller("getProcessPss");
4963        long[] pss = new long[pids.length];
4964        for (int i=pids.length-1; i>=0; i--) {
4965            ProcessRecord proc;
4966            int oomAdj;
4967            synchronized (this) {
4968                synchronized (mPidsSelfLocked) {
4969                    proc = mPidsSelfLocked.get(pids[i]);
4970                    oomAdj = proc != null ? proc.setAdj : 0;
4971                }
4972            }
4973            long[] tmpUss = new long[1];
4974            pss[i] = Debug.getPss(pids[i], tmpUss);
4975            if (proc != null) {
4976                synchronized (this) {
4977                    if (proc.thread != null && proc.setAdj == oomAdj) {
4978                        // Record this for posterity if the process has been stable.
4979                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4980                    }
4981                }
4982            }
4983        }
4984        return pss;
4985    }
4986
4987    @Override
4988    public void killApplicationProcess(String processName, int uid) {
4989        if (processName == null) {
4990            return;
4991        }
4992
4993        int callerUid = Binder.getCallingUid();
4994        // Only the system server can kill an application
4995        if (callerUid == Process.SYSTEM_UID) {
4996            synchronized (this) {
4997                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4998                if (app != null && app.thread != null) {
4999                    try {
5000                        app.thread.scheduleSuicide();
5001                    } catch (RemoteException e) {
5002                        // If the other end already died, then our work here is done.
5003                    }
5004                } else {
5005                    Slog.w(TAG, "Process/uid not found attempting kill of "
5006                            + processName + " / " + uid);
5007                }
5008            }
5009        } else {
5010            throw new SecurityException(callerUid + " cannot kill app process: " +
5011                    processName);
5012        }
5013    }
5014
5015    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5016        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5017                false, true, false, false, UserHandle.getUserId(uid), reason);
5018        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5019                Uri.fromParts("package", packageName, null));
5020        if (!mProcessesReady) {
5021            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5022                    | Intent.FLAG_RECEIVER_FOREGROUND);
5023        }
5024        intent.putExtra(Intent.EXTRA_UID, uid);
5025        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5026        broadcastIntentLocked(null, null, intent,
5027                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5028                false, false,
5029                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5030    }
5031
5032    private void forceStopUserLocked(int userId, String reason) {
5033        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5034        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5035        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5036                | Intent.FLAG_RECEIVER_FOREGROUND);
5037        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5038        broadcastIntentLocked(null, null, intent,
5039                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5040                false, false,
5041                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5042    }
5043
5044    private final boolean killPackageProcessesLocked(String packageName, int appId,
5045            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5046            boolean doit, boolean evenPersistent, String reason) {
5047        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5048
5049        // Remove all processes this package may have touched: all with the
5050        // same UID (except for the system or root user), and all whose name
5051        // matches the package name.
5052        final int NP = mProcessNames.getMap().size();
5053        for (int ip=0; ip<NP; ip++) {
5054            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5055            final int NA = apps.size();
5056            for (int ia=0; ia<NA; ia++) {
5057                ProcessRecord app = apps.valueAt(ia);
5058                if (app.persistent && !evenPersistent) {
5059                    // we don't kill persistent processes
5060                    continue;
5061                }
5062                if (app.removed) {
5063                    if (doit) {
5064                        procs.add(app);
5065                    }
5066                    continue;
5067                }
5068
5069                // Skip process if it doesn't meet our oom adj requirement.
5070                if (app.setAdj < minOomAdj) {
5071                    continue;
5072                }
5073
5074                // If no package is specified, we call all processes under the
5075                // give user id.
5076                if (packageName == null) {
5077                    if (app.userId != userId) {
5078                        continue;
5079                    }
5080                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5081                        continue;
5082                    }
5083                // Package has been specified, we want to hit all processes
5084                // that match it.  We need to qualify this by the processes
5085                // that are running under the specified app and user ID.
5086                } else {
5087                    final boolean isDep = app.pkgDeps != null
5088                            && app.pkgDeps.contains(packageName);
5089                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5090                        continue;
5091                    }
5092                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5093                        continue;
5094                    }
5095                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5096                        continue;
5097                    }
5098                }
5099
5100                // Process has passed all conditions, kill it!
5101                if (!doit) {
5102                    return true;
5103                }
5104                app.removed = true;
5105                procs.add(app);
5106            }
5107        }
5108
5109        int N = procs.size();
5110        for (int i=0; i<N; i++) {
5111            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5112        }
5113        updateOomAdjLocked();
5114        return N > 0;
5115    }
5116
5117    private final boolean forceStopPackageLocked(String name, int appId,
5118            boolean callerWillRestart, boolean purgeCache, boolean doit,
5119            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5120        int i;
5121        int N;
5122
5123        if (userId == UserHandle.USER_ALL && name == null) {
5124            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5125        }
5126
5127        if (appId < 0 && name != null) {
5128            try {
5129                appId = UserHandle.getAppId(
5130                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5131            } catch (RemoteException e) {
5132            }
5133        }
5134
5135        if (doit) {
5136            if (name != null) {
5137                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5138                        + " user=" + userId + ": " + reason);
5139            } else {
5140                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5141            }
5142
5143            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5144            for (int ip=pmap.size()-1; ip>=0; ip--) {
5145                SparseArray<Long> ba = pmap.valueAt(ip);
5146                for (i=ba.size()-1; i>=0; i--) {
5147                    boolean remove = false;
5148                    final int entUid = ba.keyAt(i);
5149                    if (name != null) {
5150                        if (userId == UserHandle.USER_ALL) {
5151                            if (UserHandle.getAppId(entUid) == appId) {
5152                                remove = true;
5153                            }
5154                        } else {
5155                            if (entUid == UserHandle.getUid(userId, appId)) {
5156                                remove = true;
5157                            }
5158                        }
5159                    } else if (UserHandle.getUserId(entUid) == userId) {
5160                        remove = true;
5161                    }
5162                    if (remove) {
5163                        ba.removeAt(i);
5164                    }
5165                }
5166                if (ba.size() == 0) {
5167                    pmap.removeAt(ip);
5168                }
5169            }
5170        }
5171
5172        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5173                -100, callerWillRestart, true, doit, evenPersistent,
5174                name == null ? ("stop user " + userId) : ("stop " + name));
5175
5176        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5177            if (!doit) {
5178                return true;
5179            }
5180            didSomething = true;
5181        }
5182
5183        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5184            if (!doit) {
5185                return true;
5186            }
5187            didSomething = true;
5188        }
5189
5190        if (name == null) {
5191            // Remove all sticky broadcasts from this user.
5192            mStickyBroadcasts.remove(userId);
5193        }
5194
5195        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5196        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5197                userId, providers)) {
5198            if (!doit) {
5199                return true;
5200            }
5201            didSomething = true;
5202        }
5203        N = providers.size();
5204        for (i=0; i<N; i++) {
5205            removeDyingProviderLocked(null, providers.get(i), true);
5206        }
5207
5208        // Remove transient permissions granted from/to this package/user
5209        removeUriPermissionsForPackageLocked(name, userId, false);
5210
5211        if (name == null || uninstalling) {
5212            // Remove pending intents.  For now we only do this when force
5213            // stopping users, because we have some problems when doing this
5214            // for packages -- app widgets are not currently cleaned up for
5215            // such packages, so they can be left with bad pending intents.
5216            if (mIntentSenderRecords.size() > 0) {
5217                Iterator<WeakReference<PendingIntentRecord>> it
5218                        = mIntentSenderRecords.values().iterator();
5219                while (it.hasNext()) {
5220                    WeakReference<PendingIntentRecord> wpir = it.next();
5221                    if (wpir == null) {
5222                        it.remove();
5223                        continue;
5224                    }
5225                    PendingIntentRecord pir = wpir.get();
5226                    if (pir == null) {
5227                        it.remove();
5228                        continue;
5229                    }
5230                    if (name == null) {
5231                        // Stopping user, remove all objects for the user.
5232                        if (pir.key.userId != userId) {
5233                            // Not the same user, skip it.
5234                            continue;
5235                        }
5236                    } else {
5237                        if (UserHandle.getAppId(pir.uid) != appId) {
5238                            // Different app id, skip it.
5239                            continue;
5240                        }
5241                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5242                            // Different user, skip it.
5243                            continue;
5244                        }
5245                        if (!pir.key.packageName.equals(name)) {
5246                            // Different package, skip it.
5247                            continue;
5248                        }
5249                    }
5250                    if (!doit) {
5251                        return true;
5252                    }
5253                    didSomething = true;
5254                    it.remove();
5255                    pir.canceled = true;
5256                    if (pir.key.activity != null) {
5257                        pir.key.activity.pendingResults.remove(pir.ref);
5258                    }
5259                }
5260            }
5261        }
5262
5263        if (doit) {
5264            if (purgeCache && name != null) {
5265                AttributeCache ac = AttributeCache.instance();
5266                if (ac != null) {
5267                    ac.removePackage(name);
5268                }
5269            }
5270            if (mBooted) {
5271                mStackSupervisor.resumeTopActivitiesLocked();
5272                mStackSupervisor.scheduleIdleLocked();
5273            }
5274        }
5275
5276        return didSomething;
5277    }
5278
5279    private final boolean removeProcessLocked(ProcessRecord app,
5280            boolean callerWillRestart, boolean allowRestart, String reason) {
5281        final String name = app.processName;
5282        final int uid = app.uid;
5283        if (DEBUG_PROCESSES) Slog.d(
5284            TAG, "Force removing proc " + app.toShortString() + " (" + name
5285            + "/" + uid + ")");
5286
5287        mProcessNames.remove(name, uid);
5288        mIsolatedProcesses.remove(app.uid);
5289        if (mHeavyWeightProcess == app) {
5290            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5291                    mHeavyWeightProcess.userId, 0));
5292            mHeavyWeightProcess = null;
5293        }
5294        boolean needRestart = false;
5295        if (app.pid > 0 && app.pid != MY_PID) {
5296            int pid = app.pid;
5297            synchronized (mPidsSelfLocked) {
5298                mPidsSelfLocked.remove(pid);
5299                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5300            }
5301            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5302            if (app.isolated) {
5303                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5304            }
5305            killUnneededProcessLocked(app, reason);
5306            Process.killProcessGroup(app.info.uid, app.pid);
5307            handleAppDiedLocked(app, true, allowRestart);
5308            removeLruProcessLocked(app);
5309
5310            if (app.persistent && !app.isolated) {
5311                if (!callerWillRestart) {
5312                    addAppLocked(app.info, false, null /* ABI override */);
5313                } else {
5314                    needRestart = true;
5315                }
5316            }
5317        } else {
5318            mRemovedProcesses.add(app);
5319        }
5320
5321        return needRestart;
5322    }
5323
5324    private final void processStartTimedOutLocked(ProcessRecord app) {
5325        final int pid = app.pid;
5326        boolean gone = false;
5327        synchronized (mPidsSelfLocked) {
5328            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5329            if (knownApp != null && knownApp.thread == null) {
5330                mPidsSelfLocked.remove(pid);
5331                gone = true;
5332            }
5333        }
5334
5335        if (gone) {
5336            Slog.w(TAG, "Process " + app + " failed to attach");
5337            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5338                    pid, app.uid, app.processName);
5339            mProcessNames.remove(app.processName, app.uid);
5340            mIsolatedProcesses.remove(app.uid);
5341            if (mHeavyWeightProcess == app) {
5342                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5343                        mHeavyWeightProcess.userId, 0));
5344                mHeavyWeightProcess = null;
5345            }
5346            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5347            if (app.isolated) {
5348                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5349            }
5350            // Take care of any launching providers waiting for this process.
5351            checkAppInLaunchingProvidersLocked(app, true);
5352            // Take care of any services that are waiting for the process.
5353            mServices.processStartTimedOutLocked(app);
5354            killUnneededProcessLocked(app, "start timeout");
5355            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5356                Slog.w(TAG, "Unattached app died before backup, skipping");
5357                try {
5358                    IBackupManager bm = IBackupManager.Stub.asInterface(
5359                            ServiceManager.getService(Context.BACKUP_SERVICE));
5360                    bm.agentDisconnected(app.info.packageName);
5361                } catch (RemoteException e) {
5362                    // Can't happen; the backup manager is local
5363                }
5364            }
5365            if (isPendingBroadcastProcessLocked(pid)) {
5366                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5367                skipPendingBroadcastLocked(pid);
5368            }
5369        } else {
5370            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5371        }
5372    }
5373
5374    private final boolean attachApplicationLocked(IApplicationThread thread,
5375            int pid) {
5376
5377        // Find the application record that is being attached...  either via
5378        // the pid if we are running in multiple processes, or just pull the
5379        // next app record if we are emulating process with anonymous threads.
5380        ProcessRecord app;
5381        if (pid != MY_PID && pid >= 0) {
5382            synchronized (mPidsSelfLocked) {
5383                app = mPidsSelfLocked.get(pid);
5384            }
5385        } else {
5386            app = null;
5387        }
5388
5389        if (app == null) {
5390            Slog.w(TAG, "No pending application record for pid " + pid
5391                    + " (IApplicationThread " + thread + "); dropping process");
5392            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5393            if (pid > 0 && pid != MY_PID) {
5394                Process.killProcessQuiet(pid);
5395                //TODO: Process.killProcessGroup(app.info.uid, pid);
5396            } else {
5397                try {
5398                    thread.scheduleExit();
5399                } catch (Exception e) {
5400                    // Ignore exceptions.
5401                }
5402            }
5403            return false;
5404        }
5405
5406        // If this application record is still attached to a previous
5407        // process, clean it up now.
5408        if (app.thread != null) {
5409            handleAppDiedLocked(app, true, true);
5410        }
5411
5412        // Tell the process all about itself.
5413
5414        if (localLOGV) Slog.v(
5415                TAG, "Binding process pid " + pid + " to record " + app);
5416
5417        final String processName = app.processName;
5418        try {
5419            AppDeathRecipient adr = new AppDeathRecipient(
5420                    app, pid, thread);
5421            thread.asBinder().linkToDeath(adr, 0);
5422            app.deathRecipient = adr;
5423        } catch (RemoteException e) {
5424            app.resetPackageList(mProcessStats);
5425            startProcessLocked(app, "link fail", processName);
5426            return false;
5427        }
5428
5429        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5430
5431        app.makeActive(thread, mProcessStats);
5432        app.curAdj = app.setAdj = -100;
5433        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5434        app.forcingToForeground = null;
5435        updateProcessForegroundLocked(app, false, false);
5436        app.hasShownUi = false;
5437        app.debugging = false;
5438        app.cached = false;
5439
5440        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5441
5442        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5443        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5444
5445        if (!normalMode) {
5446            Slog.i(TAG, "Launching preboot mode app: " + app);
5447        }
5448
5449        if (localLOGV) Slog.v(
5450            TAG, "New app record " + app
5451            + " thread=" + thread.asBinder() + " pid=" + pid);
5452        try {
5453            int testMode = IApplicationThread.DEBUG_OFF;
5454            if (mDebugApp != null && mDebugApp.equals(processName)) {
5455                testMode = mWaitForDebugger
5456                    ? IApplicationThread.DEBUG_WAIT
5457                    : IApplicationThread.DEBUG_ON;
5458                app.debugging = true;
5459                if (mDebugTransient) {
5460                    mDebugApp = mOrigDebugApp;
5461                    mWaitForDebugger = mOrigWaitForDebugger;
5462                }
5463            }
5464            String profileFile = app.instrumentationProfileFile;
5465            ParcelFileDescriptor profileFd = null;
5466            boolean profileAutoStop = false;
5467            if (mProfileApp != null && mProfileApp.equals(processName)) {
5468                mProfileProc = app;
5469                profileFile = mProfileFile;
5470                profileFd = mProfileFd;
5471                profileAutoStop = mAutoStopProfiler;
5472            }
5473            boolean enableOpenGlTrace = false;
5474            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5475                enableOpenGlTrace = true;
5476                mOpenGlTraceApp = null;
5477            }
5478
5479            // If the app is being launched for restore or full backup, set it up specially
5480            boolean isRestrictedBackupMode = false;
5481            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5482                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5483                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5484                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5485            }
5486
5487            ensurePackageDexOpt(app.instrumentationInfo != null
5488                    ? app.instrumentationInfo.packageName
5489                    : app.info.packageName);
5490            if (app.instrumentationClass != null) {
5491                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5492            }
5493            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5494                    + processName + " with config " + mConfiguration);
5495            ApplicationInfo appInfo = app.instrumentationInfo != null
5496                    ? app.instrumentationInfo : app.info;
5497            app.compat = compatibilityInfoForPackageLocked(appInfo);
5498            if (profileFd != null) {
5499                profileFd = profileFd.dup();
5500            }
5501            thread.bindApplication(processName, appInfo, providers,
5502                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5503                    app.instrumentationArguments, app.instrumentationWatcher,
5504                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5505                    isRestrictedBackupMode || !normalMode, app.persistent,
5506                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5507                    mCoreSettingsObserver.getCoreSettingsLocked());
5508            updateLruProcessLocked(app, false, null);
5509            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5510        } catch (Exception e) {
5511            // todo: Yikes!  What should we do?  For now we will try to
5512            // start another process, but that could easily get us in
5513            // an infinite loop of restarting processes...
5514            Slog.w(TAG, "Exception thrown during bind!", e);
5515
5516            app.resetPackageList(mProcessStats);
5517            app.unlinkDeathRecipient();
5518            startProcessLocked(app, "bind fail", processName);
5519            return false;
5520        }
5521
5522        // Remove this record from the list of starting applications.
5523        mPersistentStartingProcesses.remove(app);
5524        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5525                "Attach application locked removing on hold: " + app);
5526        mProcessesOnHold.remove(app);
5527
5528        boolean badApp = false;
5529        boolean didSomething = false;
5530
5531        // See if the top visible activity is waiting to run in this process...
5532        if (normalMode) {
5533            try {
5534                if (mStackSupervisor.attachApplicationLocked(app)) {
5535                    didSomething = true;
5536                }
5537            } catch (Exception e) {
5538                badApp = true;
5539            }
5540        }
5541
5542        // Find any services that should be running in this process...
5543        if (!badApp) {
5544            try {
5545                didSomething |= mServices.attachApplicationLocked(app, processName);
5546            } catch (Exception e) {
5547                badApp = true;
5548            }
5549        }
5550
5551        // Check if a next-broadcast receiver is in this process...
5552        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5553            try {
5554                didSomething |= sendPendingBroadcastsLocked(app);
5555            } catch (Exception e) {
5556                // If the app died trying to launch the receiver we declare it 'bad'
5557                badApp = true;
5558            }
5559        }
5560
5561        // Check whether the next backup agent is in this process...
5562        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5563            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5564            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5565            try {
5566                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5567                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5568                        mBackupTarget.backupMode);
5569            } catch (Exception e) {
5570                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5571                e.printStackTrace();
5572            }
5573        }
5574
5575        if (badApp) {
5576            // todo: Also need to kill application to deal with all
5577            // kinds of exceptions.
5578            handleAppDiedLocked(app, false, true);
5579            return false;
5580        }
5581
5582        if (!didSomething) {
5583            updateOomAdjLocked();
5584        }
5585
5586        return true;
5587    }
5588
5589    @Override
5590    public final void attachApplication(IApplicationThread thread) {
5591        synchronized (this) {
5592            int callingPid = Binder.getCallingPid();
5593            final long origId = Binder.clearCallingIdentity();
5594            attachApplicationLocked(thread, callingPid);
5595            Binder.restoreCallingIdentity(origId);
5596        }
5597    }
5598
5599    @Override
5600    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5601        final long origId = Binder.clearCallingIdentity();
5602        synchronized (this) {
5603            ActivityStack stack = ActivityRecord.getStackLocked(token);
5604            if (stack != null) {
5605                ActivityRecord r =
5606                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5607                if (stopProfiling) {
5608                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5609                        try {
5610                            mProfileFd.close();
5611                        } catch (IOException e) {
5612                        }
5613                        clearProfilerLocked();
5614                    }
5615                }
5616            }
5617        }
5618        Binder.restoreCallingIdentity(origId);
5619    }
5620
5621    void postEnableScreenAfterBootLocked() {
5622        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5623    }
5624
5625    void enableScreenAfterBoot() {
5626        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5627                SystemClock.uptimeMillis());
5628        mWindowManager.enableScreenAfterBoot();
5629
5630        synchronized (this) {
5631            updateEventDispatchingLocked();
5632        }
5633    }
5634
5635    @Override
5636    public void showBootMessage(final CharSequence msg, final boolean always) {
5637        enforceNotIsolatedCaller("showBootMessage");
5638        mWindowManager.showBootMessage(msg, always);
5639    }
5640
5641    @Override
5642    public void keyguardWaitingForActivityDrawn() {
5643        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5644        final long token = Binder.clearCallingIdentity();
5645        try {
5646            synchronized (this) {
5647                if (DEBUG_LOCKSCREEN) logLockScreen("");
5648                mWindowManager.keyguardWaitingForActivityDrawn();
5649            }
5650        } finally {
5651            Binder.restoreCallingIdentity(token);
5652        }
5653    }
5654
5655    final void finishBooting() {
5656        // Register receivers to handle package update events
5657        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5658
5659        // Let system services know.
5660        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5661
5662        synchronized (this) {
5663            // Ensure that any processes we had put on hold are now started
5664            // up.
5665            final int NP = mProcessesOnHold.size();
5666            if (NP > 0) {
5667                ArrayList<ProcessRecord> procs =
5668                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5669                for (int ip=0; ip<NP; ip++) {
5670                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5671                            + procs.get(ip));
5672                    startProcessLocked(procs.get(ip), "on-hold", null);
5673                }
5674            }
5675
5676            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5677                // Start looking for apps that are abusing wake locks.
5678                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5679                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5680                // Tell anyone interested that we are done booting!
5681                SystemProperties.set("sys.boot_completed", "1");
5682                SystemProperties.set("dev.bootcomplete", "1");
5683                for (int i=0; i<mStartedUsers.size(); i++) {
5684                    UserStartedState uss = mStartedUsers.valueAt(i);
5685                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5686                        uss.mState = UserStartedState.STATE_RUNNING;
5687                        final int userId = mStartedUsers.keyAt(i);
5688                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5689                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5690                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5691                        broadcastIntentLocked(null, null, intent, null,
5692                                new IIntentReceiver.Stub() {
5693                                    @Override
5694                                    public void performReceive(Intent intent, int resultCode,
5695                                            String data, Bundle extras, boolean ordered,
5696                                            boolean sticky, int sendingUser) {
5697                                        synchronized (ActivityManagerService.this) {
5698                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5699                                                    true, false);
5700                                        }
5701                                    }
5702                                },
5703                                0, null, null,
5704                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5705                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5706                                userId);
5707                    }
5708                }
5709                scheduleStartProfilesLocked();
5710            }
5711        }
5712    }
5713
5714    final void ensureBootCompleted() {
5715        boolean booting;
5716        boolean enableScreen;
5717        synchronized (this) {
5718            booting = mBooting;
5719            mBooting = false;
5720            enableScreen = !mBooted;
5721            mBooted = true;
5722        }
5723
5724        if (booting) {
5725            finishBooting();
5726        }
5727
5728        if (enableScreen) {
5729            enableScreenAfterBoot();
5730        }
5731    }
5732
5733    @Override
5734    public final void activityResumed(IBinder token) {
5735        final long origId = Binder.clearCallingIdentity();
5736        synchronized(this) {
5737            ActivityStack stack = ActivityRecord.getStackLocked(token);
5738            if (stack != null) {
5739                ActivityRecord.activityResumedLocked(token);
5740            }
5741        }
5742        Binder.restoreCallingIdentity(origId);
5743    }
5744
5745    @Override
5746    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5747        final long origId = Binder.clearCallingIdentity();
5748        synchronized(this) {
5749            ActivityStack stack = ActivityRecord.getStackLocked(token);
5750            if (stack != null) {
5751                stack.activityPausedLocked(token, false, persistentState);
5752            }
5753        }
5754        Binder.restoreCallingIdentity(origId);
5755    }
5756
5757    @Override
5758    public final void activityStopped(IBinder token, Bundle icicle,
5759            PersistableBundle persistentState, CharSequence description) {
5760        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5761
5762        // Refuse possible leaked file descriptors
5763        if (icicle != null && icicle.hasFileDescriptors()) {
5764            throw new IllegalArgumentException("File descriptors passed in Bundle");
5765        }
5766
5767        final long origId = Binder.clearCallingIdentity();
5768
5769        synchronized (this) {
5770            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5771            if (r != null) {
5772                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5773            }
5774        }
5775
5776        trimApplications();
5777
5778        Binder.restoreCallingIdentity(origId);
5779    }
5780
5781    @Override
5782    public final void activityDestroyed(IBinder token) {
5783        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5784        synchronized (this) {
5785            ActivityStack stack = ActivityRecord.getStackLocked(token);
5786            if (stack != null) {
5787                stack.activityDestroyedLocked(token);
5788            }
5789        }
5790    }
5791
5792    @Override
5793    public final void mediaResourcesReleased(IBinder token) {
5794        final long origId = Binder.clearCallingIdentity();
5795        try {
5796            synchronized (this) {
5797                ActivityStack stack = ActivityRecord.getStackLocked(token);
5798                if (stack != null) {
5799                    stack.mediaResourcesReleased(token);
5800                }
5801            }
5802        } finally {
5803            Binder.restoreCallingIdentity(origId);
5804        }
5805    }
5806
5807    @Override
5808    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5809        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5810    }
5811
5812    @Override
5813    public final void notifyEnterAnimationComplete(IBinder token) {
5814        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5815    }
5816
5817    @Override
5818    public String getCallingPackage(IBinder token) {
5819        synchronized (this) {
5820            ActivityRecord r = getCallingRecordLocked(token);
5821            return r != null ? r.info.packageName : null;
5822        }
5823    }
5824
5825    @Override
5826    public ComponentName getCallingActivity(IBinder token) {
5827        synchronized (this) {
5828            ActivityRecord r = getCallingRecordLocked(token);
5829            return r != null ? r.intent.getComponent() : null;
5830        }
5831    }
5832
5833    private ActivityRecord getCallingRecordLocked(IBinder token) {
5834        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5835        if (r == null) {
5836            return null;
5837        }
5838        return r.resultTo;
5839    }
5840
5841    @Override
5842    public ComponentName getActivityClassForToken(IBinder token) {
5843        synchronized(this) {
5844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5845            if (r == null) {
5846                return null;
5847            }
5848            return r.intent.getComponent();
5849        }
5850    }
5851
5852    @Override
5853    public String getPackageForToken(IBinder token) {
5854        synchronized(this) {
5855            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5856            if (r == null) {
5857                return null;
5858            }
5859            return r.packageName;
5860        }
5861    }
5862
5863    @Override
5864    public IIntentSender getIntentSender(int type,
5865            String packageName, IBinder token, String resultWho,
5866            int requestCode, Intent[] intents, String[] resolvedTypes,
5867            int flags, Bundle options, int userId) {
5868        enforceNotIsolatedCaller("getIntentSender");
5869        // Refuse possible leaked file descriptors
5870        if (intents != null) {
5871            if (intents.length < 1) {
5872                throw new IllegalArgumentException("Intents array length must be >= 1");
5873            }
5874            for (int i=0; i<intents.length; i++) {
5875                Intent intent = intents[i];
5876                if (intent != null) {
5877                    if (intent.hasFileDescriptors()) {
5878                        throw new IllegalArgumentException("File descriptors passed in Intent");
5879                    }
5880                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5881                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5882                        throw new IllegalArgumentException(
5883                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5884                    }
5885                    intents[i] = new Intent(intent);
5886                }
5887            }
5888            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5889                throw new IllegalArgumentException(
5890                        "Intent array length does not match resolvedTypes length");
5891            }
5892        }
5893        if (options != null) {
5894            if (options.hasFileDescriptors()) {
5895                throw new IllegalArgumentException("File descriptors passed in options");
5896            }
5897        }
5898
5899        synchronized(this) {
5900            int callingUid = Binder.getCallingUid();
5901            int origUserId = userId;
5902            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5903                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5904                    ALLOW_NON_FULL, "getIntentSender", null);
5905            if (origUserId == UserHandle.USER_CURRENT) {
5906                // We don't want to evaluate this until the pending intent is
5907                // actually executed.  However, we do want to always do the
5908                // security checking for it above.
5909                userId = UserHandle.USER_CURRENT;
5910            }
5911            try {
5912                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5913                    int uid = AppGlobals.getPackageManager()
5914                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5915                    if (!UserHandle.isSameApp(callingUid, uid)) {
5916                        String msg = "Permission Denial: getIntentSender() from pid="
5917                            + Binder.getCallingPid()
5918                            + ", uid=" + Binder.getCallingUid()
5919                            + ", (need uid=" + uid + ")"
5920                            + " is not allowed to send as package " + packageName;
5921                        Slog.w(TAG, msg);
5922                        throw new SecurityException(msg);
5923                    }
5924                }
5925
5926                return getIntentSenderLocked(type, packageName, callingUid, userId,
5927                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5928
5929            } catch (RemoteException e) {
5930                throw new SecurityException(e);
5931            }
5932        }
5933    }
5934
5935    IIntentSender getIntentSenderLocked(int type, String packageName,
5936            int callingUid, int userId, IBinder token, String resultWho,
5937            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5938            Bundle options) {
5939        if (DEBUG_MU)
5940            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5941        ActivityRecord activity = null;
5942        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5943            activity = ActivityRecord.isInStackLocked(token);
5944            if (activity == null) {
5945                return null;
5946            }
5947            if (activity.finishing) {
5948                return null;
5949            }
5950        }
5951
5952        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5953        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5954        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5955        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5956                |PendingIntent.FLAG_UPDATE_CURRENT);
5957
5958        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5959                type, packageName, activity, resultWho,
5960                requestCode, intents, resolvedTypes, flags, options, userId);
5961        WeakReference<PendingIntentRecord> ref;
5962        ref = mIntentSenderRecords.get(key);
5963        PendingIntentRecord rec = ref != null ? ref.get() : null;
5964        if (rec != null) {
5965            if (!cancelCurrent) {
5966                if (updateCurrent) {
5967                    if (rec.key.requestIntent != null) {
5968                        rec.key.requestIntent.replaceExtras(intents != null ?
5969                                intents[intents.length - 1] : null);
5970                    }
5971                    if (intents != null) {
5972                        intents[intents.length-1] = rec.key.requestIntent;
5973                        rec.key.allIntents = intents;
5974                        rec.key.allResolvedTypes = resolvedTypes;
5975                    } else {
5976                        rec.key.allIntents = null;
5977                        rec.key.allResolvedTypes = null;
5978                    }
5979                }
5980                return rec;
5981            }
5982            rec.canceled = true;
5983            mIntentSenderRecords.remove(key);
5984        }
5985        if (noCreate) {
5986            return rec;
5987        }
5988        rec = new PendingIntentRecord(this, key, callingUid);
5989        mIntentSenderRecords.put(key, rec.ref);
5990        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5991            if (activity.pendingResults == null) {
5992                activity.pendingResults
5993                        = new HashSet<WeakReference<PendingIntentRecord>>();
5994            }
5995            activity.pendingResults.add(rec.ref);
5996        }
5997        return rec;
5998    }
5999
6000    @Override
6001    public void cancelIntentSender(IIntentSender sender) {
6002        if (!(sender instanceof PendingIntentRecord)) {
6003            return;
6004        }
6005        synchronized(this) {
6006            PendingIntentRecord rec = (PendingIntentRecord)sender;
6007            try {
6008                int uid = AppGlobals.getPackageManager()
6009                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6010                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6011                    String msg = "Permission Denial: cancelIntentSender() from pid="
6012                        + Binder.getCallingPid()
6013                        + ", uid=" + Binder.getCallingUid()
6014                        + " is not allowed to cancel packges "
6015                        + rec.key.packageName;
6016                    Slog.w(TAG, msg);
6017                    throw new SecurityException(msg);
6018                }
6019            } catch (RemoteException e) {
6020                throw new SecurityException(e);
6021            }
6022            cancelIntentSenderLocked(rec, true);
6023        }
6024    }
6025
6026    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6027        rec.canceled = true;
6028        mIntentSenderRecords.remove(rec.key);
6029        if (cleanActivity && rec.key.activity != null) {
6030            rec.key.activity.pendingResults.remove(rec.ref);
6031        }
6032    }
6033
6034    @Override
6035    public String getPackageForIntentSender(IIntentSender pendingResult) {
6036        if (!(pendingResult instanceof PendingIntentRecord)) {
6037            return null;
6038        }
6039        try {
6040            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6041            return res.key.packageName;
6042        } catch (ClassCastException e) {
6043        }
6044        return null;
6045    }
6046
6047    @Override
6048    public int getUidForIntentSender(IIntentSender sender) {
6049        if (sender instanceof PendingIntentRecord) {
6050            try {
6051                PendingIntentRecord res = (PendingIntentRecord)sender;
6052                return res.uid;
6053            } catch (ClassCastException e) {
6054            }
6055        }
6056        return -1;
6057    }
6058
6059    @Override
6060    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6061        if (!(pendingResult instanceof PendingIntentRecord)) {
6062            return false;
6063        }
6064        try {
6065            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6066            if (res.key.allIntents == null) {
6067                return false;
6068            }
6069            for (int i=0; i<res.key.allIntents.length; i++) {
6070                Intent intent = res.key.allIntents[i];
6071                if (intent.getPackage() != null && intent.getComponent() != null) {
6072                    return false;
6073                }
6074            }
6075            return true;
6076        } catch (ClassCastException e) {
6077        }
6078        return false;
6079    }
6080
6081    @Override
6082    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6083        if (!(pendingResult instanceof PendingIntentRecord)) {
6084            return false;
6085        }
6086        try {
6087            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6088            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6089                return true;
6090            }
6091            return false;
6092        } catch (ClassCastException e) {
6093        }
6094        return false;
6095    }
6096
6097    @Override
6098    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6099        if (!(pendingResult instanceof PendingIntentRecord)) {
6100            return null;
6101        }
6102        try {
6103            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6104            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6105        } catch (ClassCastException e) {
6106        }
6107        return null;
6108    }
6109
6110    @Override
6111    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6112        if (!(pendingResult instanceof PendingIntentRecord)) {
6113            return null;
6114        }
6115        try {
6116            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6117            Intent intent = res.key.requestIntent;
6118            if (intent != null) {
6119                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6120                        || res.lastTagPrefix.equals(prefix))) {
6121                    return res.lastTag;
6122                }
6123                res.lastTagPrefix = prefix;
6124                StringBuilder sb = new StringBuilder(128);
6125                if (prefix != null) {
6126                    sb.append(prefix);
6127                }
6128                if (intent.getAction() != null) {
6129                    sb.append(intent.getAction());
6130                } else if (intent.getComponent() != null) {
6131                    intent.getComponent().appendShortString(sb);
6132                } else {
6133                    sb.append("?");
6134                }
6135                return res.lastTag = sb.toString();
6136            }
6137        } catch (ClassCastException e) {
6138        }
6139        return null;
6140    }
6141
6142    @Override
6143    public void setProcessLimit(int max) {
6144        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6145                "setProcessLimit()");
6146        synchronized (this) {
6147            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6148            mProcessLimitOverride = max;
6149        }
6150        trimApplications();
6151    }
6152
6153    @Override
6154    public int getProcessLimit() {
6155        synchronized (this) {
6156            return mProcessLimitOverride;
6157        }
6158    }
6159
6160    void foregroundTokenDied(ForegroundToken token) {
6161        synchronized (ActivityManagerService.this) {
6162            synchronized (mPidsSelfLocked) {
6163                ForegroundToken cur
6164                    = mForegroundProcesses.get(token.pid);
6165                if (cur != token) {
6166                    return;
6167                }
6168                mForegroundProcesses.remove(token.pid);
6169                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6170                if (pr == null) {
6171                    return;
6172                }
6173                pr.forcingToForeground = null;
6174                updateProcessForegroundLocked(pr, false, false);
6175            }
6176            updateOomAdjLocked();
6177        }
6178    }
6179
6180    @Override
6181    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6182        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6183                "setProcessForeground()");
6184        synchronized(this) {
6185            boolean changed = false;
6186
6187            synchronized (mPidsSelfLocked) {
6188                ProcessRecord pr = mPidsSelfLocked.get(pid);
6189                if (pr == null && isForeground) {
6190                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6191                    return;
6192                }
6193                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6194                if (oldToken != null) {
6195                    oldToken.token.unlinkToDeath(oldToken, 0);
6196                    mForegroundProcesses.remove(pid);
6197                    if (pr != null) {
6198                        pr.forcingToForeground = null;
6199                    }
6200                    changed = true;
6201                }
6202                if (isForeground && token != null) {
6203                    ForegroundToken newToken = new ForegroundToken() {
6204                        @Override
6205                        public void binderDied() {
6206                            foregroundTokenDied(this);
6207                        }
6208                    };
6209                    newToken.pid = pid;
6210                    newToken.token = token;
6211                    try {
6212                        token.linkToDeath(newToken, 0);
6213                        mForegroundProcesses.put(pid, newToken);
6214                        pr.forcingToForeground = token;
6215                        changed = true;
6216                    } catch (RemoteException e) {
6217                        // If the process died while doing this, we will later
6218                        // do the cleanup with the process death link.
6219                    }
6220                }
6221            }
6222
6223            if (changed) {
6224                updateOomAdjLocked();
6225            }
6226        }
6227    }
6228
6229    // =========================================================
6230    // PERMISSIONS
6231    // =========================================================
6232
6233    static class PermissionController extends IPermissionController.Stub {
6234        ActivityManagerService mActivityManagerService;
6235        PermissionController(ActivityManagerService activityManagerService) {
6236            mActivityManagerService = activityManagerService;
6237        }
6238
6239        @Override
6240        public boolean checkPermission(String permission, int pid, int uid) {
6241            return mActivityManagerService.checkPermission(permission, pid,
6242                    uid) == PackageManager.PERMISSION_GRANTED;
6243        }
6244    }
6245
6246    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6247        @Override
6248        public int checkComponentPermission(String permission, int pid, int uid,
6249                int owningUid, boolean exported) {
6250            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6251                    owningUid, exported);
6252        }
6253
6254        @Override
6255        public Object getAMSLock() {
6256            return ActivityManagerService.this;
6257        }
6258    }
6259
6260    /**
6261     * This can be called with or without the global lock held.
6262     */
6263    int checkComponentPermission(String permission, int pid, int uid,
6264            int owningUid, boolean exported) {
6265        // We might be performing an operation on behalf of an indirect binder
6266        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6267        // client identity accordingly before proceeding.
6268        Identity tlsIdentity = sCallerIdentity.get();
6269        if (tlsIdentity != null) {
6270            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6271                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6272            uid = tlsIdentity.uid;
6273            pid = tlsIdentity.pid;
6274        }
6275
6276        if (pid == MY_PID) {
6277            return PackageManager.PERMISSION_GRANTED;
6278        }
6279
6280        return ActivityManager.checkComponentPermission(permission, uid,
6281                owningUid, exported);
6282    }
6283
6284    /**
6285     * As the only public entry point for permissions checking, this method
6286     * can enforce the semantic that requesting a check on a null global
6287     * permission is automatically denied.  (Internally a null permission
6288     * string is used when calling {@link #checkComponentPermission} in cases
6289     * when only uid-based security is needed.)
6290     *
6291     * This can be called with or without the global lock held.
6292     */
6293    @Override
6294    public int checkPermission(String permission, int pid, int uid) {
6295        if (permission == null) {
6296            return PackageManager.PERMISSION_DENIED;
6297        }
6298        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6299    }
6300
6301    /**
6302     * Binder IPC calls go through the public entry point.
6303     * This can be called with or without the global lock held.
6304     */
6305    int checkCallingPermission(String permission) {
6306        return checkPermission(permission,
6307                Binder.getCallingPid(),
6308                UserHandle.getAppId(Binder.getCallingUid()));
6309    }
6310
6311    /**
6312     * This can be called with or without the global lock held.
6313     */
6314    void enforceCallingPermission(String permission, String func) {
6315        if (checkCallingPermission(permission)
6316                == PackageManager.PERMISSION_GRANTED) {
6317            return;
6318        }
6319
6320        String msg = "Permission Denial: " + func + " from pid="
6321                + Binder.getCallingPid()
6322                + ", uid=" + Binder.getCallingUid()
6323                + " requires " + permission;
6324        Slog.w(TAG, msg);
6325        throw new SecurityException(msg);
6326    }
6327
6328    /**
6329     * Determine if UID is holding permissions required to access {@link Uri} in
6330     * the given {@link ProviderInfo}. Final permission checking is always done
6331     * in {@link ContentProvider}.
6332     */
6333    private final boolean checkHoldingPermissionsLocked(
6334            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6335        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6336                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6337        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6338            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6339                    != PERMISSION_GRANTED) {
6340                return false;
6341            }
6342        }
6343        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6344    }
6345
6346    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6347            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6348        if (pi.applicationInfo.uid == uid) {
6349            return true;
6350        } else if (!pi.exported) {
6351            return false;
6352        }
6353
6354        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6355        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6356        try {
6357            // check if target holds top-level <provider> permissions
6358            if (!readMet && pi.readPermission != null && considerUidPermissions
6359                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6360                readMet = true;
6361            }
6362            if (!writeMet && pi.writePermission != null && considerUidPermissions
6363                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6364                writeMet = true;
6365            }
6366
6367            // track if unprotected read/write is allowed; any denied
6368            // <path-permission> below removes this ability
6369            boolean allowDefaultRead = pi.readPermission == null;
6370            boolean allowDefaultWrite = pi.writePermission == null;
6371
6372            // check if target holds any <path-permission> that match uri
6373            final PathPermission[] pps = pi.pathPermissions;
6374            if (pps != null) {
6375                final String path = grantUri.uri.getPath();
6376                int i = pps.length;
6377                while (i > 0 && (!readMet || !writeMet)) {
6378                    i--;
6379                    PathPermission pp = pps[i];
6380                    if (pp.match(path)) {
6381                        if (!readMet) {
6382                            final String pprperm = pp.getReadPermission();
6383                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6384                                    + pprperm + " for " + pp.getPath()
6385                                    + ": match=" + pp.match(path)
6386                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6387                            if (pprperm != null) {
6388                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6389                                        == PERMISSION_GRANTED) {
6390                                    readMet = true;
6391                                } else {
6392                                    allowDefaultRead = false;
6393                                }
6394                            }
6395                        }
6396                        if (!writeMet) {
6397                            final String ppwperm = pp.getWritePermission();
6398                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6399                                    + ppwperm + " for " + pp.getPath()
6400                                    + ": match=" + pp.match(path)
6401                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6402                            if (ppwperm != null) {
6403                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6404                                        == PERMISSION_GRANTED) {
6405                                    writeMet = true;
6406                                } else {
6407                                    allowDefaultWrite = false;
6408                                }
6409                            }
6410                        }
6411                    }
6412                }
6413            }
6414
6415            // grant unprotected <provider> read/write, if not blocked by
6416            // <path-permission> above
6417            if (allowDefaultRead) readMet = true;
6418            if (allowDefaultWrite) writeMet = true;
6419
6420        } catch (RemoteException e) {
6421            return false;
6422        }
6423
6424        return readMet && writeMet;
6425    }
6426
6427    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6428        ProviderInfo pi = null;
6429        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6430        if (cpr != null) {
6431            pi = cpr.info;
6432        } else {
6433            try {
6434                pi = AppGlobals.getPackageManager().resolveContentProvider(
6435                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6436            } catch (RemoteException ex) {
6437            }
6438        }
6439        return pi;
6440    }
6441
6442    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6443        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6444        if (targetUris != null) {
6445            return targetUris.get(grantUri);
6446        }
6447        return null;
6448    }
6449
6450    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6451            String targetPkg, int targetUid, GrantUri grantUri) {
6452        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6453        if (targetUris == null) {
6454            targetUris = Maps.newArrayMap();
6455            mGrantedUriPermissions.put(targetUid, targetUris);
6456        }
6457
6458        UriPermission perm = targetUris.get(grantUri);
6459        if (perm == null) {
6460            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6461            targetUris.put(grantUri, perm);
6462        }
6463
6464        return perm;
6465    }
6466
6467    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6468            final int modeFlags) {
6469        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6470        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6471                : UriPermission.STRENGTH_OWNED;
6472
6473        // Root gets to do everything.
6474        if (uid == 0) {
6475            return true;
6476        }
6477
6478        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6479        if (perms == null) return false;
6480
6481        // First look for exact match
6482        final UriPermission exactPerm = perms.get(grantUri);
6483        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6484            return true;
6485        }
6486
6487        // No exact match, look for prefixes
6488        final int N = perms.size();
6489        for (int i = 0; i < N; i++) {
6490            final UriPermission perm = perms.valueAt(i);
6491            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6492                    && perm.getStrength(modeFlags) >= minStrength) {
6493                return true;
6494            }
6495        }
6496
6497        return false;
6498    }
6499
6500    @Override
6501    public int checkUriPermission(Uri uri, int pid, int uid,
6502            final int modeFlags, int userId) {
6503        enforceNotIsolatedCaller("checkUriPermission");
6504
6505        // Another redirected-binder-call permissions check as in
6506        // {@link checkComponentPermission}.
6507        Identity tlsIdentity = sCallerIdentity.get();
6508        if (tlsIdentity != null) {
6509            uid = tlsIdentity.uid;
6510            pid = tlsIdentity.pid;
6511        }
6512
6513        // Our own process gets to do everything.
6514        if (pid == MY_PID) {
6515            return PackageManager.PERMISSION_GRANTED;
6516        }
6517        synchronized (this) {
6518            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6519                    ? PackageManager.PERMISSION_GRANTED
6520                    : PackageManager.PERMISSION_DENIED;
6521        }
6522    }
6523
6524    /**
6525     * Check if the targetPkg can be granted permission to access uri by
6526     * the callingUid using the given modeFlags.  Throws a security exception
6527     * if callingUid is not allowed to do this.  Returns the uid of the target
6528     * if the URI permission grant should be performed; returns -1 if it is not
6529     * needed (for example targetPkg already has permission to access the URI).
6530     * If you already know the uid of the target, you can supply it in
6531     * lastTargetUid else set that to -1.
6532     */
6533    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6534            final int modeFlags, int lastTargetUid) {
6535        if (!Intent.isAccessUriMode(modeFlags)) {
6536            return -1;
6537        }
6538
6539        if (targetPkg != null) {
6540            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6541                    "Checking grant " + targetPkg + " permission to " + grantUri);
6542        }
6543
6544        final IPackageManager pm = AppGlobals.getPackageManager();
6545
6546        // If this is not a content: uri, we can't do anything with it.
6547        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6548            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6549                    "Can't grant URI permission for non-content URI: " + grantUri);
6550            return -1;
6551        }
6552
6553        final String authority = grantUri.uri.getAuthority();
6554        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6555        if (pi == null) {
6556            Slog.w(TAG, "No content provider found for permission check: " +
6557                    grantUri.uri.toSafeString());
6558            return -1;
6559        }
6560
6561        int targetUid = lastTargetUid;
6562        if (targetUid < 0 && targetPkg != null) {
6563            try {
6564                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6565                if (targetUid < 0) {
6566                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6567                            "Can't grant URI permission no uid for: " + targetPkg);
6568                    return -1;
6569                }
6570            } catch (RemoteException ex) {
6571                return -1;
6572            }
6573        }
6574
6575        if (targetUid >= 0) {
6576            // First...  does the target actually need this permission?
6577            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6578                // No need to grant the target this permission.
6579                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6580                        "Target " + targetPkg + " already has full permission to " + grantUri);
6581                return -1;
6582            }
6583        } else {
6584            // First...  there is no target package, so can anyone access it?
6585            boolean allowed = pi.exported;
6586            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6587                if (pi.readPermission != null) {
6588                    allowed = false;
6589                }
6590            }
6591            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6592                if (pi.writePermission != null) {
6593                    allowed = false;
6594                }
6595            }
6596            if (allowed) {
6597                return -1;
6598            }
6599        }
6600
6601        /* There is a special cross user grant if:
6602         * - The target is on another user.
6603         * - Apps on the current user can access the uri without any uid permissions.
6604         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6605         * grant uri permissions.
6606         */
6607        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6608                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6609                modeFlags, false /*without considering the uid permissions*/);
6610
6611        // Second...  is the provider allowing granting of URI permissions?
6612        if (!specialCrossUserGrant) {
6613            if (!pi.grantUriPermissions) {
6614                throw new SecurityException("Provider " + pi.packageName
6615                        + "/" + pi.name
6616                        + " does not allow granting of Uri permissions (uri "
6617                        + grantUri + ")");
6618            }
6619            if (pi.uriPermissionPatterns != null) {
6620                final int N = pi.uriPermissionPatterns.length;
6621                boolean allowed = false;
6622                for (int i=0; i<N; i++) {
6623                    if (pi.uriPermissionPatterns[i] != null
6624                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6625                        allowed = true;
6626                        break;
6627                    }
6628                }
6629                if (!allowed) {
6630                    throw new SecurityException("Provider " + pi.packageName
6631                            + "/" + pi.name
6632                            + " does not allow granting of permission to path of Uri "
6633                            + grantUri);
6634                }
6635            }
6636        }
6637
6638        // Third...  does the caller itself have permission to access
6639        // this uri?
6640        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6641            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6642                // Require they hold a strong enough Uri permission
6643                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6644                    throw new SecurityException("Uid " + callingUid
6645                            + " does not have permission to uri " + grantUri);
6646                }
6647            }
6648        }
6649        return targetUid;
6650    }
6651
6652    @Override
6653    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6654            final int modeFlags, int userId) {
6655        enforceNotIsolatedCaller("checkGrantUriPermission");
6656        synchronized(this) {
6657            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6658                    new GrantUri(userId, uri, false), modeFlags, -1);
6659        }
6660    }
6661
6662    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6663            final int modeFlags, UriPermissionOwner owner) {
6664        if (!Intent.isAccessUriMode(modeFlags)) {
6665            return;
6666        }
6667
6668        // So here we are: the caller has the assumed permission
6669        // to the uri, and the target doesn't.  Let's now give this to
6670        // the target.
6671
6672        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6673                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6674
6675        final String authority = grantUri.uri.getAuthority();
6676        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6677        if (pi == null) {
6678            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6679            return;
6680        }
6681
6682        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6683            grantUri.prefix = true;
6684        }
6685        final UriPermission perm = findOrCreateUriPermissionLocked(
6686                pi.packageName, targetPkg, targetUid, grantUri);
6687        perm.grantModes(modeFlags, owner);
6688    }
6689
6690    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6691            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6692        if (targetPkg == null) {
6693            throw new NullPointerException("targetPkg");
6694        }
6695        int targetUid;
6696        final IPackageManager pm = AppGlobals.getPackageManager();
6697        try {
6698            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6699        } catch (RemoteException ex) {
6700            return;
6701        }
6702
6703        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6704                targetUid);
6705        if (targetUid < 0) {
6706            return;
6707        }
6708
6709        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6710                owner);
6711    }
6712
6713    static class NeededUriGrants extends ArrayList<GrantUri> {
6714        final String targetPkg;
6715        final int targetUid;
6716        final int flags;
6717
6718        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6719            this.targetPkg = targetPkg;
6720            this.targetUid = targetUid;
6721            this.flags = flags;
6722        }
6723    }
6724
6725    /**
6726     * Like checkGrantUriPermissionLocked, but takes an Intent.
6727     */
6728    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6729            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6730        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6731                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6732                + " clip=" + (intent != null ? intent.getClipData() : null)
6733                + " from " + intent + "; flags=0x"
6734                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6735
6736        if (targetPkg == null) {
6737            throw new NullPointerException("targetPkg");
6738        }
6739
6740        if (intent == null) {
6741            return null;
6742        }
6743        Uri data = intent.getData();
6744        ClipData clip = intent.getClipData();
6745        if (data == null && clip == null) {
6746            return null;
6747        }
6748        // Default userId for uris in the intent (if they don't specify it themselves)
6749        int contentUserHint = intent.getContentUserHint();
6750        if (contentUserHint == UserHandle.USER_CURRENT) {
6751            contentUserHint = UserHandle.getUserId(callingUid);
6752        }
6753        final IPackageManager pm = AppGlobals.getPackageManager();
6754        int targetUid;
6755        if (needed != null) {
6756            targetUid = needed.targetUid;
6757        } else {
6758            try {
6759                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6760            } catch (RemoteException ex) {
6761                return null;
6762            }
6763            if (targetUid < 0) {
6764                if (DEBUG_URI_PERMISSION) {
6765                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6766                            + " on user " + targetUserId);
6767                }
6768                return null;
6769            }
6770        }
6771        if (data != null) {
6772            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6773            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6774                    targetUid);
6775            if (targetUid > 0) {
6776                if (needed == null) {
6777                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6778                }
6779                needed.add(grantUri);
6780            }
6781        }
6782        if (clip != null) {
6783            for (int i=0; i<clip.getItemCount(); i++) {
6784                Uri uri = clip.getItemAt(i).getUri();
6785                if (uri != null) {
6786                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6787                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6788                            targetUid);
6789                    if (targetUid > 0) {
6790                        if (needed == null) {
6791                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6792                        }
6793                        needed.add(grantUri);
6794                    }
6795                } else {
6796                    Intent clipIntent = clip.getItemAt(i).getIntent();
6797                    if (clipIntent != null) {
6798                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6799                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6800                        if (newNeeded != null) {
6801                            needed = newNeeded;
6802                        }
6803                    }
6804                }
6805            }
6806        }
6807
6808        return needed;
6809    }
6810
6811    /**
6812     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6813     */
6814    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6815            UriPermissionOwner owner) {
6816        if (needed != null) {
6817            for (int i=0; i<needed.size(); i++) {
6818                GrantUri grantUri = needed.get(i);
6819                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6820                        grantUri, needed.flags, owner);
6821            }
6822        }
6823    }
6824
6825    void grantUriPermissionFromIntentLocked(int callingUid,
6826            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6827        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6828                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6829        if (needed == null) {
6830            return;
6831        }
6832
6833        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6834    }
6835
6836    @Override
6837    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6838            final int modeFlags, int userId) {
6839        enforceNotIsolatedCaller("grantUriPermission");
6840        GrantUri grantUri = new GrantUri(userId, uri, false);
6841        synchronized(this) {
6842            final ProcessRecord r = getRecordForAppLocked(caller);
6843            if (r == null) {
6844                throw new SecurityException("Unable to find app for caller "
6845                        + caller
6846                        + " when granting permission to uri " + grantUri);
6847            }
6848            if (targetPkg == null) {
6849                throw new IllegalArgumentException("null target");
6850            }
6851            if (grantUri == null) {
6852                throw new IllegalArgumentException("null uri");
6853            }
6854
6855            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6856                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6857                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6858                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6859
6860            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6861                    UserHandle.getUserId(r.uid));
6862        }
6863    }
6864
6865    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6866        if (perm.modeFlags == 0) {
6867            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6868                    perm.targetUid);
6869            if (perms != null) {
6870                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6871                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6872
6873                perms.remove(perm.uri);
6874                if (perms.isEmpty()) {
6875                    mGrantedUriPermissions.remove(perm.targetUid);
6876                }
6877            }
6878        }
6879    }
6880
6881    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6882        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6883
6884        final IPackageManager pm = AppGlobals.getPackageManager();
6885        final String authority = grantUri.uri.getAuthority();
6886        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6887        if (pi == null) {
6888            Slog.w(TAG, "No content provider found for permission revoke: "
6889                    + grantUri.toSafeString());
6890            return;
6891        }
6892
6893        // Does the caller have this permission on the URI?
6894        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6895            // Right now, if you are not the original owner of the permission,
6896            // you are not allowed to revoke it.
6897            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6898                throw new SecurityException("Uid " + callingUid
6899                        + " does not have permission to uri " + grantUri);
6900            //}
6901        }
6902
6903        boolean persistChanged = false;
6904
6905        // Go through all of the permissions and remove any that match.
6906        int N = mGrantedUriPermissions.size();
6907        for (int i = 0; i < N; i++) {
6908            final int targetUid = mGrantedUriPermissions.keyAt(i);
6909            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6910
6911            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6912                final UriPermission perm = it.next();
6913                if (perm.uri.sourceUserId == grantUri.sourceUserId
6914                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6915                    if (DEBUG_URI_PERMISSION)
6916                        Slog.v(TAG,
6917                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6918                    persistChanged |= perm.revokeModes(
6919                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6920                    if (perm.modeFlags == 0) {
6921                        it.remove();
6922                    }
6923                }
6924            }
6925
6926            if (perms.isEmpty()) {
6927                mGrantedUriPermissions.remove(targetUid);
6928                N--;
6929                i--;
6930            }
6931        }
6932
6933        if (persistChanged) {
6934            schedulePersistUriGrants();
6935        }
6936    }
6937
6938    @Override
6939    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6940            int userId) {
6941        enforceNotIsolatedCaller("revokeUriPermission");
6942        synchronized(this) {
6943            final ProcessRecord r = getRecordForAppLocked(caller);
6944            if (r == null) {
6945                throw new SecurityException("Unable to find app for caller "
6946                        + caller
6947                        + " when revoking permission to uri " + uri);
6948            }
6949            if (uri == null) {
6950                Slog.w(TAG, "revokeUriPermission: null uri");
6951                return;
6952            }
6953
6954            if (!Intent.isAccessUriMode(modeFlags)) {
6955                return;
6956            }
6957
6958            final IPackageManager pm = AppGlobals.getPackageManager();
6959            final String authority = uri.getAuthority();
6960            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6961            if (pi == null) {
6962                Slog.w(TAG, "No content provider found for permission revoke: "
6963                        + uri.toSafeString());
6964                return;
6965            }
6966
6967            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6968        }
6969    }
6970
6971    /**
6972     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6973     * given package.
6974     *
6975     * @param packageName Package name to match, or {@code null} to apply to all
6976     *            packages.
6977     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6978     *            to all users.
6979     * @param persistable If persistable grants should be removed.
6980     */
6981    private void removeUriPermissionsForPackageLocked(
6982            String packageName, int userHandle, boolean persistable) {
6983        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6984            throw new IllegalArgumentException("Must narrow by either package or user");
6985        }
6986
6987        boolean persistChanged = false;
6988
6989        int N = mGrantedUriPermissions.size();
6990        for (int i = 0; i < N; i++) {
6991            final int targetUid = mGrantedUriPermissions.keyAt(i);
6992            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6993
6994            // Only inspect grants matching user
6995            if (userHandle == UserHandle.USER_ALL
6996                    || userHandle == UserHandle.getUserId(targetUid)) {
6997                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6998                    final UriPermission perm = it.next();
6999
7000                    // Only inspect grants matching package
7001                    if (packageName == null || perm.sourcePkg.equals(packageName)
7002                            || perm.targetPkg.equals(packageName)) {
7003                        persistChanged |= perm.revokeModes(
7004                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7005
7006                        // Only remove when no modes remain; any persisted grants
7007                        // will keep this alive.
7008                        if (perm.modeFlags == 0) {
7009                            it.remove();
7010                        }
7011                    }
7012                }
7013
7014                if (perms.isEmpty()) {
7015                    mGrantedUriPermissions.remove(targetUid);
7016                    N--;
7017                    i--;
7018                }
7019            }
7020        }
7021
7022        if (persistChanged) {
7023            schedulePersistUriGrants();
7024        }
7025    }
7026
7027    @Override
7028    public IBinder newUriPermissionOwner(String name) {
7029        enforceNotIsolatedCaller("newUriPermissionOwner");
7030        synchronized(this) {
7031            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7032            return owner.getExternalTokenLocked();
7033        }
7034    }
7035
7036    @Override
7037    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7038            final int modeFlags, int sourceUserId, int targetUserId) {
7039        synchronized(this) {
7040            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7041            if (owner == null) {
7042                throw new IllegalArgumentException("Unknown owner: " + token);
7043            }
7044            if (fromUid != Binder.getCallingUid()) {
7045                if (Binder.getCallingUid() != Process.myUid()) {
7046                    // Only system code can grant URI permissions on behalf
7047                    // of other users.
7048                    throw new SecurityException("nice try");
7049                }
7050            }
7051            if (targetPkg == null) {
7052                throw new IllegalArgumentException("null target");
7053            }
7054            if (uri == null) {
7055                throw new IllegalArgumentException("null uri");
7056            }
7057
7058            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7059                    modeFlags, owner, targetUserId);
7060        }
7061    }
7062
7063    @Override
7064    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7065        synchronized(this) {
7066            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7067            if (owner == null) {
7068                throw new IllegalArgumentException("Unknown owner: " + token);
7069            }
7070
7071            if (uri == null) {
7072                owner.removeUriPermissionsLocked(mode);
7073            } else {
7074                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7075            }
7076        }
7077    }
7078
7079    private void schedulePersistUriGrants() {
7080        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7081            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7082                    10 * DateUtils.SECOND_IN_MILLIS);
7083        }
7084    }
7085
7086    private void writeGrantedUriPermissions() {
7087        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7088
7089        // Snapshot permissions so we can persist without lock
7090        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7091        synchronized (this) {
7092            final int size = mGrantedUriPermissions.size();
7093            for (int i = 0; i < size; i++) {
7094                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7095                for (UriPermission perm : perms.values()) {
7096                    if (perm.persistedModeFlags != 0) {
7097                        persist.add(perm.snapshot());
7098                    }
7099                }
7100            }
7101        }
7102
7103        FileOutputStream fos = null;
7104        try {
7105            fos = mGrantFile.startWrite();
7106
7107            XmlSerializer out = new FastXmlSerializer();
7108            out.setOutput(fos, "utf-8");
7109            out.startDocument(null, true);
7110            out.startTag(null, TAG_URI_GRANTS);
7111            for (UriPermission.Snapshot perm : persist) {
7112                out.startTag(null, TAG_URI_GRANT);
7113                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7114                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7115                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7116                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7117                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7118                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7119                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7120                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7121                out.endTag(null, TAG_URI_GRANT);
7122            }
7123            out.endTag(null, TAG_URI_GRANTS);
7124            out.endDocument();
7125
7126            mGrantFile.finishWrite(fos);
7127        } catch (IOException e) {
7128            if (fos != null) {
7129                mGrantFile.failWrite(fos);
7130            }
7131        }
7132    }
7133
7134    private void readGrantedUriPermissionsLocked() {
7135        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7136
7137        final long now = System.currentTimeMillis();
7138
7139        FileInputStream fis = null;
7140        try {
7141            fis = mGrantFile.openRead();
7142            final XmlPullParser in = Xml.newPullParser();
7143            in.setInput(fis, null);
7144
7145            int type;
7146            while ((type = in.next()) != END_DOCUMENT) {
7147                final String tag = in.getName();
7148                if (type == START_TAG) {
7149                    if (TAG_URI_GRANT.equals(tag)) {
7150                        final int sourceUserId;
7151                        final int targetUserId;
7152                        final int userHandle = readIntAttribute(in,
7153                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7154                        if (userHandle != UserHandle.USER_NULL) {
7155                            // For backwards compatibility.
7156                            sourceUserId = userHandle;
7157                            targetUserId = userHandle;
7158                        } else {
7159                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7160                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7161                        }
7162                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7163                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7164                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7165                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7166                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7167                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7168
7169                        // Sanity check that provider still belongs to source package
7170                        final ProviderInfo pi = getProviderInfoLocked(
7171                                uri.getAuthority(), sourceUserId);
7172                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7173                            int targetUid = -1;
7174                            try {
7175                                targetUid = AppGlobals.getPackageManager()
7176                                        .getPackageUid(targetPkg, targetUserId);
7177                            } catch (RemoteException e) {
7178                            }
7179                            if (targetUid != -1) {
7180                                final UriPermission perm = findOrCreateUriPermissionLocked(
7181                                        sourcePkg, targetPkg, targetUid,
7182                                        new GrantUri(sourceUserId, uri, prefix));
7183                                perm.initPersistedModes(modeFlags, createdTime);
7184                            }
7185                        } else {
7186                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7187                                    + " but instead found " + pi);
7188                        }
7189                    }
7190                }
7191            }
7192        } catch (FileNotFoundException e) {
7193            // Missing grants is okay
7194        } catch (IOException e) {
7195            Log.wtf(TAG, "Failed reading Uri grants", e);
7196        } catch (XmlPullParserException e) {
7197            Log.wtf(TAG, "Failed reading Uri grants", e);
7198        } finally {
7199            IoUtils.closeQuietly(fis);
7200        }
7201    }
7202
7203    @Override
7204    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7205        enforceNotIsolatedCaller("takePersistableUriPermission");
7206
7207        Preconditions.checkFlagsArgument(modeFlags,
7208                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7209
7210        synchronized (this) {
7211            final int callingUid = Binder.getCallingUid();
7212            boolean persistChanged = false;
7213            GrantUri grantUri = new GrantUri(userId, uri, false);
7214
7215            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7216                    new GrantUri(userId, uri, false));
7217            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7218                    new GrantUri(userId, uri, true));
7219
7220            final boolean exactValid = (exactPerm != null)
7221                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7222            final boolean prefixValid = (prefixPerm != null)
7223                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7224
7225            if (!(exactValid || prefixValid)) {
7226                throw new SecurityException("No persistable permission grants found for UID "
7227                        + callingUid + " and Uri " + grantUri.toSafeString());
7228            }
7229
7230            if (exactValid) {
7231                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7232            }
7233            if (prefixValid) {
7234                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7235            }
7236
7237            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7238
7239            if (persistChanged) {
7240                schedulePersistUriGrants();
7241            }
7242        }
7243    }
7244
7245    @Override
7246    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7247        enforceNotIsolatedCaller("releasePersistableUriPermission");
7248
7249        Preconditions.checkFlagsArgument(modeFlags,
7250                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7251
7252        synchronized (this) {
7253            final int callingUid = Binder.getCallingUid();
7254            boolean persistChanged = false;
7255
7256            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7257                    new GrantUri(userId, uri, false));
7258            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7259                    new GrantUri(userId, uri, true));
7260            if (exactPerm == null && prefixPerm == null) {
7261                throw new SecurityException("No permission grants found for UID " + callingUid
7262                        + " and Uri " + uri.toSafeString());
7263            }
7264
7265            if (exactPerm != null) {
7266                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7267                removeUriPermissionIfNeededLocked(exactPerm);
7268            }
7269            if (prefixPerm != null) {
7270                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7271                removeUriPermissionIfNeededLocked(prefixPerm);
7272            }
7273
7274            if (persistChanged) {
7275                schedulePersistUriGrants();
7276            }
7277        }
7278    }
7279
7280    /**
7281     * Prune any older {@link UriPermission} for the given UID until outstanding
7282     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7283     *
7284     * @return if any mutations occured that require persisting.
7285     */
7286    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7287        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7288        if (perms == null) return false;
7289        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7290
7291        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7292        for (UriPermission perm : perms.values()) {
7293            if (perm.persistedModeFlags != 0) {
7294                persisted.add(perm);
7295            }
7296        }
7297
7298        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7299        if (trimCount <= 0) return false;
7300
7301        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7302        for (int i = 0; i < trimCount; i++) {
7303            final UriPermission perm = persisted.get(i);
7304
7305            if (DEBUG_URI_PERMISSION) {
7306                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7307            }
7308
7309            perm.releasePersistableModes(~0);
7310            removeUriPermissionIfNeededLocked(perm);
7311        }
7312
7313        return true;
7314    }
7315
7316    @Override
7317    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7318            String packageName, boolean incoming) {
7319        enforceNotIsolatedCaller("getPersistedUriPermissions");
7320        Preconditions.checkNotNull(packageName, "packageName");
7321
7322        final int callingUid = Binder.getCallingUid();
7323        final IPackageManager pm = AppGlobals.getPackageManager();
7324        try {
7325            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7326            if (packageUid != callingUid) {
7327                throw new SecurityException(
7328                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7329            }
7330        } catch (RemoteException e) {
7331            throw new SecurityException("Failed to verify package name ownership");
7332        }
7333
7334        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7335        synchronized (this) {
7336            if (incoming) {
7337                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7338                        callingUid);
7339                if (perms == null) {
7340                    Slog.w(TAG, "No permission grants found for " + packageName);
7341                } else {
7342                    for (UriPermission perm : perms.values()) {
7343                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7344                            result.add(perm.buildPersistedPublicApiObject());
7345                        }
7346                    }
7347                }
7348            } else {
7349                final int size = mGrantedUriPermissions.size();
7350                for (int i = 0; i < size; i++) {
7351                    final ArrayMap<GrantUri, UriPermission> perms =
7352                            mGrantedUriPermissions.valueAt(i);
7353                    for (UriPermission perm : perms.values()) {
7354                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7355                            result.add(perm.buildPersistedPublicApiObject());
7356                        }
7357                    }
7358                }
7359            }
7360        }
7361        return new ParceledListSlice<android.content.UriPermission>(result);
7362    }
7363
7364    @Override
7365    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7366        synchronized (this) {
7367            ProcessRecord app =
7368                who != null ? getRecordForAppLocked(who) : null;
7369            if (app == null) return;
7370
7371            Message msg = Message.obtain();
7372            msg.what = WAIT_FOR_DEBUGGER_MSG;
7373            msg.obj = app;
7374            msg.arg1 = waiting ? 1 : 0;
7375            mHandler.sendMessage(msg);
7376        }
7377    }
7378
7379    @Override
7380    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7381        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7382        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7383        outInfo.availMem = Process.getFreeMemory();
7384        outInfo.totalMem = Process.getTotalMemory();
7385        outInfo.threshold = homeAppMem;
7386        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7387        outInfo.hiddenAppThreshold = cachedAppMem;
7388        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7389                ProcessList.SERVICE_ADJ);
7390        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7391                ProcessList.VISIBLE_APP_ADJ);
7392        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7393                ProcessList.FOREGROUND_APP_ADJ);
7394    }
7395
7396    // =========================================================
7397    // TASK MANAGEMENT
7398    // =========================================================
7399
7400    @Override
7401    public List<IAppTask> getAppTasks() {
7402        final PackageManager pm = mContext.getPackageManager();
7403        int callingUid = Binder.getCallingUid();
7404        long ident = Binder.clearCallingIdentity();
7405
7406        // Compose the list of packages for this id to test against
7407        HashSet<String> packages = new HashSet<String>();
7408        String[] uidPackages = pm.getPackagesForUid(callingUid);
7409        for (int i = 0; i < uidPackages.length; i++) {
7410            packages.add(uidPackages[i]);
7411        }
7412
7413        synchronized(this) {
7414            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7415            try {
7416                if (localLOGV) Slog.v(TAG, "getAppTasks");
7417
7418                final int N = mRecentTasks.size();
7419                for (int i = 0; i < N; i++) {
7420                    TaskRecord tr = mRecentTasks.get(i);
7421                    // Skip tasks that do not match the package name
7422                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7423                        ActivityManager.RecentTaskInfo taskInfo =
7424                                createRecentTaskInfoFromTaskRecord(tr);
7425                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7426                        list.add(taskImpl);
7427                    }
7428                }
7429            } finally {
7430                Binder.restoreCallingIdentity(ident);
7431            }
7432            return list;
7433        }
7434    }
7435
7436    @Override
7437    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7438        final int callingUid = Binder.getCallingUid();
7439        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7440
7441        synchronized(this) {
7442            if (localLOGV) Slog.v(
7443                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7444
7445            final boolean allowed = checkCallingPermission(
7446                    android.Manifest.permission.GET_TASKS)
7447                    == PackageManager.PERMISSION_GRANTED;
7448            if (!allowed) {
7449                Slog.w(TAG, "getTasks: caller " + callingUid
7450                        + " does not hold GET_TASKS; limiting output");
7451            }
7452
7453            // TODO: Improve with MRU list from all ActivityStacks.
7454            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7455        }
7456
7457        return list;
7458    }
7459
7460    TaskRecord getMostRecentTask() {
7461        return mRecentTasks.get(0);
7462    }
7463
7464    /**
7465     * Creates a new RecentTaskInfo from a TaskRecord.
7466     */
7467    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7468        // Update the task description to reflect any changes in the task stack
7469        tr.updateTaskDescription();
7470
7471        // Compose the recent task info
7472        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7473        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7474        rti.persistentId = tr.taskId;
7475        rti.baseIntent = new Intent(tr.getBaseIntent());
7476        rti.origActivity = tr.origActivity;
7477        rti.description = tr.lastDescription;
7478        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7479        rti.userId = tr.userId;
7480        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7481        rti.firstActiveTime = tr.firstActiveTime;
7482        rti.lastActiveTime = tr.lastActiveTime;
7483        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7484        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7485        return rti;
7486    }
7487
7488    @Override
7489    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7490        final int callingUid = Binder.getCallingUid();
7491        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7492                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7493
7494        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7495        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7496        synchronized (this) {
7497            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7498                    == PackageManager.PERMISSION_GRANTED;
7499            if (!allowed) {
7500                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7501                        + " does not hold GET_TASKS; limiting output");
7502            }
7503            final boolean detailed = checkCallingPermission(
7504                    android.Manifest.permission.GET_DETAILED_TASKS)
7505                    == PackageManager.PERMISSION_GRANTED;
7506
7507            IPackageManager pm = AppGlobals.getPackageManager();
7508
7509            final int N = mRecentTasks.size();
7510            ArrayList<ActivityManager.RecentTaskInfo> res
7511                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7512                            maxNum < N ? maxNum : N);
7513
7514            final Set<Integer> includedUsers;
7515            if (includeProfiles) {
7516                includedUsers = getProfileIdsLocked(userId);
7517            } else {
7518                includedUsers = new HashSet<Integer>();
7519            }
7520            includedUsers.add(Integer.valueOf(userId));
7521
7522            // Regroup affiliated tasks together.
7523            for (int i = 0; i < N; ) {
7524                TaskRecord task = mRecentTasks.remove(i);
7525                if (mTmpRecents.contains(task)) {
7526                    continue;
7527                }
7528                int affiliatedTaskId = task.mAffiliatedTaskId;
7529                while (true) {
7530                    TaskRecord next = task.mNextAffiliate;
7531                    if (next == null) {
7532                        break;
7533                    }
7534                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7535                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7536                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7537                        task.setNextAffiliate(null);
7538                        if (next.mPrevAffiliate == task) {
7539                            next.setPrevAffiliate(null);
7540                        }
7541                        break;
7542                    }
7543                    if (next.mPrevAffiliate != task) {
7544                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7545                                next.mPrevAffiliate + " task=" + task);
7546                        next.setPrevAffiliate(null);
7547                        break;
7548                    }
7549                    if (!mRecentTasks.contains(next)) {
7550                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7551                        task.setNextAffiliate(null);
7552                        if (next.mPrevAffiliate == task) {
7553                            next.setPrevAffiliate(null);
7554                        }
7555                        break;
7556                    }
7557                    task = next;
7558                }
7559                // task is now the end of the list
7560                do {
7561                    mRecentTasks.remove(task);
7562                    mRecentTasks.add(i++, task);
7563                    mTmpRecents.add(task);
7564                } while ((task = task.mPrevAffiliate) != null);
7565            }
7566            mTmpRecents.clear();
7567            // mRecentTasks is now in sorted, affiliated order.
7568
7569            for (int i=0; i<N && maxNum > 0; i++) {
7570                TaskRecord tr = mRecentTasks.get(i);
7571                // Only add calling user or related users recent tasks
7572                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7573
7574                // Return the entry if desired by the caller.  We always return
7575                // the first entry, because callers always expect this to be the
7576                // foreground app.  We may filter others if the caller has
7577                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7578                // we should exclude the entry.
7579
7580                if (i == 0
7581                        || withExcluded
7582                        || (tr.intent == null)
7583                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7584                                == 0)) {
7585                    if (!allowed) {
7586                        // If the caller doesn't have the GET_TASKS permission, then only
7587                        // allow them to see a small subset of tasks -- their own and home.
7588                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7589                            continue;
7590                        }
7591                    }
7592                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7593                        // Don't include auto remove tasks that are finished or finishing.
7594                        continue;
7595                    }
7596
7597                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7598                    if (!detailed) {
7599                        rti.baseIntent.replaceExtras((Bundle)null);
7600                    }
7601
7602                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7603                        // Check whether this activity is currently available.
7604                        try {
7605                            if (rti.origActivity != null) {
7606                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7607                                        == null) {
7608                                    continue;
7609                                }
7610                            } else if (rti.baseIntent != null) {
7611                                if (pm.queryIntentActivities(rti.baseIntent,
7612                                        null, 0, userId) == null) {
7613                                    continue;
7614                                }
7615                            }
7616                        } catch (RemoteException e) {
7617                            // Will never happen.
7618                        }
7619                    }
7620
7621                    res.add(rti);
7622                    maxNum--;
7623                }
7624            }
7625            return res;
7626        }
7627    }
7628
7629    private TaskRecord recentTaskForIdLocked(int id) {
7630        final int N = mRecentTasks.size();
7631            for (int i=0; i<N; i++) {
7632                TaskRecord tr = mRecentTasks.get(i);
7633                if (tr.taskId == id) {
7634                    return tr;
7635                }
7636            }
7637            return null;
7638    }
7639
7640    @Override
7641    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7642        synchronized (this) {
7643            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7644                    "getTaskThumbnail()");
7645            TaskRecord tr = recentTaskForIdLocked(id);
7646            if (tr != null) {
7647                return tr.getTaskThumbnailLocked();
7648            }
7649        }
7650        return null;
7651    }
7652
7653    @Override
7654    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7655        synchronized (this) {
7656            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7657            if (r != null) {
7658                r.taskDescription = td;
7659                r.task.updateTaskDescription();
7660            }
7661        }
7662    }
7663
7664    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7665        if (!pr.killedByAm) {
7666            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7667            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7668                    pr.processName, pr.setAdj, reason);
7669            pr.killedByAm = true;
7670            Process.killProcessQuiet(pr.pid);
7671            Process.killProcessGroup(pr.info.uid, pr.pid);
7672        }
7673    }
7674
7675    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7676        tr.disposeThumbnail();
7677        mRecentTasks.remove(tr);
7678        tr.closeRecentsChain();
7679        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7680        Intent baseIntent = new Intent(
7681                tr.intent != null ? tr.intent : tr.affinityIntent);
7682        ComponentName component = baseIntent.getComponent();
7683        if (component == null) {
7684            Slog.w(TAG, "Now component for base intent of task: " + tr);
7685            return;
7686        }
7687
7688        // Find any running services associated with this app.
7689        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7690
7691        if (killProcesses) {
7692            // Find any running processes associated with this app.
7693            final String pkg = component.getPackageName();
7694            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7695            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7696            for (int i=0; i<pmap.size(); i++) {
7697                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7698                for (int j=0; j<uids.size(); j++) {
7699                    ProcessRecord proc = uids.valueAt(j);
7700                    if (proc.userId != tr.userId) {
7701                        continue;
7702                    }
7703                    if (!proc.pkgList.containsKey(pkg)) {
7704                        continue;
7705                    }
7706                    procs.add(proc);
7707                }
7708            }
7709
7710            // Kill the running processes.
7711            for (int i=0; i<procs.size(); i++) {
7712                ProcessRecord pr = procs.get(i);
7713                if (pr == mHomeProcess) {
7714                    // Don't kill the home process along with tasks from the same package.
7715                    continue;
7716                }
7717                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7718                    killUnneededProcessLocked(pr, "remove task");
7719                } else {
7720                    pr.waitingToKill = "remove task";
7721                }
7722            }
7723        }
7724    }
7725
7726    /**
7727     * Removes the task with the specified task id.
7728     *
7729     * @param taskId Identifier of the task to be removed.
7730     * @param flags Additional operational flags.  May be 0 or
7731     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7732     * @return Returns true if the given task was found and removed.
7733     */
7734    private boolean removeTaskByIdLocked(int taskId, int flags) {
7735        TaskRecord tr = recentTaskForIdLocked(taskId);
7736        if (tr != null) {
7737            tr.removeTaskActivitiesLocked();
7738            cleanUpRemovedTaskLocked(tr, flags);
7739            if (tr.isPersistable) {
7740                notifyTaskPersisterLocked(null, true);
7741            }
7742            return true;
7743        }
7744        return false;
7745    }
7746
7747    @Override
7748    public boolean removeTask(int taskId, int flags) {
7749        synchronized (this) {
7750            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7751                    "removeTask()");
7752            long ident = Binder.clearCallingIdentity();
7753            try {
7754                return removeTaskByIdLocked(taskId, flags);
7755            } finally {
7756                Binder.restoreCallingIdentity(ident);
7757            }
7758        }
7759    }
7760
7761    /**
7762     * TODO: Add mController hook
7763     */
7764    @Override
7765    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7766        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7767                "moveTaskToFront()");
7768
7769        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7770        synchronized(this) {
7771            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7772                    Binder.getCallingUid(), "Task to front")) {
7773                ActivityOptions.abort(options);
7774                return;
7775            }
7776            final long origId = Binder.clearCallingIdentity();
7777            try {
7778                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7779                if (task == null) {
7780                    return;
7781                }
7782                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7783                    mStackSupervisor.showLockTaskToast();
7784                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7785                    return;
7786                }
7787                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7788                if (prev != null && prev.isRecentsActivity()) {
7789                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7790                }
7791                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7792            } finally {
7793                Binder.restoreCallingIdentity(origId);
7794            }
7795            ActivityOptions.abort(options);
7796        }
7797    }
7798
7799    @Override
7800    public void moveTaskToBack(int taskId) {
7801        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7802                "moveTaskToBack()");
7803
7804        synchronized(this) {
7805            TaskRecord tr = recentTaskForIdLocked(taskId);
7806            if (tr != null) {
7807                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7808                ActivityStack stack = tr.stack;
7809                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7810                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7811                            Binder.getCallingUid(), "Task to back")) {
7812                        return;
7813                    }
7814                }
7815                final long origId = Binder.clearCallingIdentity();
7816                try {
7817                    stack.moveTaskToBackLocked(taskId, null);
7818                } finally {
7819                    Binder.restoreCallingIdentity(origId);
7820                }
7821            }
7822        }
7823    }
7824
7825    /**
7826     * Moves an activity, and all of the other activities within the same task, to the bottom
7827     * of the history stack.  The activity's order within the task is unchanged.
7828     *
7829     * @param token A reference to the activity we wish to move
7830     * @param nonRoot If false then this only works if the activity is the root
7831     *                of a task; if true it will work for any activity in a task.
7832     * @return Returns true if the move completed, false if not.
7833     */
7834    @Override
7835    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7836        enforceNotIsolatedCaller("moveActivityTaskToBack");
7837        synchronized(this) {
7838            final long origId = Binder.clearCallingIdentity();
7839            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7840            if (taskId >= 0) {
7841                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7842            }
7843            Binder.restoreCallingIdentity(origId);
7844        }
7845        return false;
7846    }
7847
7848    @Override
7849    public void moveTaskBackwards(int task) {
7850        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7851                "moveTaskBackwards()");
7852
7853        synchronized(this) {
7854            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7855                    Binder.getCallingUid(), "Task backwards")) {
7856                return;
7857            }
7858            final long origId = Binder.clearCallingIdentity();
7859            moveTaskBackwardsLocked(task);
7860            Binder.restoreCallingIdentity(origId);
7861        }
7862    }
7863
7864    private final void moveTaskBackwardsLocked(int task) {
7865        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7866    }
7867
7868    @Override
7869    public IBinder getHomeActivityToken() throws RemoteException {
7870        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7871                "getHomeActivityToken()");
7872        synchronized (this) {
7873            return mStackSupervisor.getHomeActivityToken();
7874        }
7875    }
7876
7877    @Override
7878    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7879            IActivityContainerCallback callback) throws RemoteException {
7880        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7881                "createActivityContainer()");
7882        synchronized (this) {
7883            if (parentActivityToken == null) {
7884                throw new IllegalArgumentException("parent token must not be null");
7885            }
7886            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7887            if (r == null) {
7888                return null;
7889            }
7890            if (callback == null) {
7891                throw new IllegalArgumentException("callback must not be null");
7892            }
7893            return mStackSupervisor.createActivityContainer(r, callback);
7894        }
7895    }
7896
7897    @Override
7898    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7899        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7900                "deleteActivityContainer()");
7901        synchronized (this) {
7902            mStackSupervisor.deleteActivityContainer(container);
7903        }
7904    }
7905
7906    @Override
7907    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7908            throws RemoteException {
7909        synchronized (this) {
7910            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7911            if (stack != null) {
7912                return stack.mActivityContainer;
7913            }
7914            return null;
7915        }
7916    }
7917
7918    @Override
7919    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7920        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7921                "moveTaskToStack()");
7922        if (stackId == HOME_STACK_ID) {
7923            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7924                    new RuntimeException("here").fillInStackTrace());
7925        }
7926        synchronized (this) {
7927            long ident = Binder.clearCallingIdentity();
7928            try {
7929                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7930                        + stackId + " toTop=" + toTop);
7931                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7932            } finally {
7933                Binder.restoreCallingIdentity(ident);
7934            }
7935        }
7936    }
7937
7938    @Override
7939    public void resizeStack(int stackBoxId, Rect bounds) {
7940        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7941                "resizeStackBox()");
7942        long ident = Binder.clearCallingIdentity();
7943        try {
7944            mWindowManager.resizeStack(stackBoxId, bounds);
7945        } finally {
7946            Binder.restoreCallingIdentity(ident);
7947        }
7948    }
7949
7950    @Override
7951    public List<StackInfo> getAllStackInfos() {
7952        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7953                "getAllStackInfos()");
7954        long ident = Binder.clearCallingIdentity();
7955        try {
7956            synchronized (this) {
7957                return mStackSupervisor.getAllStackInfosLocked();
7958            }
7959        } finally {
7960            Binder.restoreCallingIdentity(ident);
7961        }
7962    }
7963
7964    @Override
7965    public StackInfo getStackInfo(int stackId) {
7966        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7967                "getStackInfo()");
7968        long ident = Binder.clearCallingIdentity();
7969        try {
7970            synchronized (this) {
7971                return mStackSupervisor.getStackInfoLocked(stackId);
7972            }
7973        } finally {
7974            Binder.restoreCallingIdentity(ident);
7975        }
7976    }
7977
7978    @Override
7979    public boolean isInHomeStack(int taskId) {
7980        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7981                "getStackInfo()");
7982        long ident = Binder.clearCallingIdentity();
7983        try {
7984            synchronized (this) {
7985                TaskRecord tr = recentTaskForIdLocked(taskId);
7986                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7987            }
7988        } finally {
7989            Binder.restoreCallingIdentity(ident);
7990        }
7991    }
7992
7993    @Override
7994    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7995        synchronized(this) {
7996            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7997        }
7998    }
7999
8000    private boolean isLockTaskAuthorized(String pkg) {
8001        final DevicePolicyManager dpm = (DevicePolicyManager)
8002                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8003        try {
8004            int uid = mContext.getPackageManager().getPackageUid(pkg,
8005                    Binder.getCallingUserHandle().getIdentifier());
8006            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8007        } catch (NameNotFoundException e) {
8008            return false;
8009        }
8010    }
8011
8012    void startLockTaskMode(TaskRecord task) {
8013        final String pkg;
8014        synchronized (this) {
8015            pkg = task.intent.getComponent().getPackageName();
8016        }
8017        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8018        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8019            final TaskRecord taskRecord = task;
8020            mHandler.post(new Runnable() {
8021                @Override
8022                public void run() {
8023                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8024                }
8025            });
8026            return;
8027        }
8028        long ident = Binder.clearCallingIdentity();
8029        try {
8030            synchronized (this) {
8031                // Since we lost lock on task, make sure it is still there.
8032                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8033                if (task != null) {
8034                    if (!isSystemInitiated
8035                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8036                        throw new IllegalArgumentException("Invalid task, not in foreground");
8037                    }
8038                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8039                }
8040            }
8041        } finally {
8042            Binder.restoreCallingIdentity(ident);
8043        }
8044    }
8045
8046    @Override
8047    public void startLockTaskMode(int taskId) {
8048        final TaskRecord task;
8049        long ident = Binder.clearCallingIdentity();
8050        try {
8051            synchronized (this) {
8052                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8053            }
8054        } finally {
8055            Binder.restoreCallingIdentity(ident);
8056        }
8057        if (task != null) {
8058            startLockTaskMode(task);
8059        }
8060    }
8061
8062    @Override
8063    public void startLockTaskMode(IBinder token) {
8064        final TaskRecord task;
8065        long ident = Binder.clearCallingIdentity();
8066        try {
8067            synchronized (this) {
8068                final ActivityRecord r = ActivityRecord.forToken(token);
8069                if (r == null) {
8070                    return;
8071                }
8072                task = r.task;
8073            }
8074        } finally {
8075            Binder.restoreCallingIdentity(ident);
8076        }
8077        if (task != null) {
8078            startLockTaskMode(task);
8079        }
8080    }
8081
8082    @Override
8083    public void startLockTaskModeOnCurrent() throws RemoteException {
8084        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8085        ActivityRecord r = null;
8086        synchronized (this) {
8087            r = mStackSupervisor.topRunningActivityLocked();
8088        }
8089        startLockTaskMode(r.task);
8090    }
8091
8092    @Override
8093    public void stopLockTaskMode() {
8094        // Verify that the user matches the package of the intent for the TaskRecord
8095        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8096        // and stopLockTaskMode.
8097        final int callingUid = Binder.getCallingUid();
8098        if (callingUid != Process.SYSTEM_UID) {
8099            try {
8100                String pkg =
8101                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8102                int uid = mContext.getPackageManager().getPackageUid(pkg,
8103                        Binder.getCallingUserHandle().getIdentifier());
8104                if (uid != callingUid) {
8105                    throw new SecurityException("Invalid uid, expected " + uid);
8106                }
8107            } catch (NameNotFoundException e) {
8108                Log.d(TAG, "stopLockTaskMode " + e);
8109                return;
8110            }
8111        }
8112        long ident = Binder.clearCallingIdentity();
8113        try {
8114            Log.d(TAG, "stopLockTaskMode");
8115            // Stop lock task
8116            synchronized (this) {
8117                mStackSupervisor.setLockTaskModeLocked(null, false);
8118            }
8119        } finally {
8120            Binder.restoreCallingIdentity(ident);
8121        }
8122    }
8123
8124    @Override
8125    public void stopLockTaskModeOnCurrent() throws RemoteException {
8126        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8127        long ident = Binder.clearCallingIdentity();
8128        try {
8129            stopLockTaskMode();
8130        } finally {
8131            Binder.restoreCallingIdentity(ident);
8132        }
8133    }
8134
8135    @Override
8136    public boolean isInLockTaskMode() {
8137        synchronized (this) {
8138            return mStackSupervisor.isInLockTaskMode();
8139        }
8140    }
8141
8142    // =========================================================
8143    // CONTENT PROVIDERS
8144    // =========================================================
8145
8146    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8147        List<ProviderInfo> providers = null;
8148        try {
8149            providers = AppGlobals.getPackageManager().
8150                queryContentProviders(app.processName, app.uid,
8151                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8152        } catch (RemoteException ex) {
8153        }
8154        if (DEBUG_MU)
8155            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8156        int userId = app.userId;
8157        if (providers != null) {
8158            int N = providers.size();
8159            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8160            for (int i=0; i<N; i++) {
8161                ProviderInfo cpi =
8162                    (ProviderInfo)providers.get(i);
8163                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8164                        cpi.name, cpi.flags);
8165                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8166                    // This is a singleton provider, but a user besides the
8167                    // default user is asking to initialize a process it runs
8168                    // in...  well, no, it doesn't actually run in this process,
8169                    // it runs in the process of the default user.  Get rid of it.
8170                    providers.remove(i);
8171                    N--;
8172                    i--;
8173                    continue;
8174                }
8175
8176                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8177                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8178                if (cpr == null) {
8179                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8180                    mProviderMap.putProviderByClass(comp, cpr);
8181                }
8182                if (DEBUG_MU)
8183                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8184                app.pubProviders.put(cpi.name, cpr);
8185                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8186                    // Don't add this if it is a platform component that is marked
8187                    // to run in multiple processes, because this is actually
8188                    // part of the framework so doesn't make sense to track as a
8189                    // separate apk in the process.
8190                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8191                            mProcessStats);
8192                }
8193                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8194            }
8195        }
8196        return providers;
8197    }
8198
8199    /**
8200     * Check if {@link ProcessRecord} has a possible chance at accessing the
8201     * given {@link ProviderInfo}. Final permission checking is always done
8202     * in {@link ContentProvider}.
8203     */
8204    private final String checkContentProviderPermissionLocked(
8205            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8206        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8207        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8208        boolean checkedGrants = false;
8209        if (checkUser) {
8210            // Looking for cross-user grants before enforcing the typical cross-users permissions
8211            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8212            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8213                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8214                    return null;
8215                }
8216                checkedGrants = true;
8217            }
8218            userId = handleIncomingUser(callingPid, callingUid, userId,
8219                    false, ALLOW_NON_FULL,
8220                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8221            if (userId != tmpTargetUserId) {
8222                // When we actually went to determine the final targer user ID, this ended
8223                // up different than our initial check for the authority.  This is because
8224                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8225                // SELF.  So we need to re-check the grants again.
8226                checkedGrants = false;
8227            }
8228        }
8229        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8230                cpi.applicationInfo.uid, cpi.exported)
8231                == PackageManager.PERMISSION_GRANTED) {
8232            return null;
8233        }
8234        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8235                cpi.applicationInfo.uid, cpi.exported)
8236                == PackageManager.PERMISSION_GRANTED) {
8237            return null;
8238        }
8239
8240        PathPermission[] pps = cpi.pathPermissions;
8241        if (pps != null) {
8242            int i = pps.length;
8243            while (i > 0) {
8244                i--;
8245                PathPermission pp = pps[i];
8246                String pprperm = pp.getReadPermission();
8247                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8248                        cpi.applicationInfo.uid, cpi.exported)
8249                        == PackageManager.PERMISSION_GRANTED) {
8250                    return null;
8251                }
8252                String ppwperm = pp.getWritePermission();
8253                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8254                        cpi.applicationInfo.uid, cpi.exported)
8255                        == PackageManager.PERMISSION_GRANTED) {
8256                    return null;
8257                }
8258            }
8259        }
8260        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8261            return null;
8262        }
8263
8264        String msg;
8265        if (!cpi.exported) {
8266            msg = "Permission Denial: opening provider " + cpi.name
8267                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8268                    + ", uid=" + callingUid + ") that is not exported from uid "
8269                    + cpi.applicationInfo.uid;
8270        } else {
8271            msg = "Permission Denial: opening provider " + cpi.name
8272                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8273                    + ", uid=" + callingUid + ") requires "
8274                    + cpi.readPermission + " or " + cpi.writePermission;
8275        }
8276        Slog.w(TAG, msg);
8277        return msg;
8278    }
8279
8280    /**
8281     * Returns if the ContentProvider has granted a uri to callingUid
8282     */
8283    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8284        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8285        if (perms != null) {
8286            for (int i=perms.size()-1; i>=0; i--) {
8287                GrantUri grantUri = perms.keyAt(i);
8288                if (grantUri.sourceUserId == userId || !checkUser) {
8289                    if (matchesProvider(grantUri.uri, cpi)) {
8290                        return true;
8291                    }
8292                }
8293            }
8294        }
8295        return false;
8296    }
8297
8298    /**
8299     * Returns true if the uri authority is one of the authorities specified in the provider.
8300     */
8301    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8302        String uriAuth = uri.getAuthority();
8303        String cpiAuth = cpi.authority;
8304        if (cpiAuth.indexOf(';') == -1) {
8305            return cpiAuth.equals(uriAuth);
8306        }
8307        String[] cpiAuths = cpiAuth.split(";");
8308        int length = cpiAuths.length;
8309        for (int i = 0; i < length; i++) {
8310            if (cpiAuths[i].equals(uriAuth)) return true;
8311        }
8312        return false;
8313    }
8314
8315    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8316            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8317        if (r != null) {
8318            for (int i=0; i<r.conProviders.size(); i++) {
8319                ContentProviderConnection conn = r.conProviders.get(i);
8320                if (conn.provider == cpr) {
8321                    if (DEBUG_PROVIDER) Slog.v(TAG,
8322                            "Adding provider requested by "
8323                            + r.processName + " from process "
8324                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8325                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8326                    if (stable) {
8327                        conn.stableCount++;
8328                        conn.numStableIncs++;
8329                    } else {
8330                        conn.unstableCount++;
8331                        conn.numUnstableIncs++;
8332                    }
8333                    return conn;
8334                }
8335            }
8336            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8337            if (stable) {
8338                conn.stableCount = 1;
8339                conn.numStableIncs = 1;
8340            } else {
8341                conn.unstableCount = 1;
8342                conn.numUnstableIncs = 1;
8343            }
8344            cpr.connections.add(conn);
8345            r.conProviders.add(conn);
8346            return conn;
8347        }
8348        cpr.addExternalProcessHandleLocked(externalProcessToken);
8349        return null;
8350    }
8351
8352    boolean decProviderCountLocked(ContentProviderConnection conn,
8353            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8354        if (conn != null) {
8355            cpr = conn.provider;
8356            if (DEBUG_PROVIDER) Slog.v(TAG,
8357                    "Removing provider requested by "
8358                    + conn.client.processName + " from process "
8359                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8360                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8361            if (stable) {
8362                conn.stableCount--;
8363            } else {
8364                conn.unstableCount--;
8365            }
8366            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8367                cpr.connections.remove(conn);
8368                conn.client.conProviders.remove(conn);
8369                return true;
8370            }
8371            return false;
8372        }
8373        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8374        return false;
8375    }
8376
8377    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8378            String name, IBinder token, boolean stable, int userId) {
8379        ContentProviderRecord cpr;
8380        ContentProviderConnection conn = null;
8381        ProviderInfo cpi = null;
8382
8383        synchronized(this) {
8384            ProcessRecord r = null;
8385            if (caller != null) {
8386                r = getRecordForAppLocked(caller);
8387                if (r == null) {
8388                    throw new SecurityException(
8389                            "Unable to find app for caller " + caller
8390                          + " (pid=" + Binder.getCallingPid()
8391                          + ") when getting content provider " + name);
8392                }
8393            }
8394
8395            boolean checkCrossUser = true;
8396
8397            // First check if this content provider has been published...
8398            cpr = mProviderMap.getProviderByName(name, userId);
8399            // If that didn't work, check if it exists for user 0 and then
8400            // verify that it's a singleton provider before using it.
8401            if (cpr == null && userId != UserHandle.USER_OWNER) {
8402                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8403                if (cpr != null) {
8404                    cpi = cpr.info;
8405                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8406                            cpi.name, cpi.flags)
8407                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8408                        userId = UserHandle.USER_OWNER;
8409                        checkCrossUser = false;
8410                    } else {
8411                        cpr = null;
8412                        cpi = null;
8413                    }
8414                }
8415            }
8416
8417            boolean providerRunning = cpr != null;
8418            if (providerRunning) {
8419                cpi = cpr.info;
8420                String msg;
8421                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8422                        != null) {
8423                    throw new SecurityException(msg);
8424                }
8425
8426                if (r != null && cpr.canRunHere(r)) {
8427                    // This provider has been published or is in the process
8428                    // of being published...  but it is also allowed to run
8429                    // in the caller's process, so don't make a connection
8430                    // and just let the caller instantiate its own instance.
8431                    ContentProviderHolder holder = cpr.newHolder(null);
8432                    // don't give caller the provider object, it needs
8433                    // to make its own.
8434                    holder.provider = null;
8435                    return holder;
8436                }
8437
8438                final long origId = Binder.clearCallingIdentity();
8439
8440                // In this case the provider instance already exists, so we can
8441                // return it right away.
8442                conn = incProviderCountLocked(r, cpr, token, stable);
8443                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8444                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8445                        // If this is a perceptible app accessing the provider,
8446                        // make sure to count it as being accessed and thus
8447                        // back up on the LRU list.  This is good because
8448                        // content providers are often expensive to start.
8449                        updateLruProcessLocked(cpr.proc, false, null);
8450                    }
8451                }
8452
8453                if (cpr.proc != null) {
8454                    if (false) {
8455                        if (cpr.name.flattenToShortString().equals(
8456                                "com.android.providers.calendar/.CalendarProvider2")) {
8457                            Slog.v(TAG, "****************** KILLING "
8458                                + cpr.name.flattenToShortString());
8459                            Process.killProcess(cpr.proc.pid);
8460                        }
8461                    }
8462                    boolean success = updateOomAdjLocked(cpr.proc);
8463                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8464                    // NOTE: there is still a race here where a signal could be
8465                    // pending on the process even though we managed to update its
8466                    // adj level.  Not sure what to do about this, but at least
8467                    // the race is now smaller.
8468                    if (!success) {
8469                        // Uh oh...  it looks like the provider's process
8470                        // has been killed on us.  We need to wait for a new
8471                        // process to be started, and make sure its death
8472                        // doesn't kill our process.
8473                        Slog.i(TAG,
8474                                "Existing provider " + cpr.name.flattenToShortString()
8475                                + " is crashing; detaching " + r);
8476                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8477                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8478                        if (!lastRef) {
8479                            // This wasn't the last ref our process had on
8480                            // the provider...  we have now been killed, bail.
8481                            return null;
8482                        }
8483                        providerRunning = false;
8484                        conn = null;
8485                    }
8486                }
8487
8488                Binder.restoreCallingIdentity(origId);
8489            }
8490
8491            boolean singleton;
8492            if (!providerRunning) {
8493                try {
8494                    cpi = AppGlobals.getPackageManager().
8495                        resolveContentProvider(name,
8496                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8497                } catch (RemoteException ex) {
8498                }
8499                if (cpi == null) {
8500                    return null;
8501                }
8502                // If the provider is a singleton AND
8503                // (it's a call within the same user || the provider is a
8504                // privileged app)
8505                // Then allow connecting to the singleton provider
8506                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8507                        cpi.name, cpi.flags)
8508                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8509                if (singleton) {
8510                    userId = UserHandle.USER_OWNER;
8511                }
8512                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8513
8514                String msg;
8515                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8516                        != null) {
8517                    throw new SecurityException(msg);
8518                }
8519
8520                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8521                        && !cpi.processName.equals("system")) {
8522                    // If this content provider does not run in the system
8523                    // process, and the system is not yet ready to run other
8524                    // processes, then fail fast instead of hanging.
8525                    throw new IllegalArgumentException(
8526                            "Attempt to launch content provider before system ready");
8527                }
8528
8529                // Make sure that the user who owns this provider is started.  If not,
8530                // we don't want to allow it to run.
8531                if (mStartedUsers.get(userId) == null) {
8532                    Slog.w(TAG, "Unable to launch app "
8533                            + cpi.applicationInfo.packageName + "/"
8534                            + cpi.applicationInfo.uid + " for provider "
8535                            + name + ": user " + userId + " is stopped");
8536                    return null;
8537                }
8538
8539                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8540                cpr = mProviderMap.getProviderByClass(comp, userId);
8541                final boolean firstClass = cpr == null;
8542                if (firstClass) {
8543                    try {
8544                        ApplicationInfo ai =
8545                            AppGlobals.getPackageManager().
8546                                getApplicationInfo(
8547                                        cpi.applicationInfo.packageName,
8548                                        STOCK_PM_FLAGS, userId);
8549                        if (ai == null) {
8550                            Slog.w(TAG, "No package info for content provider "
8551                                    + cpi.name);
8552                            return null;
8553                        }
8554                        ai = getAppInfoForUser(ai, userId);
8555                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8556                    } catch (RemoteException ex) {
8557                        // pm is in same process, this will never happen.
8558                    }
8559                }
8560
8561                if (r != null && cpr.canRunHere(r)) {
8562                    // If this is a multiprocess provider, then just return its
8563                    // info and allow the caller to instantiate it.  Only do
8564                    // this if the provider is the same user as the caller's
8565                    // process, or can run as root (so can be in any process).
8566                    return cpr.newHolder(null);
8567                }
8568
8569                if (DEBUG_PROVIDER) {
8570                    RuntimeException e = new RuntimeException("here");
8571                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8572                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8573                }
8574
8575                // This is single process, and our app is now connecting to it.
8576                // See if we are already in the process of launching this
8577                // provider.
8578                final int N = mLaunchingProviders.size();
8579                int i;
8580                for (i=0; i<N; i++) {
8581                    if (mLaunchingProviders.get(i) == cpr) {
8582                        break;
8583                    }
8584                }
8585
8586                // If the provider is not already being launched, then get it
8587                // started.
8588                if (i >= N) {
8589                    final long origId = Binder.clearCallingIdentity();
8590
8591                    try {
8592                        // Content provider is now in use, its package can't be stopped.
8593                        try {
8594                            AppGlobals.getPackageManager().setPackageStoppedState(
8595                                    cpr.appInfo.packageName, false, userId);
8596                        } catch (RemoteException e) {
8597                        } catch (IllegalArgumentException e) {
8598                            Slog.w(TAG, "Failed trying to unstop package "
8599                                    + cpr.appInfo.packageName + ": " + e);
8600                        }
8601
8602                        // Use existing process if already started
8603                        ProcessRecord proc = getProcessRecordLocked(
8604                                cpi.processName, cpr.appInfo.uid, false);
8605                        if (proc != null && proc.thread != null) {
8606                            if (DEBUG_PROVIDER) {
8607                                Slog.d(TAG, "Installing in existing process " + proc);
8608                            }
8609                            proc.pubProviders.put(cpi.name, cpr);
8610                            try {
8611                                proc.thread.scheduleInstallProvider(cpi);
8612                            } catch (RemoteException e) {
8613                            }
8614                        } else {
8615                            proc = startProcessLocked(cpi.processName,
8616                                    cpr.appInfo, false, 0, "content provider",
8617                                    new ComponentName(cpi.applicationInfo.packageName,
8618                                            cpi.name), false, false, false);
8619                            if (proc == null) {
8620                                Slog.w(TAG, "Unable to launch app "
8621                                        + cpi.applicationInfo.packageName + "/"
8622                                        + cpi.applicationInfo.uid + " for provider "
8623                                        + name + ": process is bad");
8624                                return null;
8625                            }
8626                        }
8627                        cpr.launchingApp = proc;
8628                        mLaunchingProviders.add(cpr);
8629                    } finally {
8630                        Binder.restoreCallingIdentity(origId);
8631                    }
8632                }
8633
8634                // Make sure the provider is published (the same provider class
8635                // may be published under multiple names).
8636                if (firstClass) {
8637                    mProviderMap.putProviderByClass(comp, cpr);
8638                }
8639
8640                mProviderMap.putProviderByName(name, cpr);
8641                conn = incProviderCountLocked(r, cpr, token, stable);
8642                if (conn != null) {
8643                    conn.waiting = true;
8644                }
8645            }
8646        }
8647
8648        // Wait for the provider to be published...
8649        synchronized (cpr) {
8650            while (cpr.provider == null) {
8651                if (cpr.launchingApp == null) {
8652                    Slog.w(TAG, "Unable to launch app "
8653                            + cpi.applicationInfo.packageName + "/"
8654                            + cpi.applicationInfo.uid + " for provider "
8655                            + name + ": launching app became null");
8656                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8657                            UserHandle.getUserId(cpi.applicationInfo.uid),
8658                            cpi.applicationInfo.packageName,
8659                            cpi.applicationInfo.uid, name);
8660                    return null;
8661                }
8662                try {
8663                    if (DEBUG_MU) {
8664                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8665                                + cpr.launchingApp);
8666                    }
8667                    if (conn != null) {
8668                        conn.waiting = true;
8669                    }
8670                    cpr.wait();
8671                } catch (InterruptedException ex) {
8672                } finally {
8673                    if (conn != null) {
8674                        conn.waiting = false;
8675                    }
8676                }
8677            }
8678        }
8679        return cpr != null ? cpr.newHolder(conn) : null;
8680    }
8681
8682    @Override
8683    public final ContentProviderHolder getContentProvider(
8684            IApplicationThread caller, String name, int userId, boolean stable) {
8685        enforceNotIsolatedCaller("getContentProvider");
8686        if (caller == null) {
8687            String msg = "null IApplicationThread when getting content provider "
8688                    + name;
8689            Slog.w(TAG, msg);
8690            throw new SecurityException(msg);
8691        }
8692        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8693        // with cross-user grant.
8694        return getContentProviderImpl(caller, name, null, stable, userId);
8695    }
8696
8697    public ContentProviderHolder getContentProviderExternal(
8698            String name, int userId, IBinder token) {
8699        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8700            "Do not have permission in call getContentProviderExternal()");
8701        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8702                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8703        return getContentProviderExternalUnchecked(name, token, userId);
8704    }
8705
8706    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8707            IBinder token, int userId) {
8708        return getContentProviderImpl(null, name, token, true, userId);
8709    }
8710
8711    /**
8712     * Drop a content provider from a ProcessRecord's bookkeeping
8713     */
8714    public void removeContentProvider(IBinder connection, boolean stable) {
8715        enforceNotIsolatedCaller("removeContentProvider");
8716        long ident = Binder.clearCallingIdentity();
8717        try {
8718            synchronized (this) {
8719                ContentProviderConnection conn;
8720                try {
8721                    conn = (ContentProviderConnection)connection;
8722                } catch (ClassCastException e) {
8723                    String msg ="removeContentProvider: " + connection
8724                            + " not a ContentProviderConnection";
8725                    Slog.w(TAG, msg);
8726                    throw new IllegalArgumentException(msg);
8727                }
8728                if (conn == null) {
8729                    throw new NullPointerException("connection is null");
8730                }
8731                if (decProviderCountLocked(conn, null, null, stable)) {
8732                    updateOomAdjLocked();
8733                }
8734            }
8735        } finally {
8736            Binder.restoreCallingIdentity(ident);
8737        }
8738    }
8739
8740    public void removeContentProviderExternal(String name, IBinder token) {
8741        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8742            "Do not have permission in call removeContentProviderExternal()");
8743        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8744    }
8745
8746    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8747        synchronized (this) {
8748            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8749            if(cpr == null) {
8750                //remove from mProvidersByClass
8751                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8752                return;
8753            }
8754
8755            //update content provider record entry info
8756            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8757            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8758            if (localCpr.hasExternalProcessHandles()) {
8759                if (localCpr.removeExternalProcessHandleLocked(token)) {
8760                    updateOomAdjLocked();
8761                } else {
8762                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8763                            + " with no external reference for token: "
8764                            + token + ".");
8765                }
8766            } else {
8767                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8768                        + " with no external references.");
8769            }
8770        }
8771    }
8772
8773    public final void publishContentProviders(IApplicationThread caller,
8774            List<ContentProviderHolder> providers) {
8775        if (providers == null) {
8776            return;
8777        }
8778
8779        enforceNotIsolatedCaller("publishContentProviders");
8780        synchronized (this) {
8781            final ProcessRecord r = getRecordForAppLocked(caller);
8782            if (DEBUG_MU)
8783                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8784            if (r == null) {
8785                throw new SecurityException(
8786                        "Unable to find app for caller " + caller
8787                      + " (pid=" + Binder.getCallingPid()
8788                      + ") when publishing content providers");
8789            }
8790
8791            final long origId = Binder.clearCallingIdentity();
8792
8793            final int N = providers.size();
8794            for (int i=0; i<N; i++) {
8795                ContentProviderHolder src = providers.get(i);
8796                if (src == null || src.info == null || src.provider == null) {
8797                    continue;
8798                }
8799                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8800                if (DEBUG_MU)
8801                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8802                if (dst != null) {
8803                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8804                    mProviderMap.putProviderByClass(comp, dst);
8805                    String names[] = dst.info.authority.split(";");
8806                    for (int j = 0; j < names.length; j++) {
8807                        mProviderMap.putProviderByName(names[j], dst);
8808                    }
8809
8810                    int NL = mLaunchingProviders.size();
8811                    int j;
8812                    for (j=0; j<NL; j++) {
8813                        if (mLaunchingProviders.get(j) == dst) {
8814                            mLaunchingProviders.remove(j);
8815                            j--;
8816                            NL--;
8817                        }
8818                    }
8819                    synchronized (dst) {
8820                        dst.provider = src.provider;
8821                        dst.proc = r;
8822                        dst.notifyAll();
8823                    }
8824                    updateOomAdjLocked(r);
8825                }
8826            }
8827
8828            Binder.restoreCallingIdentity(origId);
8829        }
8830    }
8831
8832    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8833        ContentProviderConnection conn;
8834        try {
8835            conn = (ContentProviderConnection)connection;
8836        } catch (ClassCastException e) {
8837            String msg ="refContentProvider: " + connection
8838                    + " not a ContentProviderConnection";
8839            Slog.w(TAG, msg);
8840            throw new IllegalArgumentException(msg);
8841        }
8842        if (conn == null) {
8843            throw new NullPointerException("connection is null");
8844        }
8845
8846        synchronized (this) {
8847            if (stable > 0) {
8848                conn.numStableIncs += stable;
8849            }
8850            stable = conn.stableCount + stable;
8851            if (stable < 0) {
8852                throw new IllegalStateException("stableCount < 0: " + stable);
8853            }
8854
8855            if (unstable > 0) {
8856                conn.numUnstableIncs += unstable;
8857            }
8858            unstable = conn.unstableCount + unstable;
8859            if (unstable < 0) {
8860                throw new IllegalStateException("unstableCount < 0: " + unstable);
8861            }
8862
8863            if ((stable+unstable) <= 0) {
8864                throw new IllegalStateException("ref counts can't go to zero here: stable="
8865                        + stable + " unstable=" + unstable);
8866            }
8867            conn.stableCount = stable;
8868            conn.unstableCount = unstable;
8869            return !conn.dead;
8870        }
8871    }
8872
8873    public void unstableProviderDied(IBinder connection) {
8874        ContentProviderConnection conn;
8875        try {
8876            conn = (ContentProviderConnection)connection;
8877        } catch (ClassCastException e) {
8878            String msg ="refContentProvider: " + connection
8879                    + " not a ContentProviderConnection";
8880            Slog.w(TAG, msg);
8881            throw new IllegalArgumentException(msg);
8882        }
8883        if (conn == null) {
8884            throw new NullPointerException("connection is null");
8885        }
8886
8887        // Safely retrieve the content provider associated with the connection.
8888        IContentProvider provider;
8889        synchronized (this) {
8890            provider = conn.provider.provider;
8891        }
8892
8893        if (provider == null) {
8894            // Um, yeah, we're way ahead of you.
8895            return;
8896        }
8897
8898        // Make sure the caller is being honest with us.
8899        if (provider.asBinder().pingBinder()) {
8900            // Er, no, still looks good to us.
8901            synchronized (this) {
8902                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8903                        + " says " + conn + " died, but we don't agree");
8904                return;
8905            }
8906        }
8907
8908        // Well look at that!  It's dead!
8909        synchronized (this) {
8910            if (conn.provider.provider != provider) {
8911                // But something changed...  good enough.
8912                return;
8913            }
8914
8915            ProcessRecord proc = conn.provider.proc;
8916            if (proc == null || proc.thread == null) {
8917                // Seems like the process is already cleaned up.
8918                return;
8919            }
8920
8921            // As far as we're concerned, this is just like receiving a
8922            // death notification...  just a bit prematurely.
8923            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8924                    + ") early provider death");
8925            final long ident = Binder.clearCallingIdentity();
8926            try {
8927                appDiedLocked(proc, proc.pid, proc.thread);
8928            } finally {
8929                Binder.restoreCallingIdentity(ident);
8930            }
8931        }
8932    }
8933
8934    @Override
8935    public void appNotRespondingViaProvider(IBinder connection) {
8936        enforceCallingPermission(
8937                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8938
8939        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8940        if (conn == null) {
8941            Slog.w(TAG, "ContentProviderConnection is null");
8942            return;
8943        }
8944
8945        final ProcessRecord host = conn.provider.proc;
8946        if (host == null) {
8947            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8948            return;
8949        }
8950
8951        final long token = Binder.clearCallingIdentity();
8952        try {
8953            appNotResponding(host, null, null, false, "ContentProvider not responding");
8954        } finally {
8955            Binder.restoreCallingIdentity(token);
8956        }
8957    }
8958
8959    public final void installSystemProviders() {
8960        List<ProviderInfo> providers;
8961        synchronized (this) {
8962            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8963            providers = generateApplicationProvidersLocked(app);
8964            if (providers != null) {
8965                for (int i=providers.size()-1; i>=0; i--) {
8966                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8967                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8968                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8969                                + ": not system .apk");
8970                        providers.remove(i);
8971                    }
8972                }
8973            }
8974        }
8975        if (providers != null) {
8976            mSystemThread.installSystemProviders(providers);
8977        }
8978
8979        mCoreSettingsObserver = new CoreSettingsObserver(this);
8980
8981        //mUsageStatsService.monitorPackages();
8982    }
8983
8984    /**
8985     * Allows apps to retrieve the MIME type of a URI.
8986     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
8987     * users, then it does not need permission to access the ContentProvider.
8988     * Either, it needs cross-user uri grants.
8989     *
8990     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8991     *
8992     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8993     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8994     */
8995    public String getProviderMimeType(Uri uri, int userId) {
8996        enforceNotIsolatedCaller("getProviderMimeType");
8997        final String name = uri.getAuthority();
8998        int callingUid = Binder.getCallingUid();
8999        int callingPid = Binder.getCallingPid();
9000        long ident = 0;
9001        boolean clearedIdentity = false;
9002        userId = unsafeConvertIncomingUser(userId);
9003        if (UserHandle.getUserId(callingUid) != userId) {
9004            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9005                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9006                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9007                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9008                clearedIdentity = true;
9009                ident = Binder.clearCallingIdentity();
9010            }
9011        }
9012        ContentProviderHolder holder = null;
9013        try {
9014            holder = getContentProviderExternalUnchecked(name, null, userId);
9015            if (holder != null) {
9016                return holder.provider.getType(uri);
9017            }
9018        } catch (RemoteException e) {
9019            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9020            return null;
9021        } finally {
9022            // We need to clear the identity to call removeContentProviderExternalUnchecked
9023            if (!clearedIdentity) {
9024                ident = Binder.clearCallingIdentity();
9025            }
9026            try {
9027                if (holder != null) {
9028                    removeContentProviderExternalUnchecked(name, null, userId);
9029                }
9030            } finally {
9031                Binder.restoreCallingIdentity(ident);
9032            }
9033        }
9034
9035        return null;
9036    }
9037
9038    // =========================================================
9039    // GLOBAL MANAGEMENT
9040    // =========================================================
9041
9042    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9043            boolean isolated, int isolatedUid) {
9044        String proc = customProcess != null ? customProcess : info.processName;
9045        BatteryStatsImpl.Uid.Proc ps = null;
9046        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9047        int uid = info.uid;
9048        if (isolated) {
9049            if (isolatedUid == 0) {
9050                int userId = UserHandle.getUserId(uid);
9051                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9052                while (true) {
9053                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9054                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9055                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9056                    }
9057                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9058                    mNextIsolatedProcessUid++;
9059                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9060                        // No process for this uid, use it.
9061                        break;
9062                    }
9063                    stepsLeft--;
9064                    if (stepsLeft <= 0) {
9065                        return null;
9066                    }
9067                }
9068            } else {
9069                // Special case for startIsolatedProcess (internal only), where
9070                // the uid of the isolated process is specified by the caller.
9071                uid = isolatedUid;
9072            }
9073        }
9074        return new ProcessRecord(stats, info, proc, uid);
9075    }
9076
9077    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9078            String abiOverride) {
9079        ProcessRecord app;
9080        if (!isolated) {
9081            app = getProcessRecordLocked(info.processName, info.uid, true);
9082        } else {
9083            app = null;
9084        }
9085
9086        if (app == null) {
9087            app = newProcessRecordLocked(info, null, isolated, 0);
9088            mProcessNames.put(info.processName, app.uid, app);
9089            if (isolated) {
9090                mIsolatedProcesses.put(app.uid, app);
9091            }
9092            updateLruProcessLocked(app, false, null);
9093            updateOomAdjLocked();
9094        }
9095
9096        // This package really, really can not be stopped.
9097        try {
9098            AppGlobals.getPackageManager().setPackageStoppedState(
9099                    info.packageName, false, UserHandle.getUserId(app.uid));
9100        } catch (RemoteException e) {
9101        } catch (IllegalArgumentException e) {
9102            Slog.w(TAG, "Failed trying to unstop package "
9103                    + info.packageName + ": " + e);
9104        }
9105
9106        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9107                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9108            app.persistent = true;
9109            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9110        }
9111        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9112            mPersistentStartingProcesses.add(app);
9113            startProcessLocked(app, "added application", app.processName, abiOverride,
9114                    null /* entryPoint */, null /* entryPointArgs */);
9115        }
9116
9117        return app;
9118    }
9119
9120    public void unhandledBack() {
9121        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9122                "unhandledBack()");
9123
9124        synchronized(this) {
9125            final long origId = Binder.clearCallingIdentity();
9126            try {
9127                getFocusedStack().unhandledBackLocked();
9128            } finally {
9129                Binder.restoreCallingIdentity(origId);
9130            }
9131        }
9132    }
9133
9134    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9135        enforceNotIsolatedCaller("openContentUri");
9136        final int userId = UserHandle.getCallingUserId();
9137        String name = uri.getAuthority();
9138        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9139        ParcelFileDescriptor pfd = null;
9140        if (cph != null) {
9141            // We record the binder invoker's uid in thread-local storage before
9142            // going to the content provider to open the file.  Later, in the code
9143            // that handles all permissions checks, we look for this uid and use
9144            // that rather than the Activity Manager's own uid.  The effect is that
9145            // we do the check against the caller's permissions even though it looks
9146            // to the content provider like the Activity Manager itself is making
9147            // the request.
9148            sCallerIdentity.set(new Identity(
9149                    Binder.getCallingPid(), Binder.getCallingUid()));
9150            try {
9151                pfd = cph.provider.openFile(null, uri, "r", null);
9152            } catch (FileNotFoundException e) {
9153                // do nothing; pfd will be returned null
9154            } finally {
9155                // Ensure that whatever happens, we clean up the identity state
9156                sCallerIdentity.remove();
9157            }
9158
9159            // We've got the fd now, so we're done with the provider.
9160            removeContentProviderExternalUnchecked(name, null, userId);
9161        } else {
9162            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9163        }
9164        return pfd;
9165    }
9166
9167    // Actually is sleeping or shutting down or whatever else in the future
9168    // is an inactive state.
9169    public boolean isSleepingOrShuttingDown() {
9170        return mSleeping || mShuttingDown;
9171    }
9172
9173    public boolean isSleeping() {
9174        return mSleeping;
9175    }
9176
9177    void goingToSleep() {
9178        synchronized(this) {
9179            mWentToSleep = true;
9180            updateEventDispatchingLocked();
9181            goToSleepIfNeededLocked();
9182        }
9183    }
9184
9185    void finishRunningVoiceLocked() {
9186        if (mRunningVoice) {
9187            mRunningVoice = false;
9188            goToSleepIfNeededLocked();
9189        }
9190    }
9191
9192    void goToSleepIfNeededLocked() {
9193        if (mWentToSleep && !mRunningVoice) {
9194            if (!mSleeping) {
9195                mSleeping = true;
9196                mStackSupervisor.goingToSleepLocked();
9197
9198                // Initialize the wake times of all processes.
9199                checkExcessivePowerUsageLocked(false);
9200                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9201                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9202                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9203            }
9204        }
9205    }
9206
9207    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9208        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9209            // Never persist the home stack.
9210            return;
9211        }
9212        mTaskPersister.wakeup(task, flush);
9213    }
9214
9215    @Override
9216    public boolean shutdown(int timeout) {
9217        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9218                != PackageManager.PERMISSION_GRANTED) {
9219            throw new SecurityException("Requires permission "
9220                    + android.Manifest.permission.SHUTDOWN);
9221        }
9222
9223        boolean timedout = false;
9224
9225        synchronized(this) {
9226            mShuttingDown = true;
9227            updateEventDispatchingLocked();
9228            timedout = mStackSupervisor.shutdownLocked(timeout);
9229        }
9230
9231        mAppOpsService.shutdown();
9232        if (mUsageStatsService != null) {
9233            mUsageStatsService.prepareShutdown();
9234        }
9235        mBatteryStatsService.shutdown();
9236        synchronized (this) {
9237            mProcessStats.shutdownLocked();
9238        }
9239        notifyTaskPersisterLocked(null, true);
9240
9241        return timedout;
9242    }
9243
9244    public final void activitySlept(IBinder token) {
9245        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9246
9247        final long origId = Binder.clearCallingIdentity();
9248
9249        synchronized (this) {
9250            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9251            if (r != null) {
9252                mStackSupervisor.activitySleptLocked(r);
9253            }
9254        }
9255
9256        Binder.restoreCallingIdentity(origId);
9257    }
9258
9259    void logLockScreen(String msg) {
9260        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9261                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9262                mWentToSleep + " mSleeping=" + mSleeping);
9263    }
9264
9265    private void comeOutOfSleepIfNeededLocked() {
9266        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9267            if (mSleeping) {
9268                mSleeping = false;
9269                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9270            }
9271        }
9272    }
9273
9274    void wakingUp() {
9275        synchronized(this) {
9276            mWentToSleep = false;
9277            updateEventDispatchingLocked();
9278            comeOutOfSleepIfNeededLocked();
9279        }
9280    }
9281
9282    void startRunningVoiceLocked() {
9283        if (!mRunningVoice) {
9284            mRunningVoice = true;
9285            comeOutOfSleepIfNeededLocked();
9286        }
9287    }
9288
9289    private void updateEventDispatchingLocked() {
9290        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9291    }
9292
9293    public void setLockScreenShown(boolean shown) {
9294        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9295                != PackageManager.PERMISSION_GRANTED) {
9296            throw new SecurityException("Requires permission "
9297                    + android.Manifest.permission.DEVICE_POWER);
9298        }
9299
9300        synchronized(this) {
9301            long ident = Binder.clearCallingIdentity();
9302            try {
9303                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9304                mLockScreenShown = shown;
9305                comeOutOfSleepIfNeededLocked();
9306            } finally {
9307                Binder.restoreCallingIdentity(ident);
9308            }
9309        }
9310    }
9311
9312    @Override
9313    public void stopAppSwitches() {
9314        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9315                != PackageManager.PERMISSION_GRANTED) {
9316            throw new SecurityException("Requires permission "
9317                    + android.Manifest.permission.STOP_APP_SWITCHES);
9318        }
9319
9320        synchronized(this) {
9321            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9322                    + APP_SWITCH_DELAY_TIME;
9323            mDidAppSwitch = false;
9324            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9325            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9326            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9327        }
9328    }
9329
9330    public void resumeAppSwitches() {
9331        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9332                != PackageManager.PERMISSION_GRANTED) {
9333            throw new SecurityException("Requires permission "
9334                    + android.Manifest.permission.STOP_APP_SWITCHES);
9335        }
9336
9337        synchronized(this) {
9338            // Note that we don't execute any pending app switches... we will
9339            // let those wait until either the timeout, or the next start
9340            // activity request.
9341            mAppSwitchesAllowedTime = 0;
9342        }
9343    }
9344
9345    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9346            String name) {
9347        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9348            return true;
9349        }
9350
9351        final int perm = checkComponentPermission(
9352                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9353                callingUid, -1, true);
9354        if (perm == PackageManager.PERMISSION_GRANTED) {
9355            return true;
9356        }
9357
9358        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9359        return false;
9360    }
9361
9362    public void setDebugApp(String packageName, boolean waitForDebugger,
9363            boolean persistent) {
9364        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9365                "setDebugApp()");
9366
9367        long ident = Binder.clearCallingIdentity();
9368        try {
9369            // Note that this is not really thread safe if there are multiple
9370            // callers into it at the same time, but that's not a situation we
9371            // care about.
9372            if (persistent) {
9373                final ContentResolver resolver = mContext.getContentResolver();
9374                Settings.Global.putString(
9375                    resolver, Settings.Global.DEBUG_APP,
9376                    packageName);
9377                Settings.Global.putInt(
9378                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9379                    waitForDebugger ? 1 : 0);
9380            }
9381
9382            synchronized (this) {
9383                if (!persistent) {
9384                    mOrigDebugApp = mDebugApp;
9385                    mOrigWaitForDebugger = mWaitForDebugger;
9386                }
9387                mDebugApp = packageName;
9388                mWaitForDebugger = waitForDebugger;
9389                mDebugTransient = !persistent;
9390                if (packageName != null) {
9391                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9392                            false, UserHandle.USER_ALL, "set debug app");
9393                }
9394            }
9395        } finally {
9396            Binder.restoreCallingIdentity(ident);
9397        }
9398    }
9399
9400    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9401        synchronized (this) {
9402            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9403            if (!isDebuggable) {
9404                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9405                    throw new SecurityException("Process not debuggable: " + app.packageName);
9406                }
9407            }
9408
9409            mOpenGlTraceApp = processName;
9410        }
9411    }
9412
9413    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9414            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9415        synchronized (this) {
9416            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9417            if (!isDebuggable) {
9418                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9419                    throw new SecurityException("Process not debuggable: " + app.packageName);
9420                }
9421            }
9422            mProfileApp = processName;
9423            mProfileFile = profileFile;
9424            if (mProfileFd != null) {
9425                try {
9426                    mProfileFd.close();
9427                } catch (IOException e) {
9428                }
9429                mProfileFd = null;
9430            }
9431            mProfileFd = profileFd;
9432            mProfileType = 0;
9433            mAutoStopProfiler = autoStopProfiler;
9434        }
9435    }
9436
9437    @Override
9438    public void setAlwaysFinish(boolean enabled) {
9439        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9440                "setAlwaysFinish()");
9441
9442        Settings.Global.putInt(
9443                mContext.getContentResolver(),
9444                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9445
9446        synchronized (this) {
9447            mAlwaysFinishActivities = enabled;
9448        }
9449    }
9450
9451    @Override
9452    public void setActivityController(IActivityController controller) {
9453        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9454                "setActivityController()");
9455        synchronized (this) {
9456            mController = controller;
9457            Watchdog.getInstance().setActivityController(controller);
9458        }
9459    }
9460
9461    @Override
9462    public void setUserIsMonkey(boolean userIsMonkey) {
9463        synchronized (this) {
9464            synchronized (mPidsSelfLocked) {
9465                final int callingPid = Binder.getCallingPid();
9466                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9467                if (precessRecord == null) {
9468                    throw new SecurityException("Unknown process: " + callingPid);
9469                }
9470                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9471                    throw new SecurityException("Only an instrumentation process "
9472                            + "with a UiAutomation can call setUserIsMonkey");
9473                }
9474            }
9475            mUserIsMonkey = userIsMonkey;
9476        }
9477    }
9478
9479    @Override
9480    public boolean isUserAMonkey() {
9481        synchronized (this) {
9482            // If there is a controller also implies the user is a monkey.
9483            return (mUserIsMonkey || mController != null);
9484        }
9485    }
9486
9487    public void requestBugReport() {
9488        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9489        SystemProperties.set("ctl.start", "bugreport");
9490    }
9491
9492    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9493        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9494    }
9495
9496    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9497        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9498            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9499        }
9500        return KEY_DISPATCHING_TIMEOUT;
9501    }
9502
9503    @Override
9504    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9505        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9506                != PackageManager.PERMISSION_GRANTED) {
9507            throw new SecurityException("Requires permission "
9508                    + android.Manifest.permission.FILTER_EVENTS);
9509        }
9510        ProcessRecord proc;
9511        long timeout;
9512        synchronized (this) {
9513            synchronized (mPidsSelfLocked) {
9514                proc = mPidsSelfLocked.get(pid);
9515            }
9516            timeout = getInputDispatchingTimeoutLocked(proc);
9517        }
9518
9519        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9520            return -1;
9521        }
9522
9523        return timeout;
9524    }
9525
9526    /**
9527     * Handle input dispatching timeouts.
9528     * Returns whether input dispatching should be aborted or not.
9529     */
9530    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9531            final ActivityRecord activity, final ActivityRecord parent,
9532            final boolean aboveSystem, String reason) {
9533        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9534                != PackageManager.PERMISSION_GRANTED) {
9535            throw new SecurityException("Requires permission "
9536                    + android.Manifest.permission.FILTER_EVENTS);
9537        }
9538
9539        final String annotation;
9540        if (reason == null) {
9541            annotation = "Input dispatching timed out";
9542        } else {
9543            annotation = "Input dispatching timed out (" + reason + ")";
9544        }
9545
9546        if (proc != null) {
9547            synchronized (this) {
9548                if (proc.debugging) {
9549                    return false;
9550                }
9551
9552                if (mDidDexOpt) {
9553                    // Give more time since we were dexopting.
9554                    mDidDexOpt = false;
9555                    return false;
9556                }
9557
9558                if (proc.instrumentationClass != null) {
9559                    Bundle info = new Bundle();
9560                    info.putString("shortMsg", "keyDispatchingTimedOut");
9561                    info.putString("longMsg", annotation);
9562                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9563                    return true;
9564                }
9565            }
9566            mHandler.post(new Runnable() {
9567                @Override
9568                public void run() {
9569                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9570                }
9571            });
9572        }
9573
9574        return true;
9575    }
9576
9577    public Bundle getAssistContextExtras(int requestType) {
9578        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9579                "getAssistContextExtras()");
9580        PendingAssistExtras pae;
9581        Bundle extras = new Bundle();
9582        synchronized (this) {
9583            ActivityRecord activity = getFocusedStack().mResumedActivity;
9584            if (activity == null) {
9585                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9586                return null;
9587            }
9588            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9589            if (activity.app == null || activity.app.thread == null) {
9590                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9591                return extras;
9592            }
9593            if (activity.app.pid == Binder.getCallingPid()) {
9594                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9595                return extras;
9596            }
9597            pae = new PendingAssistExtras(activity);
9598            try {
9599                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9600                        requestType);
9601                mPendingAssistExtras.add(pae);
9602                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9603            } catch (RemoteException e) {
9604                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9605                return extras;
9606            }
9607        }
9608        synchronized (pae) {
9609            while (!pae.haveResult) {
9610                try {
9611                    pae.wait();
9612                } catch (InterruptedException e) {
9613                }
9614            }
9615            if (pae.result != null) {
9616                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9617            }
9618        }
9619        synchronized (this) {
9620            mPendingAssistExtras.remove(pae);
9621            mHandler.removeCallbacks(pae);
9622        }
9623        return extras;
9624    }
9625
9626    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9627        PendingAssistExtras pae = (PendingAssistExtras)token;
9628        synchronized (pae) {
9629            pae.result = extras;
9630            pae.haveResult = true;
9631            pae.notifyAll();
9632        }
9633    }
9634
9635    public void registerProcessObserver(IProcessObserver observer) {
9636        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9637                "registerProcessObserver()");
9638        synchronized (this) {
9639            mProcessObservers.register(observer);
9640        }
9641    }
9642
9643    @Override
9644    public void unregisterProcessObserver(IProcessObserver observer) {
9645        synchronized (this) {
9646            mProcessObservers.unregister(observer);
9647        }
9648    }
9649
9650    @Override
9651    public boolean convertFromTranslucent(IBinder token) {
9652        final long origId = Binder.clearCallingIdentity();
9653        try {
9654            synchronized (this) {
9655                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9656                if (r == null) {
9657                    return false;
9658                }
9659                if (r.changeWindowTranslucency(true)) {
9660                    mWindowManager.setAppFullscreen(token, true);
9661                    r.task.stack.releaseMediaResources();
9662                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9663                    return true;
9664                }
9665                return false;
9666            }
9667        } finally {
9668            Binder.restoreCallingIdentity(origId);
9669        }
9670    }
9671
9672    @Override
9673    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9674        final long origId = Binder.clearCallingIdentity();
9675        try {
9676            synchronized (this) {
9677                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9678                if (r == null) {
9679                    return false;
9680                }
9681                int index = r.task.mActivities.lastIndexOf(r);
9682                if (index > 0) {
9683                    ActivityRecord under = r.task.mActivities.get(index - 1);
9684                    under.returningOptions = options;
9685                }
9686                if (r.changeWindowTranslucency(false)) {
9687                    r.task.stack.convertToTranslucent(r);
9688                    mWindowManager.setAppFullscreen(token, false);
9689                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9690                    return true;
9691                } else {
9692                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9693                    return false;
9694                }
9695            }
9696        } finally {
9697            Binder.restoreCallingIdentity(origId);
9698        }
9699    }
9700
9701    @Override
9702    public boolean setMediaPlaying(IBinder token, boolean playing) {
9703        final long origId = Binder.clearCallingIdentity();
9704        try {
9705            synchronized (this) {
9706                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9707                if (r != null) {
9708                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9709                }
9710            }
9711            return false;
9712        } finally {
9713            Binder.restoreCallingIdentity(origId);
9714        }
9715    }
9716
9717    @Override
9718    public boolean isBackgroundMediaPlaying(IBinder token) {
9719        final long origId = Binder.clearCallingIdentity();
9720        try {
9721            synchronized (this) {
9722                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9723                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9724                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9725                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9726                return playing;
9727            }
9728        } finally {
9729            Binder.restoreCallingIdentity(origId);
9730        }
9731    }
9732
9733    @Override
9734    public ActivityOptions getActivityOptions(IBinder token) {
9735        final long origId = Binder.clearCallingIdentity();
9736        try {
9737            synchronized (this) {
9738                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9739                if (r != null) {
9740                    final ActivityOptions activityOptions = r.pendingOptions;
9741                    r.pendingOptions = null;
9742                    return activityOptions;
9743                }
9744                return null;
9745            }
9746        } finally {
9747            Binder.restoreCallingIdentity(origId);
9748        }
9749    }
9750
9751    @Override
9752    public void setImmersive(IBinder token, boolean immersive) {
9753        synchronized(this) {
9754            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9755            if (r == null) {
9756                throw new IllegalArgumentException();
9757            }
9758            r.immersive = immersive;
9759
9760            // update associated state if we're frontmost
9761            if (r == mFocusedActivity) {
9762                if (DEBUG_IMMERSIVE) {
9763                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9764                }
9765                applyUpdateLockStateLocked(r);
9766            }
9767        }
9768    }
9769
9770    @Override
9771    public boolean isImmersive(IBinder token) {
9772        synchronized (this) {
9773            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9774            if (r == null) {
9775                throw new IllegalArgumentException();
9776            }
9777            return r.immersive;
9778        }
9779    }
9780
9781    public boolean isTopActivityImmersive() {
9782        enforceNotIsolatedCaller("startActivity");
9783        synchronized (this) {
9784            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9785            return (r != null) ? r.immersive : false;
9786        }
9787    }
9788
9789    @Override
9790    public boolean isTopOfTask(IBinder token) {
9791        synchronized (this) {
9792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9793            if (r == null) {
9794                throw new IllegalArgumentException();
9795            }
9796            return r.task.getTopActivity() == r;
9797        }
9798    }
9799
9800    public final void enterSafeMode() {
9801        synchronized(this) {
9802            // It only makes sense to do this before the system is ready
9803            // and started launching other packages.
9804            if (!mSystemReady) {
9805                try {
9806                    AppGlobals.getPackageManager().enterSafeMode();
9807                } catch (RemoteException e) {
9808                }
9809            }
9810
9811            mSafeMode = true;
9812        }
9813    }
9814
9815    public final void showSafeModeOverlay() {
9816        View v = LayoutInflater.from(mContext).inflate(
9817                com.android.internal.R.layout.safe_mode, null);
9818        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9819        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9820        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9821        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9822        lp.gravity = Gravity.BOTTOM | Gravity.START;
9823        lp.format = v.getBackground().getOpacity();
9824        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9825                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9826        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9827        ((WindowManager)mContext.getSystemService(
9828                Context.WINDOW_SERVICE)).addView(v, lp);
9829    }
9830
9831    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9832        if (!(sender instanceof PendingIntentRecord)) {
9833            return;
9834        }
9835        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9836        synchronized (stats) {
9837            if (mBatteryStatsService.isOnBattery()) {
9838                mBatteryStatsService.enforceCallingPermission();
9839                PendingIntentRecord rec = (PendingIntentRecord)sender;
9840                int MY_UID = Binder.getCallingUid();
9841                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9842                BatteryStatsImpl.Uid.Pkg pkg =
9843                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9844                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9845                pkg.incWakeupsLocked();
9846            }
9847        }
9848    }
9849
9850    public boolean killPids(int[] pids, String pReason, boolean secure) {
9851        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9852            throw new SecurityException("killPids only available to the system");
9853        }
9854        String reason = (pReason == null) ? "Unknown" : pReason;
9855        // XXX Note: don't acquire main activity lock here, because the window
9856        // manager calls in with its locks held.
9857
9858        boolean killed = false;
9859        synchronized (mPidsSelfLocked) {
9860            int[] types = new int[pids.length];
9861            int worstType = 0;
9862            for (int i=0; i<pids.length; i++) {
9863                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9864                if (proc != null) {
9865                    int type = proc.setAdj;
9866                    types[i] = type;
9867                    if (type > worstType) {
9868                        worstType = type;
9869                    }
9870                }
9871            }
9872
9873            // If the worst oom_adj is somewhere in the cached proc LRU range,
9874            // then constrain it so we will kill all cached procs.
9875            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9876                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9877                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9878            }
9879
9880            // If this is not a secure call, don't let it kill processes that
9881            // are important.
9882            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9883                worstType = ProcessList.SERVICE_ADJ;
9884            }
9885
9886            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9887            for (int i=0; i<pids.length; i++) {
9888                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9889                if (proc == null) {
9890                    continue;
9891                }
9892                int adj = proc.setAdj;
9893                if (adj >= worstType && !proc.killedByAm) {
9894                    killUnneededProcessLocked(proc, reason);
9895                    killed = true;
9896                }
9897            }
9898        }
9899        return killed;
9900    }
9901
9902    @Override
9903    public void killUid(int uid, String reason) {
9904        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9905            throw new SecurityException("killUid only available to the system");
9906        }
9907        synchronized (this) {
9908            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9909                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9910                    reason != null ? reason : "kill uid");
9911        }
9912    }
9913
9914    @Override
9915    public boolean killProcessesBelowForeground(String reason) {
9916        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9917            throw new SecurityException("killProcessesBelowForeground() only available to system");
9918        }
9919
9920        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9921    }
9922
9923    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9924        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9925            throw new SecurityException("killProcessesBelowAdj() only available to system");
9926        }
9927
9928        boolean killed = false;
9929        synchronized (mPidsSelfLocked) {
9930            final int size = mPidsSelfLocked.size();
9931            for (int i = 0; i < size; i++) {
9932                final int pid = mPidsSelfLocked.keyAt(i);
9933                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9934                if (proc == null) continue;
9935
9936                final int adj = proc.setAdj;
9937                if (adj > belowAdj && !proc.killedByAm) {
9938                    killUnneededProcessLocked(proc, reason);
9939                    killed = true;
9940                }
9941            }
9942        }
9943        return killed;
9944    }
9945
9946    @Override
9947    public void hang(final IBinder who, boolean allowRestart) {
9948        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9949                != PackageManager.PERMISSION_GRANTED) {
9950            throw new SecurityException("Requires permission "
9951                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9952        }
9953
9954        final IBinder.DeathRecipient death = new DeathRecipient() {
9955            @Override
9956            public void binderDied() {
9957                synchronized (this) {
9958                    notifyAll();
9959                }
9960            }
9961        };
9962
9963        try {
9964            who.linkToDeath(death, 0);
9965        } catch (RemoteException e) {
9966            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9967            return;
9968        }
9969
9970        synchronized (this) {
9971            Watchdog.getInstance().setAllowRestart(allowRestart);
9972            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9973            synchronized (death) {
9974                while (who.isBinderAlive()) {
9975                    try {
9976                        death.wait();
9977                    } catch (InterruptedException e) {
9978                    }
9979                }
9980            }
9981            Watchdog.getInstance().setAllowRestart(true);
9982        }
9983    }
9984
9985    @Override
9986    public void restart() {
9987        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9988                != PackageManager.PERMISSION_GRANTED) {
9989            throw new SecurityException("Requires permission "
9990                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9991        }
9992
9993        Log.i(TAG, "Sending shutdown broadcast...");
9994
9995        BroadcastReceiver br = new BroadcastReceiver() {
9996            @Override public void onReceive(Context context, Intent intent) {
9997                // Now the broadcast is done, finish up the low-level shutdown.
9998                Log.i(TAG, "Shutting down activity manager...");
9999                shutdown(10000);
10000                Log.i(TAG, "Shutdown complete, restarting!");
10001                Process.killProcess(Process.myPid());
10002                System.exit(10);
10003            }
10004        };
10005
10006        // First send the high-level shut down broadcast.
10007        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10008        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10009        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10010        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10011        mContext.sendOrderedBroadcastAsUser(intent,
10012                UserHandle.ALL, null, br, mHandler, 0, null, null);
10013        */
10014        br.onReceive(mContext, intent);
10015    }
10016
10017    private long getLowRamTimeSinceIdle(long now) {
10018        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10019    }
10020
10021    @Override
10022    public void performIdleMaintenance() {
10023        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10024                != PackageManager.PERMISSION_GRANTED) {
10025            throw new SecurityException("Requires permission "
10026                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10027        }
10028
10029        synchronized (this) {
10030            final long now = SystemClock.uptimeMillis();
10031            final long timeSinceLastIdle = now - mLastIdleTime;
10032            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10033            mLastIdleTime = now;
10034            mLowRamTimeSinceLastIdle = 0;
10035            if (mLowRamStartTime != 0) {
10036                mLowRamStartTime = now;
10037            }
10038
10039            StringBuilder sb = new StringBuilder(128);
10040            sb.append("Idle maintenance over ");
10041            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10042            sb.append(" low RAM for ");
10043            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10044            Slog.i(TAG, sb.toString());
10045
10046            // If at least 1/3 of our time since the last idle period has been spent
10047            // with RAM low, then we want to kill processes.
10048            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10049
10050            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10051                ProcessRecord proc = mLruProcesses.get(i);
10052                if (proc.notCachedSinceIdle) {
10053                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10054                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10055                        if (doKilling && proc.initialIdlePss != 0
10056                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10057                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10058                                    + " from " + proc.initialIdlePss + ")");
10059                        }
10060                    }
10061                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10062                    proc.notCachedSinceIdle = true;
10063                    proc.initialIdlePss = 0;
10064                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10065                            isSleeping(), now);
10066                }
10067            }
10068
10069            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10070            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10071        }
10072    }
10073
10074    private void retrieveSettings() {
10075        final ContentResolver resolver = mContext.getContentResolver();
10076        String debugApp = Settings.Global.getString(
10077            resolver, Settings.Global.DEBUG_APP);
10078        boolean waitForDebugger = Settings.Global.getInt(
10079            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10080        boolean alwaysFinishActivities = Settings.Global.getInt(
10081            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10082        boolean forceRtl = Settings.Global.getInt(
10083                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10084        // Transfer any global setting for forcing RTL layout, into a System Property
10085        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10086
10087        Configuration configuration = new Configuration();
10088        Settings.System.getConfiguration(resolver, configuration);
10089        if (forceRtl) {
10090            // This will take care of setting the correct layout direction flags
10091            configuration.setLayoutDirection(configuration.locale);
10092        }
10093
10094        synchronized (this) {
10095            mDebugApp = mOrigDebugApp = debugApp;
10096            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10097            mAlwaysFinishActivities = alwaysFinishActivities;
10098            // This happens before any activities are started, so we can
10099            // change mConfiguration in-place.
10100            updateConfigurationLocked(configuration, null, false, true);
10101            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10102        }
10103    }
10104
10105    public boolean testIsSystemReady() {
10106        // no need to synchronize(this) just to read & return the value
10107        return mSystemReady;
10108    }
10109
10110    private static File getCalledPreBootReceiversFile() {
10111        File dataDir = Environment.getDataDirectory();
10112        File systemDir = new File(dataDir, "system");
10113        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10114        return fname;
10115    }
10116
10117    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10118        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10119        File file = getCalledPreBootReceiversFile();
10120        FileInputStream fis = null;
10121        try {
10122            fis = new FileInputStream(file);
10123            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10124            int fvers = dis.readInt();
10125            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10126                String vers = dis.readUTF();
10127                String codename = dis.readUTF();
10128                String build = dis.readUTF();
10129                if (android.os.Build.VERSION.RELEASE.equals(vers)
10130                        && android.os.Build.VERSION.CODENAME.equals(codename)
10131                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10132                    int num = dis.readInt();
10133                    while (num > 0) {
10134                        num--;
10135                        String pkg = dis.readUTF();
10136                        String cls = dis.readUTF();
10137                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10138                    }
10139                }
10140            }
10141        } catch (FileNotFoundException e) {
10142        } catch (IOException e) {
10143            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10144        } finally {
10145            if (fis != null) {
10146                try {
10147                    fis.close();
10148                } catch (IOException e) {
10149                }
10150            }
10151        }
10152        return lastDoneReceivers;
10153    }
10154
10155    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10156        File file = getCalledPreBootReceiversFile();
10157        FileOutputStream fos = null;
10158        DataOutputStream dos = null;
10159        try {
10160            fos = new FileOutputStream(file);
10161            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10162            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10163            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10164            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10165            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10166            dos.writeInt(list.size());
10167            for (int i=0; i<list.size(); i++) {
10168                dos.writeUTF(list.get(i).getPackageName());
10169                dos.writeUTF(list.get(i).getClassName());
10170            }
10171        } catch (IOException e) {
10172            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10173            file.delete();
10174        } finally {
10175            FileUtils.sync(fos);
10176            if (dos != null) {
10177                try {
10178                    dos.close();
10179                } catch (IOException e) {
10180                    // TODO Auto-generated catch block
10181                    e.printStackTrace();
10182                }
10183            }
10184        }
10185    }
10186
10187    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10188            ArrayList<ComponentName> doneReceivers, int userId) {
10189        boolean waitingUpdate = false;
10190        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10191        List<ResolveInfo> ris = null;
10192        try {
10193            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10194                    intent, null, 0, userId);
10195        } catch (RemoteException e) {
10196        }
10197        if (ris != null) {
10198            for (int i=ris.size()-1; i>=0; i--) {
10199                if ((ris.get(i).activityInfo.applicationInfo.flags
10200                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10201                    ris.remove(i);
10202                }
10203            }
10204            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10205
10206            // For User 0, load the version number. When delivering to a new user, deliver
10207            // to all receivers.
10208            if (userId == UserHandle.USER_OWNER) {
10209                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10210                for (int i=0; i<ris.size(); i++) {
10211                    ActivityInfo ai = ris.get(i).activityInfo;
10212                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10213                    if (lastDoneReceivers.contains(comp)) {
10214                        // We already did the pre boot receiver for this app with the current
10215                        // platform version, so don't do it again...
10216                        ris.remove(i);
10217                        i--;
10218                        // ...however, do keep it as one that has been done, so we don't
10219                        // forget about it when rewriting the file of last done receivers.
10220                        doneReceivers.add(comp);
10221                    }
10222                }
10223            }
10224
10225            // If primary user, send broadcast to all available users, else just to userId
10226            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10227                    : new int[] { userId };
10228            for (int i = 0; i < ris.size(); i++) {
10229                ActivityInfo ai = ris.get(i).activityInfo;
10230                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10231                doneReceivers.add(comp);
10232                intent.setComponent(comp);
10233                for (int j=0; j<users.length; j++) {
10234                    IIntentReceiver finisher = null;
10235                    // On last receiver and user, set up a completion callback
10236                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10237                        finisher = new IIntentReceiver.Stub() {
10238                            public void performReceive(Intent intent, int resultCode,
10239                                    String data, Bundle extras, boolean ordered,
10240                                    boolean sticky, int sendingUser) {
10241                                // The raw IIntentReceiver interface is called
10242                                // with the AM lock held, so redispatch to
10243                                // execute our code without the lock.
10244                                mHandler.post(onFinishCallback);
10245                            }
10246                        };
10247                    }
10248                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10249                            + " for user " + users[j]);
10250                    broadcastIntentLocked(null, null, intent, null, finisher,
10251                            0, null, null, null, AppOpsManager.OP_NONE,
10252                            true, false, MY_PID, Process.SYSTEM_UID,
10253                            users[j]);
10254                    if (finisher != null) {
10255                        waitingUpdate = true;
10256                    }
10257                }
10258            }
10259        }
10260
10261        return waitingUpdate;
10262    }
10263
10264    public void systemReady(final Runnable goingCallback) {
10265        synchronized(this) {
10266            if (mSystemReady) {
10267                // If we're done calling all the receivers, run the next "boot phase" passed in
10268                // by the SystemServer
10269                if (goingCallback != null) {
10270                    goingCallback.run();
10271                }
10272                return;
10273            }
10274
10275            // Make sure we have the current profile info, since it is needed for
10276            // security checks.
10277            updateCurrentProfileIdsLocked();
10278
10279            if (mRecentTasks == null) {
10280                mRecentTasks = mTaskPersister.restoreTasksLocked();
10281                if (!mRecentTasks.isEmpty()) {
10282                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10283                }
10284                mTaskPersister.startPersisting();
10285            }
10286
10287            // Check to see if there are any update receivers to run.
10288            if (!mDidUpdate) {
10289                if (mWaitingUpdate) {
10290                    return;
10291                }
10292                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10293                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10294                    public void run() {
10295                        synchronized (ActivityManagerService.this) {
10296                            mDidUpdate = true;
10297                        }
10298                        writeLastDonePreBootReceivers(doneReceivers);
10299                        showBootMessage(mContext.getText(
10300                                R.string.android_upgrading_complete),
10301                                false);
10302                        systemReady(goingCallback);
10303                    }
10304                }, doneReceivers, UserHandle.USER_OWNER);
10305
10306                if (mWaitingUpdate) {
10307                    return;
10308                }
10309                mDidUpdate = true;
10310            }
10311
10312            mAppOpsService.systemReady();
10313            mSystemReady = true;
10314        }
10315
10316        ArrayList<ProcessRecord> procsToKill = null;
10317        synchronized(mPidsSelfLocked) {
10318            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10319                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10320                if (!isAllowedWhileBooting(proc.info)){
10321                    if (procsToKill == null) {
10322                        procsToKill = new ArrayList<ProcessRecord>();
10323                    }
10324                    procsToKill.add(proc);
10325                }
10326            }
10327        }
10328
10329        synchronized(this) {
10330            if (procsToKill != null) {
10331                for (int i=procsToKill.size()-1; i>=0; i--) {
10332                    ProcessRecord proc = procsToKill.get(i);
10333                    Slog.i(TAG, "Removing system update proc: " + proc);
10334                    removeProcessLocked(proc, true, false, "system update done");
10335                }
10336            }
10337
10338            // Now that we have cleaned up any update processes, we
10339            // are ready to start launching real processes and know that
10340            // we won't trample on them any more.
10341            mProcessesReady = true;
10342        }
10343
10344        Slog.i(TAG, "System now ready");
10345        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10346            SystemClock.uptimeMillis());
10347
10348        synchronized(this) {
10349            // Make sure we have no pre-ready processes sitting around.
10350
10351            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10352                ResolveInfo ri = mContext.getPackageManager()
10353                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10354                                STOCK_PM_FLAGS);
10355                CharSequence errorMsg = null;
10356                if (ri != null) {
10357                    ActivityInfo ai = ri.activityInfo;
10358                    ApplicationInfo app = ai.applicationInfo;
10359                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10360                        mTopAction = Intent.ACTION_FACTORY_TEST;
10361                        mTopData = null;
10362                        mTopComponent = new ComponentName(app.packageName,
10363                                ai.name);
10364                    } else {
10365                        errorMsg = mContext.getResources().getText(
10366                                com.android.internal.R.string.factorytest_not_system);
10367                    }
10368                } else {
10369                    errorMsg = mContext.getResources().getText(
10370                            com.android.internal.R.string.factorytest_no_action);
10371                }
10372                if (errorMsg != null) {
10373                    mTopAction = null;
10374                    mTopData = null;
10375                    mTopComponent = null;
10376                    Message msg = Message.obtain();
10377                    msg.what = SHOW_FACTORY_ERROR_MSG;
10378                    msg.getData().putCharSequence("msg", errorMsg);
10379                    mHandler.sendMessage(msg);
10380                }
10381            }
10382        }
10383
10384        retrieveSettings();
10385
10386        synchronized (this) {
10387            readGrantedUriPermissionsLocked();
10388        }
10389
10390        if (goingCallback != null) goingCallback.run();
10391
10392        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10393                Integer.toString(mCurrentUserId), mCurrentUserId);
10394        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10395                Integer.toString(mCurrentUserId), mCurrentUserId);
10396        mSystemServiceManager.startUser(mCurrentUserId);
10397
10398        synchronized (this) {
10399            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10400                try {
10401                    List apps = AppGlobals.getPackageManager().
10402                        getPersistentApplications(STOCK_PM_FLAGS);
10403                    if (apps != null) {
10404                        int N = apps.size();
10405                        int i;
10406                        for (i=0; i<N; i++) {
10407                            ApplicationInfo info
10408                                = (ApplicationInfo)apps.get(i);
10409                            if (info != null &&
10410                                    !info.packageName.equals("android")) {
10411                                addAppLocked(info, false, null /* ABI override */);
10412                            }
10413                        }
10414                    }
10415                } catch (RemoteException ex) {
10416                    // pm is in same process, this will never happen.
10417                }
10418            }
10419
10420            // Start up initial activity.
10421            mBooting = true;
10422
10423            try {
10424                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10425                    Message msg = Message.obtain();
10426                    msg.what = SHOW_UID_ERROR_MSG;
10427                    mHandler.sendMessage(msg);
10428                }
10429            } catch (RemoteException e) {
10430            }
10431
10432            long ident = Binder.clearCallingIdentity();
10433            try {
10434                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10435                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10436                        | Intent.FLAG_RECEIVER_FOREGROUND);
10437                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10438                broadcastIntentLocked(null, null, intent,
10439                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10440                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10441                intent = new Intent(Intent.ACTION_USER_STARTING);
10442                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10443                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10444                broadcastIntentLocked(null, null, intent,
10445                        null, new IIntentReceiver.Stub() {
10446                            @Override
10447                            public void performReceive(Intent intent, int resultCode, String data,
10448                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10449                                    throws RemoteException {
10450                            }
10451                        }, 0, null, null,
10452                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10453                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10454            } catch (Throwable t) {
10455                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10456            } finally {
10457                Binder.restoreCallingIdentity(ident);
10458            }
10459            mStackSupervisor.resumeTopActivitiesLocked();
10460            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10461        }
10462    }
10463
10464    private boolean makeAppCrashingLocked(ProcessRecord app,
10465            String shortMsg, String longMsg, String stackTrace) {
10466        app.crashing = true;
10467        app.crashingReport = generateProcessError(app,
10468                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10469        startAppProblemLocked(app);
10470        app.stopFreezingAllLocked();
10471        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10472    }
10473
10474    private void makeAppNotRespondingLocked(ProcessRecord app,
10475            String activity, String shortMsg, String longMsg) {
10476        app.notResponding = true;
10477        app.notRespondingReport = generateProcessError(app,
10478                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10479                activity, shortMsg, longMsg, null);
10480        startAppProblemLocked(app);
10481        app.stopFreezingAllLocked();
10482    }
10483
10484    /**
10485     * Generate a process error record, suitable for attachment to a ProcessRecord.
10486     *
10487     * @param app The ProcessRecord in which the error occurred.
10488     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10489     *                      ActivityManager.AppErrorStateInfo
10490     * @param activity The activity associated with the crash, if known.
10491     * @param shortMsg Short message describing the crash.
10492     * @param longMsg Long message describing the crash.
10493     * @param stackTrace Full crash stack trace, may be null.
10494     *
10495     * @return Returns a fully-formed AppErrorStateInfo record.
10496     */
10497    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10498            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10499        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10500
10501        report.condition = condition;
10502        report.processName = app.processName;
10503        report.pid = app.pid;
10504        report.uid = app.info.uid;
10505        report.tag = activity;
10506        report.shortMsg = shortMsg;
10507        report.longMsg = longMsg;
10508        report.stackTrace = stackTrace;
10509
10510        return report;
10511    }
10512
10513    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10514        synchronized (this) {
10515            app.crashing = false;
10516            app.crashingReport = null;
10517            app.notResponding = false;
10518            app.notRespondingReport = null;
10519            if (app.anrDialog == fromDialog) {
10520                app.anrDialog = null;
10521            }
10522            if (app.waitDialog == fromDialog) {
10523                app.waitDialog = null;
10524            }
10525            if (app.pid > 0 && app.pid != MY_PID) {
10526                handleAppCrashLocked(app, null, null, null);
10527                killUnneededProcessLocked(app, "user request after error");
10528            }
10529        }
10530    }
10531
10532    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10533            String stackTrace) {
10534        long now = SystemClock.uptimeMillis();
10535
10536        Long crashTime;
10537        if (!app.isolated) {
10538            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10539        } else {
10540            crashTime = null;
10541        }
10542        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10543            // This process loses!
10544            Slog.w(TAG, "Process " + app.info.processName
10545                    + " has crashed too many times: killing!");
10546            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10547                    app.userId, app.info.processName, app.uid);
10548            mStackSupervisor.handleAppCrashLocked(app);
10549            if (!app.persistent) {
10550                // We don't want to start this process again until the user
10551                // explicitly does so...  but for persistent process, we really
10552                // need to keep it running.  If a persistent process is actually
10553                // repeatedly crashing, then badness for everyone.
10554                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10555                        app.info.processName);
10556                if (!app.isolated) {
10557                    // XXX We don't have a way to mark isolated processes
10558                    // as bad, since they don't have a peristent identity.
10559                    mBadProcesses.put(app.info.processName, app.uid,
10560                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10561                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10562                }
10563                app.bad = true;
10564                app.removed = true;
10565                // Don't let services in this process be restarted and potentially
10566                // annoy the user repeatedly.  Unless it is persistent, since those
10567                // processes run critical code.
10568                removeProcessLocked(app, false, false, "crash");
10569                mStackSupervisor.resumeTopActivitiesLocked();
10570                return false;
10571            }
10572            mStackSupervisor.resumeTopActivitiesLocked();
10573        } else {
10574            mStackSupervisor.finishTopRunningActivityLocked(app);
10575        }
10576
10577        // Bump up the crash count of any services currently running in the proc.
10578        for (int i=app.services.size()-1; i>=0; i--) {
10579            // Any services running in the application need to be placed
10580            // back in the pending list.
10581            ServiceRecord sr = app.services.valueAt(i);
10582            sr.crashCount++;
10583        }
10584
10585        // If the crashing process is what we consider to be the "home process" and it has been
10586        // replaced by a third-party app, clear the package preferred activities from packages
10587        // with a home activity running in the process to prevent a repeatedly crashing app
10588        // from blocking the user to manually clear the list.
10589        final ArrayList<ActivityRecord> activities = app.activities;
10590        if (app == mHomeProcess && activities.size() > 0
10591                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10592            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10593                final ActivityRecord r = activities.get(activityNdx);
10594                if (r.isHomeActivity()) {
10595                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10596                    try {
10597                        ActivityThread.getPackageManager()
10598                                .clearPackagePreferredActivities(r.packageName);
10599                    } catch (RemoteException c) {
10600                        // pm is in same process, this will never happen.
10601                    }
10602                }
10603            }
10604        }
10605
10606        if (!app.isolated) {
10607            // XXX Can't keep track of crash times for isolated processes,
10608            // because they don't have a perisistent identity.
10609            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10610        }
10611
10612        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10613        return true;
10614    }
10615
10616    void startAppProblemLocked(ProcessRecord app) {
10617        // If this app is not running under the current user, then we
10618        // can't give it a report button because that would require
10619        // launching the report UI under a different user.
10620        app.errorReportReceiver = null;
10621
10622        for (int userId : mCurrentProfileIds) {
10623            if (app.userId == userId) {
10624                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10625                        mContext, app.info.packageName, app.info.flags);
10626            }
10627        }
10628        skipCurrentReceiverLocked(app);
10629    }
10630
10631    void skipCurrentReceiverLocked(ProcessRecord app) {
10632        for (BroadcastQueue queue : mBroadcastQueues) {
10633            queue.skipCurrentReceiverLocked(app);
10634        }
10635    }
10636
10637    /**
10638     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10639     * The application process will exit immediately after this call returns.
10640     * @param app object of the crashing app, null for the system server
10641     * @param crashInfo describing the exception
10642     */
10643    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10644        ProcessRecord r = findAppProcess(app, "Crash");
10645        final String processName = app == null ? "system_server"
10646                : (r == null ? "unknown" : r.processName);
10647
10648        handleApplicationCrashInner("crash", r, processName, crashInfo);
10649    }
10650
10651    /* Native crash reporting uses this inner version because it needs to be somewhat
10652     * decoupled from the AM-managed cleanup lifecycle
10653     */
10654    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10655            ApplicationErrorReport.CrashInfo crashInfo) {
10656        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10657                UserHandle.getUserId(Binder.getCallingUid()), processName,
10658                r == null ? -1 : r.info.flags,
10659                crashInfo.exceptionClassName,
10660                crashInfo.exceptionMessage,
10661                crashInfo.throwFileName,
10662                crashInfo.throwLineNumber);
10663
10664        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10665
10666        crashApplication(r, crashInfo);
10667    }
10668
10669    public void handleApplicationStrictModeViolation(
10670            IBinder app,
10671            int violationMask,
10672            StrictMode.ViolationInfo info) {
10673        ProcessRecord r = findAppProcess(app, "StrictMode");
10674        if (r == null) {
10675            return;
10676        }
10677
10678        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10679            Integer stackFingerprint = info.hashCode();
10680            boolean logIt = true;
10681            synchronized (mAlreadyLoggedViolatedStacks) {
10682                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10683                    logIt = false;
10684                    // TODO: sub-sample into EventLog for these, with
10685                    // the info.durationMillis?  Then we'd get
10686                    // the relative pain numbers, without logging all
10687                    // the stack traces repeatedly.  We'd want to do
10688                    // likewise in the client code, which also does
10689                    // dup suppression, before the Binder call.
10690                } else {
10691                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10692                        mAlreadyLoggedViolatedStacks.clear();
10693                    }
10694                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10695                }
10696            }
10697            if (logIt) {
10698                logStrictModeViolationToDropBox(r, info);
10699            }
10700        }
10701
10702        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10703            AppErrorResult result = new AppErrorResult();
10704            synchronized (this) {
10705                final long origId = Binder.clearCallingIdentity();
10706
10707                Message msg = Message.obtain();
10708                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10709                HashMap<String, Object> data = new HashMap<String, Object>();
10710                data.put("result", result);
10711                data.put("app", r);
10712                data.put("violationMask", violationMask);
10713                data.put("info", info);
10714                msg.obj = data;
10715                mHandler.sendMessage(msg);
10716
10717                Binder.restoreCallingIdentity(origId);
10718            }
10719            int res = result.get();
10720            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10721        }
10722    }
10723
10724    // Depending on the policy in effect, there could be a bunch of
10725    // these in quick succession so we try to batch these together to
10726    // minimize disk writes, number of dropbox entries, and maximize
10727    // compression, by having more fewer, larger records.
10728    private void logStrictModeViolationToDropBox(
10729            ProcessRecord process,
10730            StrictMode.ViolationInfo info) {
10731        if (info == null) {
10732            return;
10733        }
10734        final boolean isSystemApp = process == null ||
10735                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10736                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10737        final String processName = process == null ? "unknown" : process.processName;
10738        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10739        final DropBoxManager dbox = (DropBoxManager)
10740                mContext.getSystemService(Context.DROPBOX_SERVICE);
10741
10742        // Exit early if the dropbox isn't configured to accept this report type.
10743        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10744
10745        boolean bufferWasEmpty;
10746        boolean needsFlush;
10747        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10748        synchronized (sb) {
10749            bufferWasEmpty = sb.length() == 0;
10750            appendDropBoxProcessHeaders(process, processName, sb);
10751            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10752            sb.append("System-App: ").append(isSystemApp).append("\n");
10753            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10754            if (info.violationNumThisLoop != 0) {
10755                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10756            }
10757            if (info.numAnimationsRunning != 0) {
10758                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10759            }
10760            if (info.broadcastIntentAction != null) {
10761                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10762            }
10763            if (info.durationMillis != -1) {
10764                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10765            }
10766            if (info.numInstances != -1) {
10767                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10768            }
10769            if (info.tags != null) {
10770                for (String tag : info.tags) {
10771                    sb.append("Span-Tag: ").append(tag).append("\n");
10772                }
10773            }
10774            sb.append("\n");
10775            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10776                sb.append(info.crashInfo.stackTrace);
10777            }
10778            sb.append("\n");
10779
10780            // Only buffer up to ~64k.  Various logging bits truncate
10781            // things at 128k.
10782            needsFlush = (sb.length() > 64 * 1024);
10783        }
10784
10785        // Flush immediately if the buffer's grown too large, or this
10786        // is a non-system app.  Non-system apps are isolated with a
10787        // different tag & policy and not batched.
10788        //
10789        // Batching is useful during internal testing with
10790        // StrictMode settings turned up high.  Without batching,
10791        // thousands of separate files could be created on boot.
10792        if (!isSystemApp || needsFlush) {
10793            new Thread("Error dump: " + dropboxTag) {
10794                @Override
10795                public void run() {
10796                    String report;
10797                    synchronized (sb) {
10798                        report = sb.toString();
10799                        sb.delete(0, sb.length());
10800                        sb.trimToSize();
10801                    }
10802                    if (report.length() != 0) {
10803                        dbox.addText(dropboxTag, report);
10804                    }
10805                }
10806            }.start();
10807            return;
10808        }
10809
10810        // System app batching:
10811        if (!bufferWasEmpty) {
10812            // An existing dropbox-writing thread is outstanding, so
10813            // we don't need to start it up.  The existing thread will
10814            // catch the buffer appends we just did.
10815            return;
10816        }
10817
10818        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10819        // (After this point, we shouldn't access AMS internal data structures.)
10820        new Thread("Error dump: " + dropboxTag) {
10821            @Override
10822            public void run() {
10823                // 5 second sleep to let stacks arrive and be batched together
10824                try {
10825                    Thread.sleep(5000);  // 5 seconds
10826                } catch (InterruptedException e) {}
10827
10828                String errorReport;
10829                synchronized (mStrictModeBuffer) {
10830                    errorReport = mStrictModeBuffer.toString();
10831                    if (errorReport.length() == 0) {
10832                        return;
10833                    }
10834                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10835                    mStrictModeBuffer.trimToSize();
10836                }
10837                dbox.addText(dropboxTag, errorReport);
10838            }
10839        }.start();
10840    }
10841
10842    /**
10843     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10844     * @param app object of the crashing app, null for the system server
10845     * @param tag reported by the caller
10846     * @param crashInfo describing the context of the error
10847     * @return true if the process should exit immediately (WTF is fatal)
10848     */
10849    public boolean handleApplicationWtf(IBinder app, String tag,
10850            ApplicationErrorReport.CrashInfo crashInfo) {
10851        ProcessRecord r = findAppProcess(app, "WTF");
10852        final String processName = app == null ? "system_server"
10853                : (r == null ? "unknown" : r.processName);
10854
10855        EventLog.writeEvent(EventLogTags.AM_WTF,
10856                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10857                processName,
10858                r == null ? -1 : r.info.flags,
10859                tag, crashInfo.exceptionMessage);
10860
10861        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10862
10863        if (r != null && r.pid != Process.myPid() &&
10864                Settings.Global.getInt(mContext.getContentResolver(),
10865                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10866            crashApplication(r, crashInfo);
10867            return true;
10868        } else {
10869            return false;
10870        }
10871    }
10872
10873    /**
10874     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10875     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10876     */
10877    private ProcessRecord findAppProcess(IBinder app, String reason) {
10878        if (app == null) {
10879            return null;
10880        }
10881
10882        synchronized (this) {
10883            final int NP = mProcessNames.getMap().size();
10884            for (int ip=0; ip<NP; ip++) {
10885                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10886                final int NA = apps.size();
10887                for (int ia=0; ia<NA; ia++) {
10888                    ProcessRecord p = apps.valueAt(ia);
10889                    if (p.thread != null && p.thread.asBinder() == app) {
10890                        return p;
10891                    }
10892                }
10893            }
10894
10895            Slog.w(TAG, "Can't find mystery application for " + reason
10896                    + " from pid=" + Binder.getCallingPid()
10897                    + " uid=" + Binder.getCallingUid() + ": " + app);
10898            return null;
10899        }
10900    }
10901
10902    /**
10903     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10904     * to append various headers to the dropbox log text.
10905     */
10906    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10907            StringBuilder sb) {
10908        // Watchdog thread ends up invoking this function (with
10909        // a null ProcessRecord) to add the stack file to dropbox.
10910        // Do not acquire a lock on this (am) in such cases, as it
10911        // could cause a potential deadlock, if and when watchdog
10912        // is invoked due to unavailability of lock on am and it
10913        // would prevent watchdog from killing system_server.
10914        if (process == null) {
10915            sb.append("Process: ").append(processName).append("\n");
10916            return;
10917        }
10918        // Note: ProcessRecord 'process' is guarded by the service
10919        // instance.  (notably process.pkgList, which could otherwise change
10920        // concurrently during execution of this method)
10921        synchronized (this) {
10922            sb.append("Process: ").append(processName).append("\n");
10923            int flags = process.info.flags;
10924            IPackageManager pm = AppGlobals.getPackageManager();
10925            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10926            for (int ip=0; ip<process.pkgList.size(); ip++) {
10927                String pkg = process.pkgList.keyAt(ip);
10928                sb.append("Package: ").append(pkg);
10929                try {
10930                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10931                    if (pi != null) {
10932                        sb.append(" v").append(pi.versionCode);
10933                        if (pi.versionName != null) {
10934                            sb.append(" (").append(pi.versionName).append(")");
10935                        }
10936                    }
10937                } catch (RemoteException e) {
10938                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10939                }
10940                sb.append("\n");
10941            }
10942        }
10943    }
10944
10945    private static String processClass(ProcessRecord process) {
10946        if (process == null || process.pid == MY_PID) {
10947            return "system_server";
10948        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10949            return "system_app";
10950        } else {
10951            return "data_app";
10952        }
10953    }
10954
10955    /**
10956     * Write a description of an error (crash, WTF, ANR) to the drop box.
10957     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10958     * @param process which caused the error, null means the system server
10959     * @param activity which triggered the error, null if unknown
10960     * @param parent activity related to the error, null if unknown
10961     * @param subject line related to the error, null if absent
10962     * @param report in long form describing the error, null if absent
10963     * @param logFile to include in the report, null if none
10964     * @param crashInfo giving an application stack trace, null if absent
10965     */
10966    public void addErrorToDropBox(String eventType,
10967            ProcessRecord process, String processName, ActivityRecord activity,
10968            ActivityRecord parent, String subject,
10969            final String report, final File logFile,
10970            final ApplicationErrorReport.CrashInfo crashInfo) {
10971        // NOTE -- this must never acquire the ActivityManagerService lock,
10972        // otherwise the watchdog may be prevented from resetting the system.
10973
10974        final String dropboxTag = processClass(process) + "_" + eventType;
10975        final DropBoxManager dbox = (DropBoxManager)
10976                mContext.getSystemService(Context.DROPBOX_SERVICE);
10977
10978        // Exit early if the dropbox isn't configured to accept this report type.
10979        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10980
10981        final StringBuilder sb = new StringBuilder(1024);
10982        appendDropBoxProcessHeaders(process, processName, sb);
10983        if (activity != null) {
10984            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10985        }
10986        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10987            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10988        }
10989        if (parent != null && parent != activity) {
10990            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10991        }
10992        if (subject != null) {
10993            sb.append("Subject: ").append(subject).append("\n");
10994        }
10995        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10996        if (Debug.isDebuggerConnected()) {
10997            sb.append("Debugger: Connected\n");
10998        }
10999        sb.append("\n");
11000
11001        // Do the rest in a worker thread to avoid blocking the caller on I/O
11002        // (After this point, we shouldn't access AMS internal data structures.)
11003        Thread worker = new Thread("Error dump: " + dropboxTag) {
11004            @Override
11005            public void run() {
11006                if (report != null) {
11007                    sb.append(report);
11008                }
11009                if (logFile != null) {
11010                    try {
11011                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11012                                    "\n\n[[TRUNCATED]]"));
11013                    } catch (IOException e) {
11014                        Slog.e(TAG, "Error reading " + logFile, e);
11015                    }
11016                }
11017                if (crashInfo != null && crashInfo.stackTrace != null) {
11018                    sb.append(crashInfo.stackTrace);
11019                }
11020
11021                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11022                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11023                if (lines > 0) {
11024                    sb.append("\n");
11025
11026                    // Merge several logcat streams, and take the last N lines
11027                    InputStreamReader input = null;
11028                    try {
11029                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11030                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11031                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11032
11033                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11034                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11035                        input = new InputStreamReader(logcat.getInputStream());
11036
11037                        int num;
11038                        char[] buf = new char[8192];
11039                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11040                    } catch (IOException e) {
11041                        Slog.e(TAG, "Error running logcat", e);
11042                    } finally {
11043                        if (input != null) try { input.close(); } catch (IOException e) {}
11044                    }
11045                }
11046
11047                dbox.addText(dropboxTag, sb.toString());
11048            }
11049        };
11050
11051        if (process == null) {
11052            // If process is null, we are being called from some internal code
11053            // and may be about to die -- run this synchronously.
11054            worker.run();
11055        } else {
11056            worker.start();
11057        }
11058    }
11059
11060    /**
11061     * Bring up the "unexpected error" dialog box for a crashing app.
11062     * Deal with edge cases (intercepts from instrumented applications,
11063     * ActivityController, error intent receivers, that sort of thing).
11064     * @param r the application crashing
11065     * @param crashInfo describing the failure
11066     */
11067    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11068        long timeMillis = System.currentTimeMillis();
11069        String shortMsg = crashInfo.exceptionClassName;
11070        String longMsg = crashInfo.exceptionMessage;
11071        String stackTrace = crashInfo.stackTrace;
11072        if (shortMsg != null && longMsg != null) {
11073            longMsg = shortMsg + ": " + longMsg;
11074        } else if (shortMsg != null) {
11075            longMsg = shortMsg;
11076        }
11077
11078        AppErrorResult result = new AppErrorResult();
11079        synchronized (this) {
11080            if (mController != null) {
11081                try {
11082                    String name = r != null ? r.processName : null;
11083                    int pid = r != null ? r.pid : Binder.getCallingPid();
11084                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11085                    if (!mController.appCrashed(name, pid,
11086                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11087                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11088                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11089                            Slog.w(TAG, "Skip killing native crashed app " + name
11090                                    + "(" + pid + ") during testing");
11091                        } else {
11092                            Slog.w(TAG, "Force-killing crashed app " + name
11093                                    + " at watcher's request");
11094                            Process.killProcess(pid);
11095                            if (r != null) {
11096                                Process.killProcessGroup(uid, pid);
11097                            }
11098                        }
11099                        return;
11100                    }
11101                } catch (RemoteException e) {
11102                    mController = null;
11103                    Watchdog.getInstance().setActivityController(null);
11104                }
11105            }
11106
11107            final long origId = Binder.clearCallingIdentity();
11108
11109            // If this process is running instrumentation, finish it.
11110            if (r != null && r.instrumentationClass != null) {
11111                Slog.w(TAG, "Error in app " + r.processName
11112                      + " running instrumentation " + r.instrumentationClass + ":");
11113                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11114                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11115                Bundle info = new Bundle();
11116                info.putString("shortMsg", shortMsg);
11117                info.putString("longMsg", longMsg);
11118                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11119                Binder.restoreCallingIdentity(origId);
11120                return;
11121            }
11122
11123            // If we can't identify the process or it's already exceeded its crash quota,
11124            // quit right away without showing a crash dialog.
11125            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11126                Binder.restoreCallingIdentity(origId);
11127                return;
11128            }
11129
11130            Message msg = Message.obtain();
11131            msg.what = SHOW_ERROR_MSG;
11132            HashMap data = new HashMap();
11133            data.put("result", result);
11134            data.put("app", r);
11135            msg.obj = data;
11136            mHandler.sendMessage(msg);
11137
11138            Binder.restoreCallingIdentity(origId);
11139        }
11140
11141        int res = result.get();
11142
11143        Intent appErrorIntent = null;
11144        synchronized (this) {
11145            if (r != null && !r.isolated) {
11146                // XXX Can't keep track of crash time for isolated processes,
11147                // since they don't have a persistent identity.
11148                mProcessCrashTimes.put(r.info.processName, r.uid,
11149                        SystemClock.uptimeMillis());
11150            }
11151            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11152                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11153            }
11154        }
11155
11156        if (appErrorIntent != null) {
11157            try {
11158                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11159            } catch (ActivityNotFoundException e) {
11160                Slog.w(TAG, "bug report receiver dissappeared", e);
11161            }
11162        }
11163    }
11164
11165    Intent createAppErrorIntentLocked(ProcessRecord r,
11166            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11167        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11168        if (report == null) {
11169            return null;
11170        }
11171        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11172        result.setComponent(r.errorReportReceiver);
11173        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11174        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11175        return result;
11176    }
11177
11178    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11179            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11180        if (r.errorReportReceiver == null) {
11181            return null;
11182        }
11183
11184        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11185            return null;
11186        }
11187
11188        ApplicationErrorReport report = new ApplicationErrorReport();
11189        report.packageName = r.info.packageName;
11190        report.installerPackageName = r.errorReportReceiver.getPackageName();
11191        report.processName = r.processName;
11192        report.time = timeMillis;
11193        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11194
11195        if (r.crashing || r.forceCrashReport) {
11196            report.type = ApplicationErrorReport.TYPE_CRASH;
11197            report.crashInfo = crashInfo;
11198        } else if (r.notResponding) {
11199            report.type = ApplicationErrorReport.TYPE_ANR;
11200            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11201
11202            report.anrInfo.activity = r.notRespondingReport.tag;
11203            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11204            report.anrInfo.info = r.notRespondingReport.longMsg;
11205        }
11206
11207        return report;
11208    }
11209
11210    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11211        enforceNotIsolatedCaller("getProcessesInErrorState");
11212        // assume our apps are happy - lazy create the list
11213        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11214
11215        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11216                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11217        int userId = UserHandle.getUserId(Binder.getCallingUid());
11218
11219        synchronized (this) {
11220
11221            // iterate across all processes
11222            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11223                ProcessRecord app = mLruProcesses.get(i);
11224                if (!allUsers && app.userId != userId) {
11225                    continue;
11226                }
11227                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11228                    // This one's in trouble, so we'll generate a report for it
11229                    // crashes are higher priority (in case there's a crash *and* an anr)
11230                    ActivityManager.ProcessErrorStateInfo report = null;
11231                    if (app.crashing) {
11232                        report = app.crashingReport;
11233                    } else if (app.notResponding) {
11234                        report = app.notRespondingReport;
11235                    }
11236
11237                    if (report != null) {
11238                        if (errList == null) {
11239                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11240                        }
11241                        errList.add(report);
11242                    } else {
11243                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11244                                " crashing = " + app.crashing +
11245                                " notResponding = " + app.notResponding);
11246                    }
11247                }
11248            }
11249        }
11250
11251        return errList;
11252    }
11253
11254    static int procStateToImportance(int procState, int memAdj,
11255            ActivityManager.RunningAppProcessInfo currApp) {
11256        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11257        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11258            currApp.lru = memAdj;
11259        } else {
11260            currApp.lru = 0;
11261        }
11262        return imp;
11263    }
11264
11265    private void fillInProcMemInfo(ProcessRecord app,
11266            ActivityManager.RunningAppProcessInfo outInfo) {
11267        outInfo.pid = app.pid;
11268        outInfo.uid = app.info.uid;
11269        if (mHeavyWeightProcess == app) {
11270            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11271        }
11272        if (app.persistent) {
11273            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11274        }
11275        if (app.activities.size() > 0) {
11276            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11277        }
11278        outInfo.lastTrimLevel = app.trimMemoryLevel;
11279        int adj = app.curAdj;
11280        int procState = app.curProcState;
11281        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11282        outInfo.importanceReasonCode = app.adjTypeCode;
11283        outInfo.processState = app.curProcState;
11284    }
11285
11286    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11287        enforceNotIsolatedCaller("getRunningAppProcesses");
11288        // Lazy instantiation of list
11289        List<ActivityManager.RunningAppProcessInfo> runList = null;
11290        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11291                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11292        int userId = UserHandle.getUserId(Binder.getCallingUid());
11293        synchronized (this) {
11294            // Iterate across all processes
11295            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11296                ProcessRecord app = mLruProcesses.get(i);
11297                if (!allUsers && app.userId != userId) {
11298                    continue;
11299                }
11300                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11301                    // Generate process state info for running application
11302                    ActivityManager.RunningAppProcessInfo currApp =
11303                        new ActivityManager.RunningAppProcessInfo(app.processName,
11304                                app.pid, app.getPackageList());
11305                    fillInProcMemInfo(app, currApp);
11306                    if (app.adjSource instanceof ProcessRecord) {
11307                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11308                        currApp.importanceReasonImportance =
11309                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11310                                        app.adjSourceProcState);
11311                    } else if (app.adjSource instanceof ActivityRecord) {
11312                        ActivityRecord r = (ActivityRecord)app.adjSource;
11313                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11314                    }
11315                    if (app.adjTarget instanceof ComponentName) {
11316                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11317                    }
11318                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11319                    //        + " lru=" + currApp.lru);
11320                    if (runList == null) {
11321                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11322                    }
11323                    runList.add(currApp);
11324                }
11325            }
11326        }
11327        return runList;
11328    }
11329
11330    public List<ApplicationInfo> getRunningExternalApplications() {
11331        enforceNotIsolatedCaller("getRunningExternalApplications");
11332        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11333        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11334        if (runningApps != null && runningApps.size() > 0) {
11335            Set<String> extList = new HashSet<String>();
11336            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11337                if (app.pkgList != null) {
11338                    for (String pkg : app.pkgList) {
11339                        extList.add(pkg);
11340                    }
11341                }
11342            }
11343            IPackageManager pm = AppGlobals.getPackageManager();
11344            for (String pkg : extList) {
11345                try {
11346                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11347                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11348                        retList.add(info);
11349                    }
11350                } catch (RemoteException e) {
11351                }
11352            }
11353        }
11354        return retList;
11355    }
11356
11357    @Override
11358    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11359        enforceNotIsolatedCaller("getMyMemoryState");
11360        synchronized (this) {
11361            ProcessRecord proc;
11362            synchronized (mPidsSelfLocked) {
11363                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11364            }
11365            fillInProcMemInfo(proc, outInfo);
11366        }
11367    }
11368
11369    @Override
11370    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11371        if (checkCallingPermission(android.Manifest.permission.DUMP)
11372                != PackageManager.PERMISSION_GRANTED) {
11373            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11374                    + Binder.getCallingPid()
11375                    + ", uid=" + Binder.getCallingUid()
11376                    + " without permission "
11377                    + android.Manifest.permission.DUMP);
11378            return;
11379        }
11380
11381        boolean dumpAll = false;
11382        boolean dumpClient = false;
11383        String dumpPackage = null;
11384
11385        int opti = 0;
11386        while (opti < args.length) {
11387            String opt = args[opti];
11388            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11389                break;
11390            }
11391            opti++;
11392            if ("-a".equals(opt)) {
11393                dumpAll = true;
11394            } else if ("-c".equals(opt)) {
11395                dumpClient = true;
11396            } else if ("-h".equals(opt)) {
11397                pw.println("Activity manager dump options:");
11398                pw.println("  [-a] [-c] [-h] [cmd] ...");
11399                pw.println("  cmd may be one of:");
11400                pw.println("    a[ctivities]: activity stack state");
11401                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11402                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11403                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11404                pw.println("    o[om]: out of memory management");
11405                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11406                pw.println("    provider [COMP_SPEC]: provider client-side state");
11407                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11408                pw.println("    service [COMP_SPEC]: service client-side state");
11409                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11410                pw.println("    all: dump all activities");
11411                pw.println("    top: dump the top activity");
11412                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11413                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11414                pw.println("    a partial substring in a component name, a");
11415                pw.println("    hex object identifier.");
11416                pw.println("  -a: include all available server state.");
11417                pw.println("  -c: include client state.");
11418                return;
11419            } else {
11420                pw.println("Unknown argument: " + opt + "; use -h for help");
11421            }
11422        }
11423
11424        long origId = Binder.clearCallingIdentity();
11425        boolean more = false;
11426        // Is the caller requesting to dump a particular piece of data?
11427        if (opti < args.length) {
11428            String cmd = args[opti];
11429            opti++;
11430            if ("activities".equals(cmd) || "a".equals(cmd)) {
11431                synchronized (this) {
11432                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11433                }
11434            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11435                String[] newArgs;
11436                String name;
11437                if (opti >= args.length) {
11438                    name = null;
11439                    newArgs = EMPTY_STRING_ARRAY;
11440                } else {
11441                    name = args[opti];
11442                    opti++;
11443                    newArgs = new String[args.length - opti];
11444                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11445                            args.length - opti);
11446                }
11447                synchronized (this) {
11448                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11449                }
11450            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11451                String[] newArgs;
11452                String name;
11453                if (opti >= args.length) {
11454                    name = null;
11455                    newArgs = EMPTY_STRING_ARRAY;
11456                } else {
11457                    name = args[opti];
11458                    opti++;
11459                    newArgs = new String[args.length - opti];
11460                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11461                            args.length - opti);
11462                }
11463                synchronized (this) {
11464                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11465                }
11466            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11467                String[] newArgs;
11468                String name;
11469                if (opti >= args.length) {
11470                    name = null;
11471                    newArgs = EMPTY_STRING_ARRAY;
11472                } else {
11473                    name = args[opti];
11474                    opti++;
11475                    newArgs = new String[args.length - opti];
11476                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11477                            args.length - opti);
11478                }
11479                synchronized (this) {
11480                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11481                }
11482            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11483                synchronized (this) {
11484                    dumpOomLocked(fd, pw, args, opti, true);
11485                }
11486            } else if ("provider".equals(cmd)) {
11487                String[] newArgs;
11488                String name;
11489                if (opti >= args.length) {
11490                    name = null;
11491                    newArgs = EMPTY_STRING_ARRAY;
11492                } else {
11493                    name = args[opti];
11494                    opti++;
11495                    newArgs = new String[args.length - opti];
11496                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11497                }
11498                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11499                    pw.println("No providers match: " + name);
11500                    pw.println("Use -h for help.");
11501                }
11502            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11503                synchronized (this) {
11504                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11505                }
11506            } else if ("service".equals(cmd)) {
11507                String[] newArgs;
11508                String name;
11509                if (opti >= args.length) {
11510                    name = null;
11511                    newArgs = EMPTY_STRING_ARRAY;
11512                } else {
11513                    name = args[opti];
11514                    opti++;
11515                    newArgs = new String[args.length - opti];
11516                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11517                            args.length - opti);
11518                }
11519                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11520                    pw.println("No services match: " + name);
11521                    pw.println("Use -h for help.");
11522                }
11523            } else if ("package".equals(cmd)) {
11524                String[] newArgs;
11525                if (opti >= args.length) {
11526                    pw.println("package: no package name specified");
11527                    pw.println("Use -h for help.");
11528                } else {
11529                    dumpPackage = args[opti];
11530                    opti++;
11531                    newArgs = new String[args.length - opti];
11532                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11533                            args.length - opti);
11534                    args = newArgs;
11535                    opti = 0;
11536                    more = true;
11537                }
11538            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11539                synchronized (this) {
11540                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11541                }
11542            } else {
11543                // Dumping a single activity?
11544                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11545                    pw.println("Bad activity command, or no activities match: " + cmd);
11546                    pw.println("Use -h for help.");
11547                }
11548            }
11549            if (!more) {
11550                Binder.restoreCallingIdentity(origId);
11551                return;
11552            }
11553        }
11554
11555        // No piece of data specified, dump everything.
11556        synchronized (this) {
11557            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11558            pw.println();
11559            if (dumpAll) {
11560                pw.println("-------------------------------------------------------------------------------");
11561            }
11562            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11563            pw.println();
11564            if (dumpAll) {
11565                pw.println("-------------------------------------------------------------------------------");
11566            }
11567            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11568            pw.println();
11569            if (dumpAll) {
11570                pw.println("-------------------------------------------------------------------------------");
11571            }
11572            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11573            pw.println();
11574            if (dumpAll) {
11575                pw.println("-------------------------------------------------------------------------------");
11576            }
11577            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11578            pw.println();
11579            if (dumpAll) {
11580                pw.println("-------------------------------------------------------------------------------");
11581            }
11582            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11583        }
11584        Binder.restoreCallingIdentity(origId);
11585    }
11586
11587    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11588            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11589        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11590
11591        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11592                dumpPackage);
11593        boolean needSep = printedAnything;
11594
11595        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11596                dumpPackage, needSep, "  mFocusedActivity: ");
11597        if (printed) {
11598            printedAnything = true;
11599            needSep = false;
11600        }
11601
11602        if (dumpPackage == null) {
11603            if (needSep) {
11604                pw.println();
11605            }
11606            needSep = true;
11607            printedAnything = true;
11608            mStackSupervisor.dump(pw, "  ");
11609        }
11610
11611        if (mRecentTasks.size() > 0) {
11612            boolean printedHeader = false;
11613
11614            final int N = mRecentTasks.size();
11615            for (int i=0; i<N; i++) {
11616                TaskRecord tr = mRecentTasks.get(i);
11617                if (dumpPackage != null) {
11618                    if (tr.realActivity == null ||
11619                            !dumpPackage.equals(tr.realActivity)) {
11620                        continue;
11621                    }
11622                }
11623                if (!printedHeader) {
11624                    if (needSep) {
11625                        pw.println();
11626                    }
11627                    pw.println("  Recent tasks:");
11628                    printedHeader = true;
11629                    printedAnything = true;
11630                }
11631                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11632                        pw.println(tr);
11633                if (dumpAll) {
11634                    mRecentTasks.get(i).dump(pw, "    ");
11635                }
11636            }
11637        }
11638
11639        if (!printedAnything) {
11640            pw.println("  (nothing)");
11641        }
11642    }
11643
11644    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11645            int opti, boolean dumpAll, String dumpPackage) {
11646        boolean needSep = false;
11647        boolean printedAnything = false;
11648        int numPers = 0;
11649
11650        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11651
11652        if (dumpAll) {
11653            final int NP = mProcessNames.getMap().size();
11654            for (int ip=0; ip<NP; ip++) {
11655                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11656                final int NA = procs.size();
11657                for (int ia=0; ia<NA; ia++) {
11658                    ProcessRecord r = procs.valueAt(ia);
11659                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11660                        continue;
11661                    }
11662                    if (!needSep) {
11663                        pw.println("  All known processes:");
11664                        needSep = true;
11665                        printedAnything = true;
11666                    }
11667                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11668                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11669                        pw.print(" "); pw.println(r);
11670                    r.dump(pw, "    ");
11671                    if (r.persistent) {
11672                        numPers++;
11673                    }
11674                }
11675            }
11676        }
11677
11678        if (mIsolatedProcesses.size() > 0) {
11679            boolean printed = false;
11680            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11681                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11682                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11683                    continue;
11684                }
11685                if (!printed) {
11686                    if (needSep) {
11687                        pw.println();
11688                    }
11689                    pw.println("  Isolated process list (sorted by uid):");
11690                    printedAnything = true;
11691                    printed = true;
11692                    needSep = true;
11693                }
11694                pw.println(String.format("%sIsolated #%2d: %s",
11695                        "    ", i, r.toString()));
11696            }
11697        }
11698
11699        if (mLruProcesses.size() > 0) {
11700            if (needSep) {
11701                pw.println();
11702            }
11703            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11704                    pw.print(" total, non-act at ");
11705                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11706                    pw.print(", non-svc at ");
11707                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11708                    pw.println("):");
11709            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11710            needSep = true;
11711            printedAnything = true;
11712        }
11713
11714        if (dumpAll || dumpPackage != null) {
11715            synchronized (mPidsSelfLocked) {
11716                boolean printed = false;
11717                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11718                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11719                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11720                        continue;
11721                    }
11722                    if (!printed) {
11723                        if (needSep) pw.println();
11724                        needSep = true;
11725                        pw.println("  PID mappings:");
11726                        printed = true;
11727                        printedAnything = true;
11728                    }
11729                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11730                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11731                }
11732            }
11733        }
11734
11735        if (mForegroundProcesses.size() > 0) {
11736            synchronized (mPidsSelfLocked) {
11737                boolean printed = false;
11738                for (int i=0; i<mForegroundProcesses.size(); i++) {
11739                    ProcessRecord r = mPidsSelfLocked.get(
11740                            mForegroundProcesses.valueAt(i).pid);
11741                    if (dumpPackage != null && (r == null
11742                            || !r.pkgList.containsKey(dumpPackage))) {
11743                        continue;
11744                    }
11745                    if (!printed) {
11746                        if (needSep) pw.println();
11747                        needSep = true;
11748                        pw.println("  Foreground Processes:");
11749                        printed = true;
11750                        printedAnything = true;
11751                    }
11752                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11753                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11754                }
11755            }
11756        }
11757
11758        if (mPersistentStartingProcesses.size() > 0) {
11759            if (needSep) pw.println();
11760            needSep = true;
11761            printedAnything = true;
11762            pw.println("  Persisent processes that are starting:");
11763            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11764                    "Starting Norm", "Restarting PERS", dumpPackage);
11765        }
11766
11767        if (mRemovedProcesses.size() > 0) {
11768            if (needSep) pw.println();
11769            needSep = true;
11770            printedAnything = true;
11771            pw.println("  Processes that are being removed:");
11772            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11773                    "Removed Norm", "Removed PERS", dumpPackage);
11774        }
11775
11776        if (mProcessesOnHold.size() > 0) {
11777            if (needSep) pw.println();
11778            needSep = true;
11779            printedAnything = true;
11780            pw.println("  Processes that are on old until the system is ready:");
11781            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11782                    "OnHold Norm", "OnHold PERS", dumpPackage);
11783        }
11784
11785        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11786
11787        if (mProcessCrashTimes.getMap().size() > 0) {
11788            boolean printed = false;
11789            long now = SystemClock.uptimeMillis();
11790            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11791            final int NP = pmap.size();
11792            for (int ip=0; ip<NP; ip++) {
11793                String pname = pmap.keyAt(ip);
11794                SparseArray<Long> uids = pmap.valueAt(ip);
11795                final int N = uids.size();
11796                for (int i=0; i<N; i++) {
11797                    int puid = uids.keyAt(i);
11798                    ProcessRecord r = mProcessNames.get(pname, puid);
11799                    if (dumpPackage != null && (r == null
11800                            || !r.pkgList.containsKey(dumpPackage))) {
11801                        continue;
11802                    }
11803                    if (!printed) {
11804                        if (needSep) pw.println();
11805                        needSep = true;
11806                        pw.println("  Time since processes crashed:");
11807                        printed = true;
11808                        printedAnything = true;
11809                    }
11810                    pw.print("    Process "); pw.print(pname);
11811                            pw.print(" uid "); pw.print(puid);
11812                            pw.print(": last crashed ");
11813                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11814                            pw.println(" ago");
11815                }
11816            }
11817        }
11818
11819        if (mBadProcesses.getMap().size() > 0) {
11820            boolean printed = false;
11821            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11822            final int NP = pmap.size();
11823            for (int ip=0; ip<NP; ip++) {
11824                String pname = pmap.keyAt(ip);
11825                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11826                final int N = uids.size();
11827                for (int i=0; i<N; i++) {
11828                    int puid = uids.keyAt(i);
11829                    ProcessRecord r = mProcessNames.get(pname, puid);
11830                    if (dumpPackage != null && (r == null
11831                            || !r.pkgList.containsKey(dumpPackage))) {
11832                        continue;
11833                    }
11834                    if (!printed) {
11835                        if (needSep) pw.println();
11836                        needSep = true;
11837                        pw.println("  Bad processes:");
11838                        printedAnything = true;
11839                    }
11840                    BadProcessInfo info = uids.valueAt(i);
11841                    pw.print("    Bad process "); pw.print(pname);
11842                            pw.print(" uid "); pw.print(puid);
11843                            pw.print(": crashed at time "); pw.println(info.time);
11844                    if (info.shortMsg != null) {
11845                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11846                    }
11847                    if (info.longMsg != null) {
11848                        pw.print("      Long msg: "); pw.println(info.longMsg);
11849                    }
11850                    if (info.stack != null) {
11851                        pw.println("      Stack:");
11852                        int lastPos = 0;
11853                        for (int pos=0; pos<info.stack.length(); pos++) {
11854                            if (info.stack.charAt(pos) == '\n') {
11855                                pw.print("        ");
11856                                pw.write(info.stack, lastPos, pos-lastPos);
11857                                pw.println();
11858                                lastPos = pos+1;
11859                            }
11860                        }
11861                        if (lastPos < info.stack.length()) {
11862                            pw.print("        ");
11863                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11864                            pw.println();
11865                        }
11866                    }
11867                }
11868            }
11869        }
11870
11871        if (dumpPackage == null) {
11872            pw.println();
11873            needSep = false;
11874            pw.println("  mStartedUsers:");
11875            for (int i=0; i<mStartedUsers.size(); i++) {
11876                UserStartedState uss = mStartedUsers.valueAt(i);
11877                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11878                        pw.print(": "); uss.dump("", pw);
11879            }
11880            pw.print("  mStartedUserArray: [");
11881            for (int i=0; i<mStartedUserArray.length; i++) {
11882                if (i > 0) pw.print(", ");
11883                pw.print(mStartedUserArray[i]);
11884            }
11885            pw.println("]");
11886            pw.print("  mUserLru: [");
11887            for (int i=0; i<mUserLru.size(); i++) {
11888                if (i > 0) pw.print(", ");
11889                pw.print(mUserLru.get(i));
11890            }
11891            pw.println("]");
11892            if (dumpAll) {
11893                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11894            }
11895            synchronized (mUserProfileGroupIdsSelfLocked) {
11896                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11897                    pw.println("  mUserProfileGroupIds:");
11898                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11899                        pw.print("    User #");
11900                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11901                        pw.print(" -> profile #");
11902                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11903                    }
11904                }
11905            }
11906        }
11907        if (mHomeProcess != null && (dumpPackage == null
11908                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11909            if (needSep) {
11910                pw.println();
11911                needSep = false;
11912            }
11913            pw.println("  mHomeProcess: " + mHomeProcess);
11914        }
11915        if (mPreviousProcess != null && (dumpPackage == null
11916                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11917            if (needSep) {
11918                pw.println();
11919                needSep = false;
11920            }
11921            pw.println("  mPreviousProcess: " + mPreviousProcess);
11922        }
11923        if (dumpAll) {
11924            StringBuilder sb = new StringBuilder(128);
11925            sb.append("  mPreviousProcessVisibleTime: ");
11926            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11927            pw.println(sb);
11928        }
11929        if (mHeavyWeightProcess != null && (dumpPackage == null
11930                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11931            if (needSep) {
11932                pw.println();
11933                needSep = false;
11934            }
11935            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11936        }
11937        if (dumpPackage == null) {
11938            pw.println("  mConfiguration: " + mConfiguration);
11939        }
11940        if (dumpAll) {
11941            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11942            if (mCompatModePackages.getPackages().size() > 0) {
11943                boolean printed = false;
11944                for (Map.Entry<String, Integer> entry
11945                        : mCompatModePackages.getPackages().entrySet()) {
11946                    String pkg = entry.getKey();
11947                    int mode = entry.getValue();
11948                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11949                        continue;
11950                    }
11951                    if (!printed) {
11952                        pw.println("  mScreenCompatPackages:");
11953                        printed = true;
11954                    }
11955                    pw.print("    "); pw.print(pkg); pw.print(": ");
11956                            pw.print(mode); pw.println();
11957                }
11958            }
11959        }
11960        if (dumpPackage == null) {
11961            if (mSleeping || mWentToSleep || mLockScreenShown) {
11962                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11963                        + " mLockScreenShown " + mLockScreenShown);
11964            }
11965            if (mShuttingDown || mRunningVoice) {
11966                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11967            }
11968        }
11969        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11970                || mOrigWaitForDebugger) {
11971            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11972                    || dumpPackage.equals(mOrigDebugApp)) {
11973                if (needSep) {
11974                    pw.println();
11975                    needSep = false;
11976                }
11977                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11978                        + " mDebugTransient=" + mDebugTransient
11979                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11980            }
11981        }
11982        if (mOpenGlTraceApp != null) {
11983            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11984                if (needSep) {
11985                    pw.println();
11986                    needSep = false;
11987                }
11988                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11989            }
11990        }
11991        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11992                || mProfileFd != null) {
11993            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11994                if (needSep) {
11995                    pw.println();
11996                    needSep = false;
11997                }
11998                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11999                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12000                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12001                        + mAutoStopProfiler);
12002            }
12003        }
12004        if (dumpPackage == null) {
12005            if (mAlwaysFinishActivities || mController != null) {
12006                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12007                        + " mController=" + mController);
12008            }
12009            if (dumpAll) {
12010                pw.println("  Total persistent processes: " + numPers);
12011                pw.println("  mProcessesReady=" + mProcessesReady
12012                        + " mSystemReady=" + mSystemReady);
12013                pw.println("  mBooting=" + mBooting
12014                        + " mBooted=" + mBooted
12015                        + " mFactoryTest=" + mFactoryTest);
12016                pw.print("  mLastPowerCheckRealtime=");
12017                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12018                        pw.println("");
12019                pw.print("  mLastPowerCheckUptime=");
12020                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12021                        pw.println("");
12022                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12023                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12024                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12025                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12026                        + " (" + mLruProcesses.size() + " total)"
12027                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12028                        + " mNumServiceProcs=" + mNumServiceProcs
12029                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12030                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12031                        + " mLastMemoryLevel" + mLastMemoryLevel
12032                        + " mLastNumProcesses" + mLastNumProcesses);
12033                long now = SystemClock.uptimeMillis();
12034                pw.print("  mLastIdleTime=");
12035                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12036                        pw.print(" mLowRamSinceLastIdle=");
12037                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12038                        pw.println();
12039            }
12040        }
12041
12042        if (!printedAnything) {
12043            pw.println("  (nothing)");
12044        }
12045    }
12046
12047    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12048            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12049        if (mProcessesToGc.size() > 0) {
12050            boolean printed = false;
12051            long now = SystemClock.uptimeMillis();
12052            for (int i=0; i<mProcessesToGc.size(); i++) {
12053                ProcessRecord proc = mProcessesToGc.get(i);
12054                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12055                    continue;
12056                }
12057                if (!printed) {
12058                    if (needSep) pw.println();
12059                    needSep = true;
12060                    pw.println("  Processes that are waiting to GC:");
12061                    printed = true;
12062                }
12063                pw.print("    Process "); pw.println(proc);
12064                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12065                        pw.print(", last gced=");
12066                        pw.print(now-proc.lastRequestedGc);
12067                        pw.print(" ms ago, last lowMem=");
12068                        pw.print(now-proc.lastLowMemory);
12069                        pw.println(" ms ago");
12070
12071            }
12072        }
12073        return needSep;
12074    }
12075
12076    void printOomLevel(PrintWriter pw, String name, int adj) {
12077        pw.print("    ");
12078        if (adj >= 0) {
12079            pw.print(' ');
12080            if (adj < 10) pw.print(' ');
12081        } else {
12082            if (adj > -10) pw.print(' ');
12083        }
12084        pw.print(adj);
12085        pw.print(": ");
12086        pw.print(name);
12087        pw.print(" (");
12088        pw.print(mProcessList.getMemLevel(adj)/1024);
12089        pw.println(" kB)");
12090    }
12091
12092    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12093            int opti, boolean dumpAll) {
12094        boolean needSep = false;
12095
12096        if (mLruProcesses.size() > 0) {
12097            if (needSep) pw.println();
12098            needSep = true;
12099            pw.println("  OOM levels:");
12100            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12101            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12102            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12103            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12104            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12105            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12106            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12107            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12108            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12109            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12110            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12111            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12112            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12113
12114            if (needSep) pw.println();
12115            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12116                    pw.print(" total, non-act at ");
12117                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12118                    pw.print(", non-svc at ");
12119                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12120                    pw.println("):");
12121            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12122            needSep = true;
12123        }
12124
12125        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12126
12127        pw.println();
12128        pw.println("  mHomeProcess: " + mHomeProcess);
12129        pw.println("  mPreviousProcess: " + mPreviousProcess);
12130        if (mHeavyWeightProcess != null) {
12131            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12132        }
12133
12134        return true;
12135    }
12136
12137    /**
12138     * There are three ways to call this:
12139     *  - no provider specified: dump all the providers
12140     *  - a flattened component name that matched an existing provider was specified as the
12141     *    first arg: dump that one provider
12142     *  - the first arg isn't the flattened component name of an existing provider:
12143     *    dump all providers whose component contains the first arg as a substring
12144     */
12145    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12146            int opti, boolean dumpAll) {
12147        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12148    }
12149
12150    static class ItemMatcher {
12151        ArrayList<ComponentName> components;
12152        ArrayList<String> strings;
12153        ArrayList<Integer> objects;
12154        boolean all;
12155
12156        ItemMatcher() {
12157            all = true;
12158        }
12159
12160        void build(String name) {
12161            ComponentName componentName = ComponentName.unflattenFromString(name);
12162            if (componentName != null) {
12163                if (components == null) {
12164                    components = new ArrayList<ComponentName>();
12165                }
12166                components.add(componentName);
12167                all = false;
12168            } else {
12169                int objectId = 0;
12170                // Not a '/' separated full component name; maybe an object ID?
12171                try {
12172                    objectId = Integer.parseInt(name, 16);
12173                    if (objects == null) {
12174                        objects = new ArrayList<Integer>();
12175                    }
12176                    objects.add(objectId);
12177                    all = false;
12178                } catch (RuntimeException e) {
12179                    // Not an integer; just do string match.
12180                    if (strings == null) {
12181                        strings = new ArrayList<String>();
12182                    }
12183                    strings.add(name);
12184                    all = false;
12185                }
12186            }
12187        }
12188
12189        int build(String[] args, int opti) {
12190            for (; opti<args.length; opti++) {
12191                String name = args[opti];
12192                if ("--".equals(name)) {
12193                    return opti+1;
12194                }
12195                build(name);
12196            }
12197            return opti;
12198        }
12199
12200        boolean match(Object object, ComponentName comp) {
12201            if (all) {
12202                return true;
12203            }
12204            if (components != null) {
12205                for (int i=0; i<components.size(); i++) {
12206                    if (components.get(i).equals(comp)) {
12207                        return true;
12208                    }
12209                }
12210            }
12211            if (objects != null) {
12212                for (int i=0; i<objects.size(); i++) {
12213                    if (System.identityHashCode(object) == objects.get(i)) {
12214                        return true;
12215                    }
12216                }
12217            }
12218            if (strings != null) {
12219                String flat = comp.flattenToString();
12220                for (int i=0; i<strings.size(); i++) {
12221                    if (flat.contains(strings.get(i))) {
12222                        return true;
12223                    }
12224                }
12225            }
12226            return false;
12227        }
12228    }
12229
12230    /**
12231     * There are three things that cmd can be:
12232     *  - a flattened component name that matches an existing activity
12233     *  - the cmd arg isn't the flattened component name of an existing activity:
12234     *    dump all activity whose component contains the cmd as a substring
12235     *  - A hex number of the ActivityRecord object instance.
12236     */
12237    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12238            int opti, boolean dumpAll) {
12239        ArrayList<ActivityRecord> activities;
12240
12241        synchronized (this) {
12242            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12243        }
12244
12245        if (activities.size() <= 0) {
12246            return false;
12247        }
12248
12249        String[] newArgs = new String[args.length - opti];
12250        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12251
12252        TaskRecord lastTask = null;
12253        boolean needSep = false;
12254        for (int i=activities.size()-1; i>=0; i--) {
12255            ActivityRecord r = activities.get(i);
12256            if (needSep) {
12257                pw.println();
12258            }
12259            needSep = true;
12260            synchronized (this) {
12261                if (lastTask != r.task) {
12262                    lastTask = r.task;
12263                    pw.print("TASK "); pw.print(lastTask.affinity);
12264                            pw.print(" id="); pw.println(lastTask.taskId);
12265                    if (dumpAll) {
12266                        lastTask.dump(pw, "  ");
12267                    }
12268                }
12269            }
12270            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12271        }
12272        return true;
12273    }
12274
12275    /**
12276     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12277     * there is a thread associated with the activity.
12278     */
12279    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12280            final ActivityRecord r, String[] args, boolean dumpAll) {
12281        String innerPrefix = prefix + "  ";
12282        synchronized (this) {
12283            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12284                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12285                    pw.print(" pid=");
12286                    if (r.app != null) pw.println(r.app.pid);
12287                    else pw.println("(not running)");
12288            if (dumpAll) {
12289                r.dump(pw, innerPrefix);
12290            }
12291        }
12292        if (r.app != null && r.app.thread != null) {
12293            // flush anything that is already in the PrintWriter since the thread is going
12294            // to write to the file descriptor directly
12295            pw.flush();
12296            try {
12297                TransferPipe tp = new TransferPipe();
12298                try {
12299                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12300                            r.appToken, innerPrefix, args);
12301                    tp.go(fd);
12302                } finally {
12303                    tp.kill();
12304                }
12305            } catch (IOException e) {
12306                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12307            } catch (RemoteException e) {
12308                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12309            }
12310        }
12311    }
12312
12313    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12314            int opti, boolean dumpAll, String dumpPackage) {
12315        boolean needSep = false;
12316        boolean onlyHistory = false;
12317        boolean printedAnything = false;
12318
12319        if ("history".equals(dumpPackage)) {
12320            if (opti < args.length && "-s".equals(args[opti])) {
12321                dumpAll = false;
12322            }
12323            onlyHistory = true;
12324            dumpPackage = null;
12325        }
12326
12327        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12328        if (!onlyHistory && dumpAll) {
12329            if (mRegisteredReceivers.size() > 0) {
12330                boolean printed = false;
12331                Iterator it = mRegisteredReceivers.values().iterator();
12332                while (it.hasNext()) {
12333                    ReceiverList r = (ReceiverList)it.next();
12334                    if (dumpPackage != null && (r.app == null ||
12335                            !dumpPackage.equals(r.app.info.packageName))) {
12336                        continue;
12337                    }
12338                    if (!printed) {
12339                        pw.println("  Registered Receivers:");
12340                        needSep = true;
12341                        printed = true;
12342                        printedAnything = true;
12343                    }
12344                    pw.print("  * "); pw.println(r);
12345                    r.dump(pw, "    ");
12346                }
12347            }
12348
12349            if (mReceiverResolver.dump(pw, needSep ?
12350                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12351                    "    ", dumpPackage, false)) {
12352                needSep = true;
12353                printedAnything = true;
12354            }
12355        }
12356
12357        for (BroadcastQueue q : mBroadcastQueues) {
12358            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12359            printedAnything |= needSep;
12360        }
12361
12362        needSep = true;
12363
12364        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12365            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12366                if (needSep) {
12367                    pw.println();
12368                }
12369                needSep = true;
12370                printedAnything = true;
12371                pw.print("  Sticky broadcasts for user ");
12372                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12373                StringBuilder sb = new StringBuilder(128);
12374                for (Map.Entry<String, ArrayList<Intent>> ent
12375                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12376                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12377                    if (dumpAll) {
12378                        pw.println(":");
12379                        ArrayList<Intent> intents = ent.getValue();
12380                        final int N = intents.size();
12381                        for (int i=0; i<N; i++) {
12382                            sb.setLength(0);
12383                            sb.append("    Intent: ");
12384                            intents.get(i).toShortString(sb, false, true, false, false);
12385                            pw.println(sb.toString());
12386                            Bundle bundle = intents.get(i).getExtras();
12387                            if (bundle != null) {
12388                                pw.print("      ");
12389                                pw.println(bundle.toString());
12390                            }
12391                        }
12392                    } else {
12393                        pw.println("");
12394                    }
12395                }
12396            }
12397        }
12398
12399        if (!onlyHistory && dumpAll) {
12400            pw.println();
12401            for (BroadcastQueue queue : mBroadcastQueues) {
12402                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12403                        + queue.mBroadcastsScheduled);
12404            }
12405            pw.println("  mHandler:");
12406            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12407            needSep = true;
12408            printedAnything = true;
12409        }
12410
12411        if (!printedAnything) {
12412            pw.println("  (nothing)");
12413        }
12414    }
12415
12416    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12417            int opti, boolean dumpAll, String dumpPackage) {
12418        boolean needSep;
12419        boolean printedAnything = false;
12420
12421        ItemMatcher matcher = new ItemMatcher();
12422        matcher.build(args, opti);
12423
12424        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12425
12426        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12427        printedAnything |= needSep;
12428
12429        if (mLaunchingProviders.size() > 0) {
12430            boolean printed = false;
12431            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12432                ContentProviderRecord r = mLaunchingProviders.get(i);
12433                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12434                    continue;
12435                }
12436                if (!printed) {
12437                    if (needSep) pw.println();
12438                    needSep = true;
12439                    pw.println("  Launching content providers:");
12440                    printed = true;
12441                    printedAnything = true;
12442                }
12443                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12444                        pw.println(r);
12445            }
12446        }
12447
12448        if (mGrantedUriPermissions.size() > 0) {
12449            boolean printed = false;
12450            int dumpUid = -2;
12451            if (dumpPackage != null) {
12452                try {
12453                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12454                } catch (NameNotFoundException e) {
12455                    dumpUid = -1;
12456                }
12457            }
12458            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12459                int uid = mGrantedUriPermissions.keyAt(i);
12460                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12461                    continue;
12462                }
12463                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12464                if (!printed) {
12465                    if (needSep) pw.println();
12466                    needSep = true;
12467                    pw.println("  Granted Uri Permissions:");
12468                    printed = true;
12469                    printedAnything = true;
12470                }
12471                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12472                for (UriPermission perm : perms.values()) {
12473                    pw.print("    "); pw.println(perm);
12474                    if (dumpAll) {
12475                        perm.dump(pw, "      ");
12476                    }
12477                }
12478            }
12479        }
12480
12481        if (!printedAnything) {
12482            pw.println("  (nothing)");
12483        }
12484    }
12485
12486    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12487            int opti, boolean dumpAll, String dumpPackage) {
12488        boolean printed = false;
12489
12490        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12491
12492        if (mIntentSenderRecords.size() > 0) {
12493            Iterator<WeakReference<PendingIntentRecord>> it
12494                    = mIntentSenderRecords.values().iterator();
12495            while (it.hasNext()) {
12496                WeakReference<PendingIntentRecord> ref = it.next();
12497                PendingIntentRecord rec = ref != null ? ref.get(): null;
12498                if (dumpPackage != null && (rec == null
12499                        || !dumpPackage.equals(rec.key.packageName))) {
12500                    continue;
12501                }
12502                printed = true;
12503                if (rec != null) {
12504                    pw.print("  * "); pw.println(rec);
12505                    if (dumpAll) {
12506                        rec.dump(pw, "    ");
12507                    }
12508                } else {
12509                    pw.print("  * "); pw.println(ref);
12510                }
12511            }
12512        }
12513
12514        if (!printed) {
12515            pw.println("  (nothing)");
12516        }
12517    }
12518
12519    private static final int dumpProcessList(PrintWriter pw,
12520            ActivityManagerService service, List list,
12521            String prefix, String normalLabel, String persistentLabel,
12522            String dumpPackage) {
12523        int numPers = 0;
12524        final int N = list.size()-1;
12525        for (int i=N; i>=0; i--) {
12526            ProcessRecord r = (ProcessRecord)list.get(i);
12527            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12528                continue;
12529            }
12530            pw.println(String.format("%s%s #%2d: %s",
12531                    prefix, (r.persistent ? persistentLabel : normalLabel),
12532                    i, r.toString()));
12533            if (r.persistent) {
12534                numPers++;
12535            }
12536        }
12537        return numPers;
12538    }
12539
12540    private static final boolean dumpProcessOomList(PrintWriter pw,
12541            ActivityManagerService service, List<ProcessRecord> origList,
12542            String prefix, String normalLabel, String persistentLabel,
12543            boolean inclDetails, String dumpPackage) {
12544
12545        ArrayList<Pair<ProcessRecord, Integer>> list
12546                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12547        for (int i=0; i<origList.size(); i++) {
12548            ProcessRecord r = origList.get(i);
12549            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12550                continue;
12551            }
12552            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12553        }
12554
12555        if (list.size() <= 0) {
12556            return false;
12557        }
12558
12559        Comparator<Pair<ProcessRecord, Integer>> comparator
12560                = new Comparator<Pair<ProcessRecord, Integer>>() {
12561            @Override
12562            public int compare(Pair<ProcessRecord, Integer> object1,
12563                    Pair<ProcessRecord, Integer> object2) {
12564                if (object1.first.setAdj != object2.first.setAdj) {
12565                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12566                }
12567                if (object1.second.intValue() != object2.second.intValue()) {
12568                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12569                }
12570                return 0;
12571            }
12572        };
12573
12574        Collections.sort(list, comparator);
12575
12576        final long curRealtime = SystemClock.elapsedRealtime();
12577        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12578        final long curUptime = SystemClock.uptimeMillis();
12579        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12580
12581        for (int i=list.size()-1; i>=0; i--) {
12582            ProcessRecord r = list.get(i).first;
12583            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12584            char schedGroup;
12585            switch (r.setSchedGroup) {
12586                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12587                    schedGroup = 'B';
12588                    break;
12589                case Process.THREAD_GROUP_DEFAULT:
12590                    schedGroup = 'F';
12591                    break;
12592                default:
12593                    schedGroup = '?';
12594                    break;
12595            }
12596            char foreground;
12597            if (r.foregroundActivities) {
12598                foreground = 'A';
12599            } else if (r.foregroundServices) {
12600                foreground = 'S';
12601            } else {
12602                foreground = ' ';
12603            }
12604            String procState = ProcessList.makeProcStateString(r.curProcState);
12605            pw.print(prefix);
12606            pw.print(r.persistent ? persistentLabel : normalLabel);
12607            pw.print(" #");
12608            int num = (origList.size()-1)-list.get(i).second;
12609            if (num < 10) pw.print(' ');
12610            pw.print(num);
12611            pw.print(": ");
12612            pw.print(oomAdj);
12613            pw.print(' ');
12614            pw.print(schedGroup);
12615            pw.print('/');
12616            pw.print(foreground);
12617            pw.print('/');
12618            pw.print(procState);
12619            pw.print(" trm:");
12620            if (r.trimMemoryLevel < 10) pw.print(' ');
12621            pw.print(r.trimMemoryLevel);
12622            pw.print(' ');
12623            pw.print(r.toShortString());
12624            pw.print(" (");
12625            pw.print(r.adjType);
12626            pw.println(')');
12627            if (r.adjSource != null || r.adjTarget != null) {
12628                pw.print(prefix);
12629                pw.print("    ");
12630                if (r.adjTarget instanceof ComponentName) {
12631                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12632                } else if (r.adjTarget != null) {
12633                    pw.print(r.adjTarget.toString());
12634                } else {
12635                    pw.print("{null}");
12636                }
12637                pw.print("<=");
12638                if (r.adjSource instanceof ProcessRecord) {
12639                    pw.print("Proc{");
12640                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12641                    pw.println("}");
12642                } else if (r.adjSource != null) {
12643                    pw.println(r.adjSource.toString());
12644                } else {
12645                    pw.println("{null}");
12646                }
12647            }
12648            if (inclDetails) {
12649                pw.print(prefix);
12650                pw.print("    ");
12651                pw.print("oom: max="); pw.print(r.maxAdj);
12652                pw.print(" curRaw="); pw.print(r.curRawAdj);
12653                pw.print(" setRaw="); pw.print(r.setRawAdj);
12654                pw.print(" cur="); pw.print(r.curAdj);
12655                pw.print(" set="); pw.println(r.setAdj);
12656                pw.print(prefix);
12657                pw.print("    ");
12658                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12659                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12660                pw.print(" lastPss="); pw.print(r.lastPss);
12661                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12662                pw.print(prefix);
12663                pw.print("    ");
12664                pw.print("cached="); pw.print(r.cached);
12665                pw.print(" empty="); pw.print(r.empty);
12666                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12667
12668                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12669                    if (r.lastWakeTime != 0) {
12670                        long wtime;
12671                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12672                        synchronized (stats) {
12673                            wtime = stats.getProcessWakeTime(r.info.uid,
12674                                    r.pid, curRealtime);
12675                        }
12676                        long timeUsed = wtime - r.lastWakeTime;
12677                        pw.print(prefix);
12678                        pw.print("    ");
12679                        pw.print("keep awake over ");
12680                        TimeUtils.formatDuration(realtimeSince, pw);
12681                        pw.print(" used ");
12682                        TimeUtils.formatDuration(timeUsed, pw);
12683                        pw.print(" (");
12684                        pw.print((timeUsed*100)/realtimeSince);
12685                        pw.println("%)");
12686                    }
12687                    if (r.lastCpuTime != 0) {
12688                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12689                        pw.print(prefix);
12690                        pw.print("    ");
12691                        pw.print("run cpu over ");
12692                        TimeUtils.formatDuration(uptimeSince, pw);
12693                        pw.print(" used ");
12694                        TimeUtils.formatDuration(timeUsed, pw);
12695                        pw.print(" (");
12696                        pw.print((timeUsed*100)/uptimeSince);
12697                        pw.println("%)");
12698                    }
12699                }
12700            }
12701        }
12702        return true;
12703    }
12704
12705    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12706        ArrayList<ProcessRecord> procs;
12707        synchronized (this) {
12708            if (args != null && args.length > start
12709                    && args[start].charAt(0) != '-') {
12710                procs = new ArrayList<ProcessRecord>();
12711                int pid = -1;
12712                try {
12713                    pid = Integer.parseInt(args[start]);
12714                } catch (NumberFormatException e) {
12715                }
12716                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12717                    ProcessRecord proc = mLruProcesses.get(i);
12718                    if (proc.pid == pid) {
12719                        procs.add(proc);
12720                    } else if (proc.processName.equals(args[start])) {
12721                        procs.add(proc);
12722                    }
12723                }
12724                if (procs.size() <= 0) {
12725                    return null;
12726                }
12727            } else {
12728                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12729            }
12730        }
12731        return procs;
12732    }
12733
12734    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12735            PrintWriter pw, String[] args) {
12736        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12737        if (procs == null) {
12738            pw.println("No process found for: " + args[0]);
12739            return;
12740        }
12741
12742        long uptime = SystemClock.uptimeMillis();
12743        long realtime = SystemClock.elapsedRealtime();
12744        pw.println("Applications Graphics Acceleration Info:");
12745        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12746
12747        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12748            ProcessRecord r = procs.get(i);
12749            if (r.thread != null) {
12750                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12751                pw.flush();
12752                try {
12753                    TransferPipe tp = new TransferPipe();
12754                    try {
12755                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12756                        tp.go(fd);
12757                    } finally {
12758                        tp.kill();
12759                    }
12760                } catch (IOException e) {
12761                    pw.println("Failure while dumping the app: " + r);
12762                    pw.flush();
12763                } catch (RemoteException e) {
12764                    pw.println("Got a RemoteException while dumping the app " + r);
12765                    pw.flush();
12766                }
12767            }
12768        }
12769    }
12770
12771    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12772        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12773        if (procs == null) {
12774            pw.println("No process found for: " + args[0]);
12775            return;
12776        }
12777
12778        pw.println("Applications Database Info:");
12779
12780        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12781            ProcessRecord r = procs.get(i);
12782            if (r.thread != null) {
12783                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12784                pw.flush();
12785                try {
12786                    TransferPipe tp = new TransferPipe();
12787                    try {
12788                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12789                        tp.go(fd);
12790                    } finally {
12791                        tp.kill();
12792                    }
12793                } catch (IOException e) {
12794                    pw.println("Failure while dumping the app: " + r);
12795                    pw.flush();
12796                } catch (RemoteException e) {
12797                    pw.println("Got a RemoteException while dumping the app " + r);
12798                    pw.flush();
12799                }
12800            }
12801        }
12802    }
12803
12804    final static class MemItem {
12805        final boolean isProc;
12806        final String label;
12807        final String shortLabel;
12808        final long pss;
12809        final int id;
12810        final boolean hasActivities;
12811        ArrayList<MemItem> subitems;
12812
12813        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12814                boolean _hasActivities) {
12815            isProc = true;
12816            label = _label;
12817            shortLabel = _shortLabel;
12818            pss = _pss;
12819            id = _id;
12820            hasActivities = _hasActivities;
12821        }
12822
12823        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12824            isProc = false;
12825            label = _label;
12826            shortLabel = _shortLabel;
12827            pss = _pss;
12828            id = _id;
12829            hasActivities = false;
12830        }
12831    }
12832
12833    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12834            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12835        if (sort && !isCompact) {
12836            Collections.sort(items, new Comparator<MemItem>() {
12837                @Override
12838                public int compare(MemItem lhs, MemItem rhs) {
12839                    if (lhs.pss < rhs.pss) {
12840                        return 1;
12841                    } else if (lhs.pss > rhs.pss) {
12842                        return -1;
12843                    }
12844                    return 0;
12845                }
12846            });
12847        }
12848
12849        for (int i=0; i<items.size(); i++) {
12850            MemItem mi = items.get(i);
12851            if (!isCompact) {
12852                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12853            } else if (mi.isProc) {
12854                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12855                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12856                pw.println(mi.hasActivities ? ",a" : ",e");
12857            } else {
12858                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12859                pw.println(mi.pss);
12860            }
12861            if (mi.subitems != null) {
12862                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12863                        true, isCompact);
12864            }
12865        }
12866    }
12867
12868    // These are in KB.
12869    static final long[] DUMP_MEM_BUCKETS = new long[] {
12870        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12871        120*1024, 160*1024, 200*1024,
12872        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12873        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12874    };
12875
12876    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12877            boolean stackLike) {
12878        int start = label.lastIndexOf('.');
12879        if (start >= 0) start++;
12880        else start = 0;
12881        int end = label.length();
12882        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12883            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12884                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12885                out.append(bucket);
12886                out.append(stackLike ? "MB." : "MB ");
12887                out.append(label, start, end);
12888                return;
12889            }
12890        }
12891        out.append(memKB/1024);
12892        out.append(stackLike ? "MB." : "MB ");
12893        out.append(label, start, end);
12894    }
12895
12896    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12897            ProcessList.NATIVE_ADJ,
12898            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12899            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12900            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12901            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12902            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12903    };
12904    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12905            "Native",
12906            "System", "Persistent", "Foreground",
12907            "Visible", "Perceptible",
12908            "Heavy Weight", "Backup",
12909            "A Services", "Home",
12910            "Previous", "B Services", "Cached"
12911    };
12912    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12913            "native",
12914            "sys", "pers", "fore",
12915            "vis", "percept",
12916            "heavy", "backup",
12917            "servicea", "home",
12918            "prev", "serviceb", "cached"
12919    };
12920
12921    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12922            long realtime, boolean isCheckinRequest, boolean isCompact) {
12923        if (isCheckinRequest || isCompact) {
12924            // short checkin version
12925            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12926        } else {
12927            pw.println("Applications Memory Usage (kB):");
12928            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12929        }
12930    }
12931
12932    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12933            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12934        boolean dumpDetails = false;
12935        boolean dumpFullDetails = false;
12936        boolean dumpDalvik = false;
12937        boolean oomOnly = false;
12938        boolean isCompact = false;
12939        boolean localOnly = false;
12940
12941        int opti = 0;
12942        while (opti < args.length) {
12943            String opt = args[opti];
12944            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12945                break;
12946            }
12947            opti++;
12948            if ("-a".equals(opt)) {
12949                dumpDetails = true;
12950                dumpFullDetails = true;
12951                dumpDalvik = true;
12952            } else if ("-d".equals(opt)) {
12953                dumpDalvik = true;
12954            } else if ("-c".equals(opt)) {
12955                isCompact = true;
12956            } else if ("--oom".equals(opt)) {
12957                oomOnly = true;
12958            } else if ("--local".equals(opt)) {
12959                localOnly = true;
12960            } else if ("-h".equals(opt)) {
12961                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12962                pw.println("  -a: include all available information for each process.");
12963                pw.println("  -d: include dalvik details when dumping process details.");
12964                pw.println("  -c: dump in a compact machine-parseable representation.");
12965                pw.println("  --oom: only show processes organized by oom adj.");
12966                pw.println("  --local: only collect details locally, don't call process.");
12967                pw.println("If [process] is specified it can be the name or ");
12968                pw.println("pid of a specific process to dump.");
12969                return;
12970            } else {
12971                pw.println("Unknown argument: " + opt + "; use -h for help");
12972            }
12973        }
12974
12975        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12976        long uptime = SystemClock.uptimeMillis();
12977        long realtime = SystemClock.elapsedRealtime();
12978        final long[] tmpLong = new long[1];
12979
12980        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12981        if (procs == null) {
12982            // No Java processes.  Maybe they want to print a native process.
12983            if (args != null && args.length > opti
12984                    && args[opti].charAt(0) != '-') {
12985                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12986                        = new ArrayList<ProcessCpuTracker.Stats>();
12987                updateCpuStatsNow();
12988                int findPid = -1;
12989                try {
12990                    findPid = Integer.parseInt(args[opti]);
12991                } catch (NumberFormatException e) {
12992                }
12993                synchronized (mProcessCpuThread) {
12994                    final int N = mProcessCpuTracker.countStats();
12995                    for (int i=0; i<N; i++) {
12996                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12997                        if (st.pid == findPid || (st.baseName != null
12998                                && st.baseName.equals(args[opti]))) {
12999                            nativeProcs.add(st);
13000                        }
13001                    }
13002                }
13003                if (nativeProcs.size() > 0) {
13004                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13005                            isCompact);
13006                    Debug.MemoryInfo mi = null;
13007                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13008                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13009                        final int pid = r.pid;
13010                        if (!isCheckinRequest && dumpDetails) {
13011                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13012                        }
13013                        if (mi == null) {
13014                            mi = new Debug.MemoryInfo();
13015                        }
13016                        if (dumpDetails || (!brief && !oomOnly)) {
13017                            Debug.getMemoryInfo(pid, mi);
13018                        } else {
13019                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13020                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13021                        }
13022                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13023                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13024                        if (isCheckinRequest) {
13025                            pw.println();
13026                        }
13027                    }
13028                    return;
13029                }
13030            }
13031            pw.println("No process found for: " + args[opti]);
13032            return;
13033        }
13034
13035        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13036            dumpDetails = true;
13037        }
13038
13039        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13040
13041        String[] innerArgs = new String[args.length-opti];
13042        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13043
13044        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13045        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13046        long nativePss=0, dalvikPss=0, otherPss=0;
13047        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13048
13049        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13050        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13051                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13052
13053        long totalPss = 0;
13054        long cachedPss = 0;
13055
13056        Debug.MemoryInfo mi = null;
13057        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13058            final ProcessRecord r = procs.get(i);
13059            final IApplicationThread thread;
13060            final int pid;
13061            final int oomAdj;
13062            final boolean hasActivities;
13063            synchronized (this) {
13064                thread = r.thread;
13065                pid = r.pid;
13066                oomAdj = r.getSetAdjWithServices();
13067                hasActivities = r.activities.size() > 0;
13068            }
13069            if (thread != null) {
13070                if (!isCheckinRequest && dumpDetails) {
13071                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13072                }
13073                if (mi == null) {
13074                    mi = new Debug.MemoryInfo();
13075                }
13076                if (dumpDetails || (!brief && !oomOnly)) {
13077                    Debug.getMemoryInfo(pid, mi);
13078                } else {
13079                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13080                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13081                }
13082                if (dumpDetails) {
13083                    if (localOnly) {
13084                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13085                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13086                        if (isCheckinRequest) {
13087                            pw.println();
13088                        }
13089                    } else {
13090                        try {
13091                            pw.flush();
13092                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13093                                    dumpDalvik, innerArgs);
13094                        } catch (RemoteException e) {
13095                            if (!isCheckinRequest) {
13096                                pw.println("Got RemoteException!");
13097                                pw.flush();
13098                            }
13099                        }
13100                    }
13101                }
13102
13103                final long myTotalPss = mi.getTotalPss();
13104                final long myTotalUss = mi.getTotalUss();
13105
13106                synchronized (this) {
13107                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13108                        // Record this for posterity if the process has been stable.
13109                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13110                    }
13111                }
13112
13113                if (!isCheckinRequest && mi != null) {
13114                    totalPss += myTotalPss;
13115                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13116                            (hasActivities ? " / activities)" : ")"),
13117                            r.processName, myTotalPss, pid, hasActivities);
13118                    procMems.add(pssItem);
13119                    procMemsMap.put(pid, pssItem);
13120
13121                    nativePss += mi.nativePss;
13122                    dalvikPss += mi.dalvikPss;
13123                    otherPss += mi.otherPss;
13124                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13125                        long mem = mi.getOtherPss(j);
13126                        miscPss[j] += mem;
13127                        otherPss -= mem;
13128                    }
13129
13130                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13131                        cachedPss += myTotalPss;
13132                    }
13133
13134                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13135                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13136                                || oomIndex == (oomPss.length-1)) {
13137                            oomPss[oomIndex] += myTotalPss;
13138                            if (oomProcs[oomIndex] == null) {
13139                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13140                            }
13141                            oomProcs[oomIndex].add(pssItem);
13142                            break;
13143                        }
13144                    }
13145                }
13146            }
13147        }
13148
13149        long nativeProcTotalPss = 0;
13150
13151        if (!isCheckinRequest && procs.size() > 1) {
13152            // If we are showing aggregations, also look for native processes to
13153            // include so that our aggregations are more accurate.
13154            updateCpuStatsNow();
13155            synchronized (mProcessCpuThread) {
13156                final int N = mProcessCpuTracker.countStats();
13157                for (int i=0; i<N; i++) {
13158                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13159                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13160                        if (mi == null) {
13161                            mi = new Debug.MemoryInfo();
13162                        }
13163                        if (!brief && !oomOnly) {
13164                            Debug.getMemoryInfo(st.pid, mi);
13165                        } else {
13166                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13167                            mi.nativePrivateDirty = (int)tmpLong[0];
13168                        }
13169
13170                        final long myTotalPss = mi.getTotalPss();
13171                        totalPss += myTotalPss;
13172                        nativeProcTotalPss += myTotalPss;
13173
13174                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13175                                st.name, myTotalPss, st.pid, false);
13176                        procMems.add(pssItem);
13177
13178                        nativePss += mi.nativePss;
13179                        dalvikPss += mi.dalvikPss;
13180                        otherPss += mi.otherPss;
13181                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13182                            long mem = mi.getOtherPss(j);
13183                            miscPss[j] += mem;
13184                            otherPss -= mem;
13185                        }
13186                        oomPss[0] += myTotalPss;
13187                        if (oomProcs[0] == null) {
13188                            oomProcs[0] = new ArrayList<MemItem>();
13189                        }
13190                        oomProcs[0].add(pssItem);
13191                    }
13192                }
13193            }
13194
13195            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13196
13197            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13198            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13199            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13200            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13201                String label = Debug.MemoryInfo.getOtherLabel(j);
13202                catMems.add(new MemItem(label, label, miscPss[j], j));
13203            }
13204
13205            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13206            for (int j=0; j<oomPss.length; j++) {
13207                if (oomPss[j] != 0) {
13208                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13209                            : DUMP_MEM_OOM_LABEL[j];
13210                    MemItem item = new MemItem(label, label, oomPss[j],
13211                            DUMP_MEM_OOM_ADJ[j]);
13212                    item.subitems = oomProcs[j];
13213                    oomMems.add(item);
13214                }
13215            }
13216
13217            if (!brief && !oomOnly && !isCompact) {
13218                pw.println();
13219                pw.println("Total PSS by process:");
13220                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13221                pw.println();
13222            }
13223            if (!isCompact) {
13224                pw.println("Total PSS by OOM adjustment:");
13225            }
13226            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13227            if (!brief && !oomOnly) {
13228                PrintWriter out = categoryPw != null ? categoryPw : pw;
13229                if (!isCompact) {
13230                    out.println();
13231                    out.println("Total PSS by category:");
13232                }
13233                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13234            }
13235            if (!isCompact) {
13236                pw.println();
13237            }
13238            MemInfoReader memInfo = new MemInfoReader();
13239            memInfo.readMemInfo();
13240            if (nativeProcTotalPss > 0) {
13241                synchronized (this) {
13242                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13243                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13244                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13245                            nativeProcTotalPss);
13246                }
13247            }
13248            if (!brief) {
13249                if (!isCompact) {
13250                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13251                    pw.print(" kB (status ");
13252                    switch (mLastMemoryLevel) {
13253                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13254                            pw.println("normal)");
13255                            break;
13256                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13257                            pw.println("moderate)");
13258                            break;
13259                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13260                            pw.println("low)");
13261                            break;
13262                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13263                            pw.println("critical)");
13264                            break;
13265                        default:
13266                            pw.print(mLastMemoryLevel);
13267                            pw.println(")");
13268                            break;
13269                    }
13270                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13271                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13272                            pw.print(cachedPss); pw.print(" cached pss + ");
13273                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13274                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13275                } else {
13276                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13277                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13278                            + memInfo.getFreeSizeKb()); pw.print(",");
13279                    pw.println(totalPss - cachedPss);
13280                }
13281            }
13282            if (!isCompact) {
13283                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13284                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13285                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13286                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13287                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13288                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13289                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13290                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13291                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13292                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13293                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13294            }
13295            if (!brief) {
13296                if (memInfo.getZramTotalSizeKb() != 0) {
13297                    if (!isCompact) {
13298                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13299                                pw.print(" kB physical used for ");
13300                                pw.print(memInfo.getSwapTotalSizeKb()
13301                                        - memInfo.getSwapFreeSizeKb());
13302                                pw.print(" kB in swap (");
13303                                pw.print(memInfo.getSwapTotalSizeKb());
13304                                pw.println(" kB total swap)");
13305                    } else {
13306                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13307                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13308                                pw.println(memInfo.getSwapFreeSizeKb());
13309                    }
13310                }
13311                final int[] SINGLE_LONG_FORMAT = new int[] {
13312                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13313                };
13314                long[] longOut = new long[1];
13315                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13316                        SINGLE_LONG_FORMAT, null, longOut, null);
13317                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13318                longOut[0] = 0;
13319                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13320                        SINGLE_LONG_FORMAT, null, longOut, null);
13321                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13322                longOut[0] = 0;
13323                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13324                        SINGLE_LONG_FORMAT, null, longOut, null);
13325                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13326                longOut[0] = 0;
13327                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13328                        SINGLE_LONG_FORMAT, null, longOut, null);
13329                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13330                if (!isCompact) {
13331                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13332                        pw.print("      KSM: "); pw.print(sharing);
13333                                pw.print(" kB saved from shared ");
13334                                pw.print(shared); pw.println(" kB");
13335                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13336                                pw.print(voltile); pw.println(" kB volatile");
13337                    }
13338                    pw.print("   Tuning: ");
13339                    pw.print(ActivityManager.staticGetMemoryClass());
13340                    pw.print(" (large ");
13341                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13342                    pw.print("), oom ");
13343                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13344                    pw.print(" kB");
13345                    pw.print(", restore limit ");
13346                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13347                    pw.print(" kB");
13348                    if (ActivityManager.isLowRamDeviceStatic()) {
13349                        pw.print(" (low-ram)");
13350                    }
13351                    if (ActivityManager.isHighEndGfx()) {
13352                        pw.print(" (high-end-gfx)");
13353                    }
13354                    pw.println();
13355                } else {
13356                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13357                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13358                    pw.println(voltile);
13359                    pw.print("tuning,");
13360                    pw.print(ActivityManager.staticGetMemoryClass());
13361                    pw.print(',');
13362                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13363                    pw.print(',');
13364                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13365                    if (ActivityManager.isLowRamDeviceStatic()) {
13366                        pw.print(",low-ram");
13367                    }
13368                    if (ActivityManager.isHighEndGfx()) {
13369                        pw.print(",high-end-gfx");
13370                    }
13371                    pw.println();
13372                }
13373            }
13374        }
13375    }
13376
13377    /**
13378     * Searches array of arguments for the specified string
13379     * @param args array of argument strings
13380     * @param value value to search for
13381     * @return true if the value is contained in the array
13382     */
13383    private static boolean scanArgs(String[] args, String value) {
13384        if (args != null) {
13385            for (String arg : args) {
13386                if (value.equals(arg)) {
13387                    return true;
13388                }
13389            }
13390        }
13391        return false;
13392    }
13393
13394    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13395            ContentProviderRecord cpr, boolean always) {
13396        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13397
13398        if (!inLaunching || always) {
13399            synchronized (cpr) {
13400                cpr.launchingApp = null;
13401                cpr.notifyAll();
13402            }
13403            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13404            String names[] = cpr.info.authority.split(";");
13405            for (int j = 0; j < names.length; j++) {
13406                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13407            }
13408        }
13409
13410        for (int i=0; i<cpr.connections.size(); i++) {
13411            ContentProviderConnection conn = cpr.connections.get(i);
13412            if (conn.waiting) {
13413                // If this connection is waiting for the provider, then we don't
13414                // need to mess with its process unless we are always removing
13415                // or for some reason the provider is not currently launching.
13416                if (inLaunching && !always) {
13417                    continue;
13418                }
13419            }
13420            ProcessRecord capp = conn.client;
13421            conn.dead = true;
13422            if (conn.stableCount > 0) {
13423                if (!capp.persistent && capp.thread != null
13424                        && capp.pid != 0
13425                        && capp.pid != MY_PID) {
13426                    killUnneededProcessLocked(capp, "depends on provider "
13427                            + cpr.name.flattenToShortString()
13428                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13429                }
13430            } else if (capp.thread != null && conn.provider.provider != null) {
13431                try {
13432                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13433                } catch (RemoteException e) {
13434                }
13435                // In the protocol here, we don't expect the client to correctly
13436                // clean up this connection, we'll just remove it.
13437                cpr.connections.remove(i);
13438                conn.client.conProviders.remove(conn);
13439            }
13440        }
13441
13442        if (inLaunching && always) {
13443            mLaunchingProviders.remove(cpr);
13444        }
13445        return inLaunching;
13446    }
13447
13448    /**
13449     * Main code for cleaning up a process when it has gone away.  This is
13450     * called both as a result of the process dying, or directly when stopping
13451     * a process when running in single process mode.
13452     */
13453    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13454            boolean restarting, boolean allowRestart, int index) {
13455        if (index >= 0) {
13456            removeLruProcessLocked(app);
13457            ProcessList.remove(app.pid);
13458        }
13459
13460        mProcessesToGc.remove(app);
13461        mPendingPssProcesses.remove(app);
13462
13463        // Dismiss any open dialogs.
13464        if (app.crashDialog != null && !app.forceCrashReport) {
13465            app.crashDialog.dismiss();
13466            app.crashDialog = null;
13467        }
13468        if (app.anrDialog != null) {
13469            app.anrDialog.dismiss();
13470            app.anrDialog = null;
13471        }
13472        if (app.waitDialog != null) {
13473            app.waitDialog.dismiss();
13474            app.waitDialog = null;
13475        }
13476
13477        app.crashing = false;
13478        app.notResponding = false;
13479
13480        app.resetPackageList(mProcessStats);
13481        app.unlinkDeathRecipient();
13482        app.makeInactive(mProcessStats);
13483        app.waitingToKill = null;
13484        app.forcingToForeground = null;
13485        updateProcessForegroundLocked(app, false, false);
13486        app.foregroundActivities = false;
13487        app.hasShownUi = false;
13488        app.treatLikeActivity = false;
13489        app.hasAboveClient = false;
13490        app.hasClientActivities = false;
13491
13492        mServices.killServicesLocked(app, allowRestart);
13493
13494        boolean restart = false;
13495
13496        // Remove published content providers.
13497        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13498            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13499            final boolean always = app.bad || !allowRestart;
13500            if (removeDyingProviderLocked(app, cpr, always) || always) {
13501                // We left the provider in the launching list, need to
13502                // restart it.
13503                restart = true;
13504            }
13505
13506            cpr.provider = null;
13507            cpr.proc = null;
13508        }
13509        app.pubProviders.clear();
13510
13511        // Take care of any launching providers waiting for this process.
13512        if (checkAppInLaunchingProvidersLocked(app, false)) {
13513            restart = true;
13514        }
13515
13516        // Unregister from connected content providers.
13517        if (!app.conProviders.isEmpty()) {
13518            for (int i=0; i<app.conProviders.size(); i++) {
13519                ContentProviderConnection conn = app.conProviders.get(i);
13520                conn.provider.connections.remove(conn);
13521            }
13522            app.conProviders.clear();
13523        }
13524
13525        // At this point there may be remaining entries in mLaunchingProviders
13526        // where we were the only one waiting, so they are no longer of use.
13527        // Look for these and clean up if found.
13528        // XXX Commented out for now.  Trying to figure out a way to reproduce
13529        // the actual situation to identify what is actually going on.
13530        if (false) {
13531            for (int i=0; i<mLaunchingProviders.size(); i++) {
13532                ContentProviderRecord cpr = (ContentProviderRecord)
13533                        mLaunchingProviders.get(i);
13534                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13535                    synchronized (cpr) {
13536                        cpr.launchingApp = null;
13537                        cpr.notifyAll();
13538                    }
13539                }
13540            }
13541        }
13542
13543        skipCurrentReceiverLocked(app);
13544
13545        // Unregister any receivers.
13546        for (int i=app.receivers.size()-1; i>=0; i--) {
13547            removeReceiverLocked(app.receivers.valueAt(i));
13548        }
13549        app.receivers.clear();
13550
13551        // If the app is undergoing backup, tell the backup manager about it
13552        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13553            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13554                    + mBackupTarget.appInfo + " died during backup");
13555            try {
13556                IBackupManager bm = IBackupManager.Stub.asInterface(
13557                        ServiceManager.getService(Context.BACKUP_SERVICE));
13558                bm.agentDisconnected(app.info.packageName);
13559            } catch (RemoteException e) {
13560                // can't happen; backup manager is local
13561            }
13562        }
13563
13564        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13565            ProcessChangeItem item = mPendingProcessChanges.get(i);
13566            if (item.pid == app.pid) {
13567                mPendingProcessChanges.remove(i);
13568                mAvailProcessChanges.add(item);
13569            }
13570        }
13571        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13572
13573        // If the caller is restarting this app, then leave it in its
13574        // current lists and let the caller take care of it.
13575        if (restarting) {
13576            return;
13577        }
13578
13579        if (!app.persistent || app.isolated) {
13580            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13581                    "Removing non-persistent process during cleanup: " + app);
13582            mProcessNames.remove(app.processName, app.uid);
13583            mIsolatedProcesses.remove(app.uid);
13584            if (mHeavyWeightProcess == app) {
13585                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13586                        mHeavyWeightProcess.userId, 0));
13587                mHeavyWeightProcess = null;
13588            }
13589        } else if (!app.removed) {
13590            // This app is persistent, so we need to keep its record around.
13591            // If it is not already on the pending app list, add it there
13592            // and start a new process for it.
13593            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13594                mPersistentStartingProcesses.add(app);
13595                restart = true;
13596            }
13597        }
13598        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13599                "Clean-up removing on hold: " + app);
13600        mProcessesOnHold.remove(app);
13601
13602        if (app == mHomeProcess) {
13603            mHomeProcess = null;
13604        }
13605        if (app == mPreviousProcess) {
13606            mPreviousProcess = null;
13607        }
13608
13609        if (restart && !app.isolated) {
13610            // We have components that still need to be running in the
13611            // process, so re-launch it.
13612            mProcessNames.put(app.processName, app.uid, app);
13613            startProcessLocked(app, "restart", app.processName);
13614        } else if (app.pid > 0 && app.pid != MY_PID) {
13615            // Goodbye!
13616            boolean removed;
13617            synchronized (mPidsSelfLocked) {
13618                mPidsSelfLocked.remove(app.pid);
13619                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13620            }
13621            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13622            if (app.isolated) {
13623                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13624            }
13625            app.setPid(0);
13626        }
13627    }
13628
13629    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13630        // Look through the content providers we are waiting to have launched,
13631        // and if any run in this process then either schedule a restart of
13632        // the process or kill the client waiting for it if this process has
13633        // gone bad.
13634        int NL = mLaunchingProviders.size();
13635        boolean restart = false;
13636        for (int i=0; i<NL; i++) {
13637            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13638            if (cpr.launchingApp == app) {
13639                if (!alwaysBad && !app.bad) {
13640                    restart = true;
13641                } else {
13642                    removeDyingProviderLocked(app, cpr, true);
13643                    // cpr should have been removed from mLaunchingProviders
13644                    NL = mLaunchingProviders.size();
13645                    i--;
13646                }
13647            }
13648        }
13649        return restart;
13650    }
13651
13652    // =========================================================
13653    // SERVICES
13654    // =========================================================
13655
13656    @Override
13657    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13658            int flags) {
13659        enforceNotIsolatedCaller("getServices");
13660        synchronized (this) {
13661            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13662        }
13663    }
13664
13665    @Override
13666    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13667        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13668        synchronized (this) {
13669            return mServices.getRunningServiceControlPanelLocked(name);
13670        }
13671    }
13672
13673    @Override
13674    public ComponentName startService(IApplicationThread caller, Intent service,
13675            String resolvedType, int userId) {
13676        enforceNotIsolatedCaller("startService");
13677        // Refuse possible leaked file descriptors
13678        if (service != null && service.hasFileDescriptors() == true) {
13679            throw new IllegalArgumentException("File descriptors passed in Intent");
13680        }
13681
13682        if (DEBUG_SERVICE)
13683            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13684        synchronized(this) {
13685            final int callingPid = Binder.getCallingPid();
13686            final int callingUid = Binder.getCallingUid();
13687            final long origId = Binder.clearCallingIdentity();
13688            ComponentName res = mServices.startServiceLocked(caller, service,
13689                    resolvedType, callingPid, callingUid, userId);
13690            Binder.restoreCallingIdentity(origId);
13691            return res;
13692        }
13693    }
13694
13695    ComponentName startServiceInPackage(int uid,
13696            Intent service, String resolvedType, int userId) {
13697        synchronized(this) {
13698            if (DEBUG_SERVICE)
13699                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13700            final long origId = Binder.clearCallingIdentity();
13701            ComponentName res = mServices.startServiceLocked(null, service,
13702                    resolvedType, -1, uid, userId);
13703            Binder.restoreCallingIdentity(origId);
13704            return res;
13705        }
13706    }
13707
13708    @Override
13709    public int stopService(IApplicationThread caller, Intent service,
13710            String resolvedType, int userId) {
13711        enforceNotIsolatedCaller("stopService");
13712        // Refuse possible leaked file descriptors
13713        if (service != null && service.hasFileDescriptors() == true) {
13714            throw new IllegalArgumentException("File descriptors passed in Intent");
13715        }
13716
13717        synchronized(this) {
13718            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13719        }
13720    }
13721
13722    @Override
13723    public IBinder peekService(Intent service, String resolvedType) {
13724        enforceNotIsolatedCaller("peekService");
13725        // Refuse possible leaked file descriptors
13726        if (service != null && service.hasFileDescriptors() == true) {
13727            throw new IllegalArgumentException("File descriptors passed in Intent");
13728        }
13729        synchronized(this) {
13730            return mServices.peekServiceLocked(service, resolvedType);
13731        }
13732    }
13733
13734    @Override
13735    public boolean stopServiceToken(ComponentName className, IBinder token,
13736            int startId) {
13737        synchronized(this) {
13738            return mServices.stopServiceTokenLocked(className, token, startId);
13739        }
13740    }
13741
13742    @Override
13743    public void setServiceForeground(ComponentName className, IBinder token,
13744            int id, Notification notification, boolean removeNotification) {
13745        synchronized(this) {
13746            mServices.setServiceForegroundLocked(className, token, id, notification,
13747                    removeNotification);
13748        }
13749    }
13750
13751    @Override
13752    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13753            boolean requireFull, String name, String callerPackage) {
13754        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13755                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13756    }
13757
13758    int unsafeConvertIncomingUser(int userId) {
13759        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13760                ? mCurrentUserId : userId;
13761    }
13762
13763    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13764            int allowMode, String name, String callerPackage) {
13765        final int callingUserId = UserHandle.getUserId(callingUid);
13766        if (callingUserId == userId) {
13767            return userId;
13768        }
13769
13770        // Note that we may be accessing mCurrentUserId outside of a lock...
13771        // shouldn't be a big deal, if this is being called outside
13772        // of a locked context there is intrinsically a race with
13773        // the value the caller will receive and someone else changing it.
13774        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13775        // we will switch to the calling user if access to the current user fails.
13776        int targetUserId = unsafeConvertIncomingUser(userId);
13777
13778        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13779            final boolean allow;
13780            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13781                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13782                // If the caller has this permission, they always pass go.  And collect $200.
13783                allow = true;
13784            } else if (allowMode == ALLOW_FULL_ONLY) {
13785                // We require full access, sucks to be you.
13786                allow = false;
13787            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13788                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13789                // If the caller does not have either permission, they are always doomed.
13790                allow = false;
13791            } else if (allowMode == ALLOW_NON_FULL) {
13792                // We are blanket allowing non-full access, you lucky caller!
13793                allow = true;
13794            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13795                // We may or may not allow this depending on whether the two users are
13796                // in the same profile.
13797                synchronized (mUserProfileGroupIdsSelfLocked) {
13798                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13799                            UserInfo.NO_PROFILE_GROUP_ID);
13800                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13801                            UserInfo.NO_PROFILE_GROUP_ID);
13802                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13803                            && callingProfile == targetProfile;
13804                }
13805            } else {
13806                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13807            }
13808            if (!allow) {
13809                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13810                    // In this case, they would like to just execute as their
13811                    // owner user instead of failing.
13812                    targetUserId = callingUserId;
13813                } else {
13814                    StringBuilder builder = new StringBuilder(128);
13815                    builder.append("Permission Denial: ");
13816                    builder.append(name);
13817                    if (callerPackage != null) {
13818                        builder.append(" from ");
13819                        builder.append(callerPackage);
13820                    }
13821                    builder.append(" asks to run as user ");
13822                    builder.append(userId);
13823                    builder.append(" but is calling from user ");
13824                    builder.append(UserHandle.getUserId(callingUid));
13825                    builder.append("; this requires ");
13826                    builder.append(INTERACT_ACROSS_USERS_FULL);
13827                    if (allowMode != ALLOW_FULL_ONLY) {
13828                        builder.append(" or ");
13829                        builder.append(INTERACT_ACROSS_USERS);
13830                    }
13831                    String msg = builder.toString();
13832                    Slog.w(TAG, msg);
13833                    throw new SecurityException(msg);
13834                }
13835            }
13836        }
13837        if (!allowAll && targetUserId < 0) {
13838            throw new IllegalArgumentException(
13839                    "Call does not support special user #" + targetUserId);
13840        }
13841        return targetUserId;
13842    }
13843
13844    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13845            String className, int flags) {
13846        boolean result = false;
13847        // For apps that don't have pre-defined UIDs, check for permission
13848        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13849            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13850                if (ActivityManager.checkUidPermission(
13851                        INTERACT_ACROSS_USERS,
13852                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13853                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13854                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13855                            + " requests FLAG_SINGLE_USER, but app does not hold "
13856                            + INTERACT_ACROSS_USERS;
13857                    Slog.w(TAG, msg);
13858                    throw new SecurityException(msg);
13859                }
13860                // Permission passed
13861                result = true;
13862            }
13863        } else if ("system".equals(componentProcessName)) {
13864            result = true;
13865        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13866                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13867            // Phone app is allowed to export singleuser providers.
13868            result = true;
13869        } else {
13870            // App with pre-defined UID, check if it's a persistent app
13871            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13872        }
13873        if (DEBUG_MU) {
13874            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13875                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13876        }
13877        return result;
13878    }
13879
13880    /**
13881     * Checks to see if the caller is in the same app as the singleton
13882     * component, or the component is in a special app. It allows special apps
13883     * to export singleton components but prevents exporting singleton
13884     * components for regular apps.
13885     */
13886    boolean isValidSingletonCall(int callingUid, int componentUid) {
13887        int componentAppId = UserHandle.getAppId(componentUid);
13888        return UserHandle.isSameApp(callingUid, componentUid)
13889                || componentAppId == Process.SYSTEM_UID
13890                || componentAppId == Process.PHONE_UID
13891                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13892                        == PackageManager.PERMISSION_GRANTED;
13893    }
13894
13895    public int bindService(IApplicationThread caller, IBinder token,
13896            Intent service, String resolvedType,
13897            IServiceConnection connection, int flags, int userId) {
13898        enforceNotIsolatedCaller("bindService");
13899        // Refuse possible leaked file descriptors
13900        if (service != null && service.hasFileDescriptors() == true) {
13901            throw new IllegalArgumentException("File descriptors passed in Intent");
13902        }
13903
13904        synchronized(this) {
13905            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13906                    connection, flags, userId);
13907        }
13908    }
13909
13910    public boolean unbindService(IServiceConnection connection) {
13911        synchronized (this) {
13912            return mServices.unbindServiceLocked(connection);
13913        }
13914    }
13915
13916    public void publishService(IBinder token, Intent intent, IBinder service) {
13917        // Refuse possible leaked file descriptors
13918        if (intent != null && intent.hasFileDescriptors() == true) {
13919            throw new IllegalArgumentException("File descriptors passed in Intent");
13920        }
13921
13922        synchronized(this) {
13923            if (!(token instanceof ServiceRecord)) {
13924                throw new IllegalArgumentException("Invalid service token");
13925            }
13926            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13927        }
13928    }
13929
13930    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13931        // Refuse possible leaked file descriptors
13932        if (intent != null && intent.hasFileDescriptors() == true) {
13933            throw new IllegalArgumentException("File descriptors passed in Intent");
13934        }
13935
13936        synchronized(this) {
13937            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13938        }
13939    }
13940
13941    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13942        synchronized(this) {
13943            if (!(token instanceof ServiceRecord)) {
13944                throw new IllegalArgumentException("Invalid service token");
13945            }
13946            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13947        }
13948    }
13949
13950    // =========================================================
13951    // BACKUP AND RESTORE
13952    // =========================================================
13953
13954    // Cause the target app to be launched if necessary and its backup agent
13955    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13956    // activity manager to announce its creation.
13957    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13958        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13959        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13960
13961        synchronized(this) {
13962            // !!! TODO: currently no check here that we're already bound
13963            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13964            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13965            synchronized (stats) {
13966                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13967            }
13968
13969            // Backup agent is now in use, its package can't be stopped.
13970            try {
13971                AppGlobals.getPackageManager().setPackageStoppedState(
13972                        app.packageName, false, UserHandle.getUserId(app.uid));
13973            } catch (RemoteException e) {
13974            } catch (IllegalArgumentException e) {
13975                Slog.w(TAG, "Failed trying to unstop package "
13976                        + app.packageName + ": " + e);
13977            }
13978
13979            BackupRecord r = new BackupRecord(ss, app, backupMode);
13980            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13981                    ? new ComponentName(app.packageName, app.backupAgentName)
13982                    : new ComponentName("android", "FullBackupAgent");
13983            // startProcessLocked() returns existing proc's record if it's already running
13984            ProcessRecord proc = startProcessLocked(app.processName, app,
13985                    false, 0, "backup", hostingName, false, false, false);
13986            if (proc == null) {
13987                Slog.e(TAG, "Unable to start backup agent process " + r);
13988                return false;
13989            }
13990
13991            r.app = proc;
13992            mBackupTarget = r;
13993            mBackupAppName = app.packageName;
13994
13995            // Try not to kill the process during backup
13996            updateOomAdjLocked(proc);
13997
13998            // If the process is already attached, schedule the creation of the backup agent now.
13999            // If it is not yet live, this will be done when it attaches to the framework.
14000            if (proc.thread != null) {
14001                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14002                try {
14003                    proc.thread.scheduleCreateBackupAgent(app,
14004                            compatibilityInfoForPackageLocked(app), backupMode);
14005                } catch (RemoteException e) {
14006                    // Will time out on the backup manager side
14007                }
14008            } else {
14009                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14010            }
14011            // Invariants: at this point, the target app process exists and the application
14012            // is either already running or in the process of coming up.  mBackupTarget and
14013            // mBackupAppName describe the app, so that when it binds back to the AM we
14014            // know that it's scheduled for a backup-agent operation.
14015        }
14016
14017        return true;
14018    }
14019
14020    @Override
14021    public void clearPendingBackup() {
14022        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14023        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14024
14025        synchronized (this) {
14026            mBackupTarget = null;
14027            mBackupAppName = null;
14028        }
14029    }
14030
14031    // A backup agent has just come up
14032    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14033        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14034                + " = " + agent);
14035
14036        synchronized(this) {
14037            if (!agentPackageName.equals(mBackupAppName)) {
14038                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14039                return;
14040            }
14041        }
14042
14043        long oldIdent = Binder.clearCallingIdentity();
14044        try {
14045            IBackupManager bm = IBackupManager.Stub.asInterface(
14046                    ServiceManager.getService(Context.BACKUP_SERVICE));
14047            bm.agentConnected(agentPackageName, agent);
14048        } catch (RemoteException e) {
14049            // can't happen; the backup manager service is local
14050        } catch (Exception e) {
14051            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14052            e.printStackTrace();
14053        } finally {
14054            Binder.restoreCallingIdentity(oldIdent);
14055        }
14056    }
14057
14058    // done with this agent
14059    public void unbindBackupAgent(ApplicationInfo appInfo) {
14060        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14061        if (appInfo == null) {
14062            Slog.w(TAG, "unbind backup agent for null app");
14063            return;
14064        }
14065
14066        synchronized(this) {
14067            try {
14068                if (mBackupAppName == null) {
14069                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14070                    return;
14071                }
14072
14073                if (!mBackupAppName.equals(appInfo.packageName)) {
14074                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14075                    return;
14076                }
14077
14078                // Not backing this app up any more; reset its OOM adjustment
14079                final ProcessRecord proc = mBackupTarget.app;
14080                updateOomAdjLocked(proc);
14081
14082                // If the app crashed during backup, 'thread' will be null here
14083                if (proc.thread != null) {
14084                    try {
14085                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14086                                compatibilityInfoForPackageLocked(appInfo));
14087                    } catch (Exception e) {
14088                        Slog.e(TAG, "Exception when unbinding backup agent:");
14089                        e.printStackTrace();
14090                    }
14091                }
14092            } finally {
14093                mBackupTarget = null;
14094                mBackupAppName = null;
14095            }
14096        }
14097    }
14098    // =========================================================
14099    // BROADCASTS
14100    // =========================================================
14101
14102    private final List getStickiesLocked(String action, IntentFilter filter,
14103            List cur, int userId) {
14104        final ContentResolver resolver = mContext.getContentResolver();
14105        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14106        if (stickies == null) {
14107            return cur;
14108        }
14109        final ArrayList<Intent> list = stickies.get(action);
14110        if (list == null) {
14111            return cur;
14112        }
14113        int N = list.size();
14114        for (int i=0; i<N; i++) {
14115            Intent intent = list.get(i);
14116            if (filter.match(resolver, intent, true, TAG) >= 0) {
14117                if (cur == null) {
14118                    cur = new ArrayList<Intent>();
14119                }
14120                cur.add(intent);
14121            }
14122        }
14123        return cur;
14124    }
14125
14126    boolean isPendingBroadcastProcessLocked(int pid) {
14127        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14128                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14129    }
14130
14131    void skipPendingBroadcastLocked(int pid) {
14132            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14133            for (BroadcastQueue queue : mBroadcastQueues) {
14134                queue.skipPendingBroadcastLocked(pid);
14135            }
14136    }
14137
14138    // The app just attached; send any pending broadcasts that it should receive
14139    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14140        boolean didSomething = false;
14141        for (BroadcastQueue queue : mBroadcastQueues) {
14142            didSomething |= queue.sendPendingBroadcastsLocked(app);
14143        }
14144        return didSomething;
14145    }
14146
14147    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14148            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14149        enforceNotIsolatedCaller("registerReceiver");
14150        int callingUid;
14151        int callingPid;
14152        synchronized(this) {
14153            ProcessRecord callerApp = null;
14154            if (caller != null) {
14155                callerApp = getRecordForAppLocked(caller);
14156                if (callerApp == null) {
14157                    throw new SecurityException(
14158                            "Unable to find app for caller " + caller
14159                            + " (pid=" + Binder.getCallingPid()
14160                            + ") when registering receiver " + receiver);
14161                }
14162                if (callerApp.info.uid != Process.SYSTEM_UID &&
14163                        !callerApp.pkgList.containsKey(callerPackage) &&
14164                        !"android".equals(callerPackage)) {
14165                    throw new SecurityException("Given caller package " + callerPackage
14166                            + " is not running in process " + callerApp);
14167                }
14168                callingUid = callerApp.info.uid;
14169                callingPid = callerApp.pid;
14170            } else {
14171                callerPackage = null;
14172                callingUid = Binder.getCallingUid();
14173                callingPid = Binder.getCallingPid();
14174            }
14175
14176            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14177                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14178
14179            List allSticky = null;
14180
14181            // Look for any matching sticky broadcasts...
14182            Iterator actions = filter.actionsIterator();
14183            if (actions != null) {
14184                while (actions.hasNext()) {
14185                    String action = (String)actions.next();
14186                    allSticky = getStickiesLocked(action, filter, allSticky,
14187                            UserHandle.USER_ALL);
14188                    allSticky = getStickiesLocked(action, filter, allSticky,
14189                            UserHandle.getUserId(callingUid));
14190                }
14191            } else {
14192                allSticky = getStickiesLocked(null, filter, allSticky,
14193                        UserHandle.USER_ALL);
14194                allSticky = getStickiesLocked(null, filter, allSticky,
14195                        UserHandle.getUserId(callingUid));
14196            }
14197
14198            // The first sticky in the list is returned directly back to
14199            // the client.
14200            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14201
14202            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14203                    + ": " + sticky);
14204
14205            if (receiver == null) {
14206                return sticky;
14207            }
14208
14209            ReceiverList rl
14210                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14211            if (rl == null) {
14212                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14213                        userId, receiver);
14214                if (rl.app != null) {
14215                    rl.app.receivers.add(rl);
14216                } else {
14217                    try {
14218                        receiver.asBinder().linkToDeath(rl, 0);
14219                    } catch (RemoteException e) {
14220                        return sticky;
14221                    }
14222                    rl.linkedToDeath = true;
14223                }
14224                mRegisteredReceivers.put(receiver.asBinder(), rl);
14225            } else if (rl.uid != callingUid) {
14226                throw new IllegalArgumentException(
14227                        "Receiver requested to register for uid " + callingUid
14228                        + " was previously registered for uid " + rl.uid);
14229            } else if (rl.pid != callingPid) {
14230                throw new IllegalArgumentException(
14231                        "Receiver requested to register for pid " + callingPid
14232                        + " was previously registered for pid " + rl.pid);
14233            } else if (rl.userId != userId) {
14234                throw new IllegalArgumentException(
14235                        "Receiver requested to register for user " + userId
14236                        + " was previously registered for user " + rl.userId);
14237            }
14238            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14239                    permission, callingUid, userId);
14240            rl.add(bf);
14241            if (!bf.debugCheck()) {
14242                Slog.w(TAG, "==> For Dynamic broadast");
14243            }
14244            mReceiverResolver.addFilter(bf);
14245
14246            // Enqueue broadcasts for all existing stickies that match
14247            // this filter.
14248            if (allSticky != null) {
14249                ArrayList receivers = new ArrayList();
14250                receivers.add(bf);
14251
14252                int N = allSticky.size();
14253                for (int i=0; i<N; i++) {
14254                    Intent intent = (Intent)allSticky.get(i);
14255                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14256                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14257                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14258                            null, null, false, true, true, -1);
14259                    queue.enqueueParallelBroadcastLocked(r);
14260                    queue.scheduleBroadcastsLocked();
14261                }
14262            }
14263
14264            return sticky;
14265        }
14266    }
14267
14268    public void unregisterReceiver(IIntentReceiver receiver) {
14269        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14270
14271        final long origId = Binder.clearCallingIdentity();
14272        try {
14273            boolean doTrim = false;
14274
14275            synchronized(this) {
14276                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14277                if (rl != null) {
14278                    if (rl.curBroadcast != null) {
14279                        BroadcastRecord r = rl.curBroadcast;
14280                        final boolean doNext = finishReceiverLocked(
14281                                receiver.asBinder(), r.resultCode, r.resultData,
14282                                r.resultExtras, r.resultAbort);
14283                        if (doNext) {
14284                            doTrim = true;
14285                            r.queue.processNextBroadcast(false);
14286                        }
14287                    }
14288
14289                    if (rl.app != null) {
14290                        rl.app.receivers.remove(rl);
14291                    }
14292                    removeReceiverLocked(rl);
14293                    if (rl.linkedToDeath) {
14294                        rl.linkedToDeath = false;
14295                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14296                    }
14297                }
14298            }
14299
14300            // If we actually concluded any broadcasts, we might now be able
14301            // to trim the recipients' apps from our working set
14302            if (doTrim) {
14303                trimApplications();
14304                return;
14305            }
14306
14307        } finally {
14308            Binder.restoreCallingIdentity(origId);
14309        }
14310    }
14311
14312    void removeReceiverLocked(ReceiverList rl) {
14313        mRegisteredReceivers.remove(rl.receiver.asBinder());
14314        int N = rl.size();
14315        for (int i=0; i<N; i++) {
14316            mReceiverResolver.removeFilter(rl.get(i));
14317        }
14318    }
14319
14320    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14321        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14322            ProcessRecord r = mLruProcesses.get(i);
14323            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14324                try {
14325                    r.thread.dispatchPackageBroadcast(cmd, packages);
14326                } catch (RemoteException ex) {
14327                }
14328            }
14329        }
14330    }
14331
14332    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14333            int[] users) {
14334        List<ResolveInfo> receivers = null;
14335        try {
14336            HashSet<ComponentName> singleUserReceivers = null;
14337            boolean scannedFirstReceivers = false;
14338            for (int user : users) {
14339                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14340                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14341                if (user != 0 && newReceivers != null) {
14342                    // If this is not the primary user, we need to check for
14343                    // any receivers that should be filtered out.
14344                    for (int i=0; i<newReceivers.size(); i++) {
14345                        ResolveInfo ri = newReceivers.get(i);
14346                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14347                            newReceivers.remove(i);
14348                            i--;
14349                        }
14350                    }
14351                }
14352                if (newReceivers != null && newReceivers.size() == 0) {
14353                    newReceivers = null;
14354                }
14355                if (receivers == null) {
14356                    receivers = newReceivers;
14357                } else if (newReceivers != null) {
14358                    // We need to concatenate the additional receivers
14359                    // found with what we have do far.  This would be easy,
14360                    // but we also need to de-dup any receivers that are
14361                    // singleUser.
14362                    if (!scannedFirstReceivers) {
14363                        // Collect any single user receivers we had already retrieved.
14364                        scannedFirstReceivers = true;
14365                        for (int i=0; i<receivers.size(); i++) {
14366                            ResolveInfo ri = receivers.get(i);
14367                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14368                                ComponentName cn = new ComponentName(
14369                                        ri.activityInfo.packageName, ri.activityInfo.name);
14370                                if (singleUserReceivers == null) {
14371                                    singleUserReceivers = new HashSet<ComponentName>();
14372                                }
14373                                singleUserReceivers.add(cn);
14374                            }
14375                        }
14376                    }
14377                    // Add the new results to the existing results, tracking
14378                    // and de-dupping single user receivers.
14379                    for (int i=0; i<newReceivers.size(); i++) {
14380                        ResolveInfo ri = newReceivers.get(i);
14381                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14382                            ComponentName cn = new ComponentName(
14383                                    ri.activityInfo.packageName, ri.activityInfo.name);
14384                            if (singleUserReceivers == null) {
14385                                singleUserReceivers = new HashSet<ComponentName>();
14386                            }
14387                            if (!singleUserReceivers.contains(cn)) {
14388                                singleUserReceivers.add(cn);
14389                                receivers.add(ri);
14390                            }
14391                        } else {
14392                            receivers.add(ri);
14393                        }
14394                    }
14395                }
14396            }
14397        } catch (RemoteException ex) {
14398            // pm is in same process, this will never happen.
14399        }
14400        return receivers;
14401    }
14402
14403    private final int broadcastIntentLocked(ProcessRecord callerApp,
14404            String callerPackage, Intent intent, String resolvedType,
14405            IIntentReceiver resultTo, int resultCode, String resultData,
14406            Bundle map, String requiredPermission, int appOp,
14407            boolean ordered, boolean sticky, int callingPid, int callingUid,
14408            int userId) {
14409        intent = new Intent(intent);
14410
14411        // By default broadcasts do not go to stopped apps.
14412        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14413
14414        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14415            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14416            + " ordered=" + ordered + " userid=" + userId);
14417        if ((resultTo != null) && !ordered) {
14418            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14419        }
14420
14421        userId = handleIncomingUser(callingPid, callingUid, userId,
14422                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14423
14424        // Make sure that the user who is receiving this broadcast is started.
14425        // If not, we will just skip it.
14426
14427
14428        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14429            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14430                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14431                Slog.w(TAG, "Skipping broadcast of " + intent
14432                        + ": user " + userId + " is stopped");
14433                return ActivityManager.BROADCAST_SUCCESS;
14434            }
14435        }
14436
14437        /*
14438         * Prevent non-system code (defined here to be non-persistent
14439         * processes) from sending protected broadcasts.
14440         */
14441        int callingAppId = UserHandle.getAppId(callingUid);
14442        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14443            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14444            || callingAppId == Process.NFC_UID || callingUid == 0) {
14445            // Always okay.
14446        } else if (callerApp == null || !callerApp.persistent) {
14447            try {
14448                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14449                        intent.getAction())) {
14450                    String msg = "Permission Denial: not allowed to send broadcast "
14451                            + intent.getAction() + " from pid="
14452                            + callingPid + ", uid=" + callingUid;
14453                    Slog.w(TAG, msg);
14454                    throw new SecurityException(msg);
14455                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14456                    // Special case for compatibility: we don't want apps to send this,
14457                    // but historically it has not been protected and apps may be using it
14458                    // to poke their own app widget.  So, instead of making it protected,
14459                    // just limit it to the caller.
14460                    if (callerApp == null) {
14461                        String msg = "Permission Denial: not allowed to send broadcast "
14462                                + intent.getAction() + " from unknown caller.";
14463                        Slog.w(TAG, msg);
14464                        throw new SecurityException(msg);
14465                    } else if (intent.getComponent() != null) {
14466                        // They are good enough to send to an explicit component...  verify
14467                        // it is being sent to the calling app.
14468                        if (!intent.getComponent().getPackageName().equals(
14469                                callerApp.info.packageName)) {
14470                            String msg = "Permission Denial: not allowed to send broadcast "
14471                                    + intent.getAction() + " to "
14472                                    + intent.getComponent().getPackageName() + " from "
14473                                    + callerApp.info.packageName;
14474                            Slog.w(TAG, msg);
14475                            throw new SecurityException(msg);
14476                        }
14477                    } else {
14478                        // Limit broadcast to their own package.
14479                        intent.setPackage(callerApp.info.packageName);
14480                    }
14481                }
14482            } catch (RemoteException e) {
14483                Slog.w(TAG, "Remote exception", e);
14484                return ActivityManager.BROADCAST_SUCCESS;
14485            }
14486        }
14487
14488        // Handle special intents: if this broadcast is from the package
14489        // manager about a package being removed, we need to remove all of
14490        // its activities from the history stack.
14491        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14492                intent.getAction());
14493        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14494                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14495                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14496                || uidRemoved) {
14497            if (checkComponentPermission(
14498                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14499                    callingPid, callingUid, -1, true)
14500                    == PackageManager.PERMISSION_GRANTED) {
14501                if (uidRemoved) {
14502                    final Bundle intentExtras = intent.getExtras();
14503                    final int uid = intentExtras != null
14504                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14505                    if (uid >= 0) {
14506                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14507                        synchronized (bs) {
14508                            bs.removeUidStatsLocked(uid);
14509                        }
14510                        mAppOpsService.uidRemoved(uid);
14511                    }
14512                } else {
14513                    // If resources are unavailable just force stop all
14514                    // those packages and flush the attribute cache as well.
14515                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14516                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14517                        if (list != null && (list.length > 0)) {
14518                            for (String pkg : list) {
14519                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14520                                        "storage unmount");
14521                            }
14522                            sendPackageBroadcastLocked(
14523                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14524                        }
14525                    } else {
14526                        Uri data = intent.getData();
14527                        String ssp;
14528                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14529                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14530                                    intent.getAction());
14531                            boolean fullUninstall = removed &&
14532                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14533                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14534                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14535                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14536                                        false, fullUninstall, userId,
14537                                        removed ? "pkg removed" : "pkg changed");
14538                            }
14539                            if (removed) {
14540                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14541                                        new String[] {ssp}, userId);
14542                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14543                                    mAppOpsService.packageRemoved(
14544                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14545
14546                                    // Remove all permissions granted from/to this package
14547                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14548                                }
14549                            }
14550                        }
14551                    }
14552                }
14553            } else {
14554                String msg = "Permission Denial: " + intent.getAction()
14555                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14556                        + ", uid=" + callingUid + ")"
14557                        + " requires "
14558                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14559                Slog.w(TAG, msg);
14560                throw new SecurityException(msg);
14561            }
14562
14563        // Special case for adding a package: by default turn on compatibility
14564        // mode.
14565        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14566            Uri data = intent.getData();
14567            String ssp;
14568            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14569                mCompatModePackages.handlePackageAddedLocked(ssp,
14570                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14571            }
14572        }
14573
14574        /*
14575         * If this is the time zone changed action, queue up a message that will reset the timezone
14576         * of all currently running processes. This message will get queued up before the broadcast
14577         * happens.
14578         */
14579        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14580            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14581        }
14582
14583        /*
14584         * If the user set the time, let all running processes know.
14585         */
14586        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14587            final int is24Hour = intent.getBooleanExtra(
14588                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14589            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14590        }
14591
14592        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14593            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14594        }
14595
14596        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14597            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14598            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14599        }
14600
14601        // Add to the sticky list if requested.
14602        if (sticky) {
14603            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14604                    callingPid, callingUid)
14605                    != PackageManager.PERMISSION_GRANTED) {
14606                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14607                        + callingPid + ", uid=" + callingUid
14608                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14609                Slog.w(TAG, msg);
14610                throw new SecurityException(msg);
14611            }
14612            if (requiredPermission != null) {
14613                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14614                        + " and enforce permission " + requiredPermission);
14615                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14616            }
14617            if (intent.getComponent() != null) {
14618                throw new SecurityException(
14619                        "Sticky broadcasts can't target a specific component");
14620            }
14621            // We use userId directly here, since the "all" target is maintained
14622            // as a separate set of sticky broadcasts.
14623            if (userId != UserHandle.USER_ALL) {
14624                // But first, if this is not a broadcast to all users, then
14625                // make sure it doesn't conflict with an existing broadcast to
14626                // all users.
14627                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14628                        UserHandle.USER_ALL);
14629                if (stickies != null) {
14630                    ArrayList<Intent> list = stickies.get(intent.getAction());
14631                    if (list != null) {
14632                        int N = list.size();
14633                        int i;
14634                        for (i=0; i<N; i++) {
14635                            if (intent.filterEquals(list.get(i))) {
14636                                throw new IllegalArgumentException(
14637                                        "Sticky broadcast " + intent + " for user "
14638                                        + userId + " conflicts with existing global broadcast");
14639                            }
14640                        }
14641                    }
14642                }
14643            }
14644            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14645            if (stickies == null) {
14646                stickies = new ArrayMap<String, ArrayList<Intent>>();
14647                mStickyBroadcasts.put(userId, stickies);
14648            }
14649            ArrayList<Intent> list = stickies.get(intent.getAction());
14650            if (list == null) {
14651                list = new ArrayList<Intent>();
14652                stickies.put(intent.getAction(), list);
14653            }
14654            int N = list.size();
14655            int i;
14656            for (i=0; i<N; i++) {
14657                if (intent.filterEquals(list.get(i))) {
14658                    // This sticky already exists, replace it.
14659                    list.set(i, new Intent(intent));
14660                    break;
14661                }
14662            }
14663            if (i >= N) {
14664                list.add(new Intent(intent));
14665            }
14666        }
14667
14668        int[] users;
14669        if (userId == UserHandle.USER_ALL) {
14670            // Caller wants broadcast to go to all started users.
14671            users = mStartedUserArray;
14672        } else {
14673            // Caller wants broadcast to go to one specific user.
14674            users = new int[] {userId};
14675        }
14676
14677        // Figure out who all will receive this broadcast.
14678        List receivers = null;
14679        List<BroadcastFilter> registeredReceivers = null;
14680        // Need to resolve the intent to interested receivers...
14681        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14682                 == 0) {
14683            receivers = collectReceiverComponents(intent, resolvedType, users);
14684        }
14685        if (intent.getComponent() == null) {
14686            registeredReceivers = mReceiverResolver.queryIntent(intent,
14687                    resolvedType, false, userId);
14688        }
14689
14690        final boolean replacePending =
14691                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14692
14693        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14694                + " replacePending=" + replacePending);
14695
14696        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14697        if (!ordered && NR > 0) {
14698            // If we are not serializing this broadcast, then send the
14699            // registered receivers separately so they don't wait for the
14700            // components to be launched.
14701            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14702            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14703                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14704                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14705                    ordered, sticky, false, userId);
14706            if (DEBUG_BROADCAST) Slog.v(
14707                    TAG, "Enqueueing parallel broadcast " + r);
14708            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14709            if (!replaced) {
14710                queue.enqueueParallelBroadcastLocked(r);
14711                queue.scheduleBroadcastsLocked();
14712            }
14713            registeredReceivers = null;
14714            NR = 0;
14715        }
14716
14717        // Merge into one list.
14718        int ir = 0;
14719        if (receivers != null) {
14720            // A special case for PACKAGE_ADDED: do not allow the package
14721            // being added to see this broadcast.  This prevents them from
14722            // using this as a back door to get run as soon as they are
14723            // installed.  Maybe in the future we want to have a special install
14724            // broadcast or such for apps, but we'd like to deliberately make
14725            // this decision.
14726            String skipPackages[] = null;
14727            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14728                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14729                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14730                Uri data = intent.getData();
14731                if (data != null) {
14732                    String pkgName = data.getSchemeSpecificPart();
14733                    if (pkgName != null) {
14734                        skipPackages = new String[] { pkgName };
14735                    }
14736                }
14737            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14738                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14739            }
14740            if (skipPackages != null && (skipPackages.length > 0)) {
14741                for (String skipPackage : skipPackages) {
14742                    if (skipPackage != null) {
14743                        int NT = receivers.size();
14744                        for (int it=0; it<NT; it++) {
14745                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14746                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14747                                receivers.remove(it);
14748                                it--;
14749                                NT--;
14750                            }
14751                        }
14752                    }
14753                }
14754            }
14755
14756            int NT = receivers != null ? receivers.size() : 0;
14757            int it = 0;
14758            ResolveInfo curt = null;
14759            BroadcastFilter curr = null;
14760            while (it < NT && ir < NR) {
14761                if (curt == null) {
14762                    curt = (ResolveInfo)receivers.get(it);
14763                }
14764                if (curr == null) {
14765                    curr = registeredReceivers.get(ir);
14766                }
14767                if (curr.getPriority() >= curt.priority) {
14768                    // Insert this broadcast record into the final list.
14769                    receivers.add(it, curr);
14770                    ir++;
14771                    curr = null;
14772                    it++;
14773                    NT++;
14774                } else {
14775                    // Skip to the next ResolveInfo in the final list.
14776                    it++;
14777                    curt = null;
14778                }
14779            }
14780        }
14781        while (ir < NR) {
14782            if (receivers == null) {
14783                receivers = new ArrayList();
14784            }
14785            receivers.add(registeredReceivers.get(ir));
14786            ir++;
14787        }
14788
14789        if ((receivers != null && receivers.size() > 0)
14790                || resultTo != null) {
14791            BroadcastQueue queue = broadcastQueueForIntent(intent);
14792            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14793                    callerPackage, callingPid, callingUid, resolvedType,
14794                    requiredPermission, appOp, receivers, resultTo, resultCode,
14795                    resultData, map, ordered, sticky, false, userId);
14796            if (DEBUG_BROADCAST) Slog.v(
14797                    TAG, "Enqueueing ordered broadcast " + r
14798                    + ": prev had " + queue.mOrderedBroadcasts.size());
14799            if (DEBUG_BROADCAST) {
14800                int seq = r.intent.getIntExtra("seq", -1);
14801                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14802            }
14803            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14804            if (!replaced) {
14805                queue.enqueueOrderedBroadcastLocked(r);
14806                queue.scheduleBroadcastsLocked();
14807            }
14808        }
14809
14810        return ActivityManager.BROADCAST_SUCCESS;
14811    }
14812
14813    final Intent verifyBroadcastLocked(Intent intent) {
14814        // Refuse possible leaked file descriptors
14815        if (intent != null && intent.hasFileDescriptors() == true) {
14816            throw new IllegalArgumentException("File descriptors passed in Intent");
14817        }
14818
14819        int flags = intent.getFlags();
14820
14821        if (!mProcessesReady) {
14822            // if the caller really truly claims to know what they're doing, go
14823            // ahead and allow the broadcast without launching any receivers
14824            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14825                intent = new Intent(intent);
14826                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14827            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14828                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14829                        + " before boot completion");
14830                throw new IllegalStateException("Cannot broadcast before boot completed");
14831            }
14832        }
14833
14834        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14835            throw new IllegalArgumentException(
14836                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14837        }
14838
14839        return intent;
14840    }
14841
14842    public final int broadcastIntent(IApplicationThread caller,
14843            Intent intent, String resolvedType, IIntentReceiver resultTo,
14844            int resultCode, String resultData, Bundle map,
14845            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14846        enforceNotIsolatedCaller("broadcastIntent");
14847        synchronized(this) {
14848            intent = verifyBroadcastLocked(intent);
14849
14850            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14851            final int callingPid = Binder.getCallingPid();
14852            final int callingUid = Binder.getCallingUid();
14853            final long origId = Binder.clearCallingIdentity();
14854            int res = broadcastIntentLocked(callerApp,
14855                    callerApp != null ? callerApp.info.packageName : null,
14856                    intent, resolvedType, resultTo,
14857                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14858                    callingPid, callingUid, userId);
14859            Binder.restoreCallingIdentity(origId);
14860            return res;
14861        }
14862    }
14863
14864    int broadcastIntentInPackage(String packageName, int uid,
14865            Intent intent, String resolvedType, IIntentReceiver resultTo,
14866            int resultCode, String resultData, Bundle map,
14867            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14868        synchronized(this) {
14869            intent = verifyBroadcastLocked(intent);
14870
14871            final long origId = Binder.clearCallingIdentity();
14872            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14873                    resultTo, resultCode, resultData, map, requiredPermission,
14874                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14875            Binder.restoreCallingIdentity(origId);
14876            return res;
14877        }
14878    }
14879
14880    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14881        // Refuse possible leaked file descriptors
14882        if (intent != null && intent.hasFileDescriptors() == true) {
14883            throw new IllegalArgumentException("File descriptors passed in Intent");
14884        }
14885
14886        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14887                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14888
14889        synchronized(this) {
14890            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14891                    != PackageManager.PERMISSION_GRANTED) {
14892                String msg = "Permission Denial: unbroadcastIntent() from pid="
14893                        + Binder.getCallingPid()
14894                        + ", uid=" + Binder.getCallingUid()
14895                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14896                Slog.w(TAG, msg);
14897                throw new SecurityException(msg);
14898            }
14899            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14900            if (stickies != null) {
14901                ArrayList<Intent> list = stickies.get(intent.getAction());
14902                if (list != null) {
14903                    int N = list.size();
14904                    int i;
14905                    for (i=0; i<N; i++) {
14906                        if (intent.filterEquals(list.get(i))) {
14907                            list.remove(i);
14908                            break;
14909                        }
14910                    }
14911                    if (list.size() <= 0) {
14912                        stickies.remove(intent.getAction());
14913                    }
14914                }
14915                if (stickies.size() <= 0) {
14916                    mStickyBroadcasts.remove(userId);
14917                }
14918            }
14919        }
14920    }
14921
14922    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14923            String resultData, Bundle resultExtras, boolean resultAbort) {
14924        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14925        if (r == null) {
14926            Slog.w(TAG, "finishReceiver called but not found on queue");
14927            return false;
14928        }
14929
14930        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14931    }
14932
14933    void backgroundServicesFinishedLocked(int userId) {
14934        for (BroadcastQueue queue : mBroadcastQueues) {
14935            queue.backgroundServicesFinishedLocked(userId);
14936        }
14937    }
14938
14939    public void finishReceiver(IBinder who, int resultCode, String resultData,
14940            Bundle resultExtras, boolean resultAbort) {
14941        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14942
14943        // Refuse possible leaked file descriptors
14944        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14945            throw new IllegalArgumentException("File descriptors passed in Bundle");
14946        }
14947
14948        final long origId = Binder.clearCallingIdentity();
14949        try {
14950            boolean doNext = false;
14951            BroadcastRecord r;
14952
14953            synchronized(this) {
14954                r = broadcastRecordForReceiverLocked(who);
14955                if (r != null) {
14956                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14957                        resultData, resultExtras, resultAbort, true);
14958                }
14959            }
14960
14961            if (doNext) {
14962                r.queue.processNextBroadcast(false);
14963            }
14964            trimApplications();
14965        } finally {
14966            Binder.restoreCallingIdentity(origId);
14967        }
14968    }
14969
14970    // =========================================================
14971    // INSTRUMENTATION
14972    // =========================================================
14973
14974    public boolean startInstrumentation(ComponentName className,
14975            String profileFile, int flags, Bundle arguments,
14976            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14977            int userId, String abiOverride) {
14978        enforceNotIsolatedCaller("startInstrumentation");
14979        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14980                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14981        // Refuse possible leaked file descriptors
14982        if (arguments != null && arguments.hasFileDescriptors()) {
14983            throw new IllegalArgumentException("File descriptors passed in Bundle");
14984        }
14985
14986        synchronized(this) {
14987            InstrumentationInfo ii = null;
14988            ApplicationInfo ai = null;
14989            try {
14990                ii = mContext.getPackageManager().getInstrumentationInfo(
14991                    className, STOCK_PM_FLAGS);
14992                ai = AppGlobals.getPackageManager().getApplicationInfo(
14993                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14994            } catch (PackageManager.NameNotFoundException e) {
14995            } catch (RemoteException e) {
14996            }
14997            if (ii == null) {
14998                reportStartInstrumentationFailure(watcher, className,
14999                        "Unable to find instrumentation info for: " + className);
15000                return false;
15001            }
15002            if (ai == null) {
15003                reportStartInstrumentationFailure(watcher, className,
15004                        "Unable to find instrumentation target package: " + ii.targetPackage);
15005                return false;
15006            }
15007
15008            int match = mContext.getPackageManager().checkSignatures(
15009                    ii.targetPackage, ii.packageName);
15010            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15011                String msg = "Permission Denial: starting instrumentation "
15012                        + className + " from pid="
15013                        + Binder.getCallingPid()
15014                        + ", uid=" + Binder.getCallingPid()
15015                        + " not allowed because package " + ii.packageName
15016                        + " does not have a signature matching the target "
15017                        + ii.targetPackage;
15018                reportStartInstrumentationFailure(watcher, className, msg);
15019                throw new SecurityException(msg);
15020            }
15021
15022            final long origId = Binder.clearCallingIdentity();
15023            // Instrumentation can kill and relaunch even persistent processes
15024            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15025                    "start instr");
15026            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15027            app.instrumentationClass = className;
15028            app.instrumentationInfo = ai;
15029            app.instrumentationProfileFile = profileFile;
15030            app.instrumentationArguments = arguments;
15031            app.instrumentationWatcher = watcher;
15032            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15033            app.instrumentationResultClass = className;
15034            Binder.restoreCallingIdentity(origId);
15035        }
15036
15037        return true;
15038    }
15039
15040    /**
15041     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15042     * error to the logs, but if somebody is watching, send the report there too.  This enables
15043     * the "am" command to report errors with more information.
15044     *
15045     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15046     * @param cn The component name of the instrumentation.
15047     * @param report The error report.
15048     */
15049    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15050            ComponentName cn, String report) {
15051        Slog.w(TAG, report);
15052        try {
15053            if (watcher != null) {
15054                Bundle results = new Bundle();
15055                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15056                results.putString("Error", report);
15057                watcher.instrumentationStatus(cn, -1, results);
15058            }
15059        } catch (RemoteException e) {
15060            Slog.w(TAG, e);
15061        }
15062    }
15063
15064    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15065        if (app.instrumentationWatcher != null) {
15066            try {
15067                // NOTE:  IInstrumentationWatcher *must* be oneway here
15068                app.instrumentationWatcher.instrumentationFinished(
15069                    app.instrumentationClass,
15070                    resultCode,
15071                    results);
15072            } catch (RemoteException e) {
15073            }
15074        }
15075        if (app.instrumentationUiAutomationConnection != null) {
15076            try {
15077                app.instrumentationUiAutomationConnection.shutdown();
15078            } catch (RemoteException re) {
15079                /* ignore */
15080            }
15081            // Only a UiAutomation can set this flag and now that
15082            // it is finished we make sure it is reset to its default.
15083            mUserIsMonkey = false;
15084        }
15085        app.instrumentationWatcher = null;
15086        app.instrumentationUiAutomationConnection = null;
15087        app.instrumentationClass = null;
15088        app.instrumentationInfo = null;
15089        app.instrumentationProfileFile = null;
15090        app.instrumentationArguments = null;
15091
15092        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15093                "finished inst");
15094    }
15095
15096    public void finishInstrumentation(IApplicationThread target,
15097            int resultCode, Bundle results) {
15098        int userId = UserHandle.getCallingUserId();
15099        // Refuse possible leaked file descriptors
15100        if (results != null && results.hasFileDescriptors()) {
15101            throw new IllegalArgumentException("File descriptors passed in Intent");
15102        }
15103
15104        synchronized(this) {
15105            ProcessRecord app = getRecordForAppLocked(target);
15106            if (app == null) {
15107                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15108                return;
15109            }
15110            final long origId = Binder.clearCallingIdentity();
15111            finishInstrumentationLocked(app, resultCode, results);
15112            Binder.restoreCallingIdentity(origId);
15113        }
15114    }
15115
15116    // =========================================================
15117    // CONFIGURATION
15118    // =========================================================
15119
15120    public ConfigurationInfo getDeviceConfigurationInfo() {
15121        ConfigurationInfo config = new ConfigurationInfo();
15122        synchronized (this) {
15123            config.reqTouchScreen = mConfiguration.touchscreen;
15124            config.reqKeyboardType = mConfiguration.keyboard;
15125            config.reqNavigation = mConfiguration.navigation;
15126            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15127                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15128                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15129            }
15130            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15131                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15132                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15133            }
15134            config.reqGlEsVersion = GL_ES_VERSION;
15135        }
15136        return config;
15137    }
15138
15139    ActivityStack getFocusedStack() {
15140        return mStackSupervisor.getFocusedStack();
15141    }
15142
15143    public Configuration getConfiguration() {
15144        Configuration ci;
15145        synchronized(this) {
15146            ci = new Configuration(mConfiguration);
15147        }
15148        return ci;
15149    }
15150
15151    public void updatePersistentConfiguration(Configuration values) {
15152        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15153                "updateConfiguration()");
15154        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15155                "updateConfiguration()");
15156        if (values == null) {
15157            throw new NullPointerException("Configuration must not be null");
15158        }
15159
15160        synchronized(this) {
15161            final long origId = Binder.clearCallingIdentity();
15162            updateConfigurationLocked(values, null, true, false);
15163            Binder.restoreCallingIdentity(origId);
15164        }
15165    }
15166
15167    public void updateConfiguration(Configuration values) {
15168        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15169                "updateConfiguration()");
15170
15171        synchronized(this) {
15172            if (values == null && mWindowManager != null) {
15173                // sentinel: fetch the current configuration from the window manager
15174                values = mWindowManager.computeNewConfiguration();
15175            }
15176
15177            if (mWindowManager != null) {
15178                mProcessList.applyDisplaySize(mWindowManager);
15179            }
15180
15181            final long origId = Binder.clearCallingIdentity();
15182            if (values != null) {
15183                Settings.System.clearConfiguration(values);
15184            }
15185            updateConfigurationLocked(values, null, false, false);
15186            Binder.restoreCallingIdentity(origId);
15187        }
15188    }
15189
15190    /**
15191     * Do either or both things: (1) change the current configuration, and (2)
15192     * make sure the given activity is running with the (now) current
15193     * configuration.  Returns true if the activity has been left running, or
15194     * false if <var>starting</var> is being destroyed to match the new
15195     * configuration.
15196     * @param persistent TODO
15197     */
15198    boolean updateConfigurationLocked(Configuration values,
15199            ActivityRecord starting, boolean persistent, boolean initLocale) {
15200        int changes = 0;
15201
15202        if (values != null) {
15203            Configuration newConfig = new Configuration(mConfiguration);
15204            changes = newConfig.updateFrom(values);
15205            if (changes != 0) {
15206                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15207                    Slog.i(TAG, "Updating configuration to: " + values);
15208                }
15209
15210                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15211
15212                if (values.locale != null && !initLocale) {
15213                    saveLocaleLocked(values.locale,
15214                                     !values.locale.equals(mConfiguration.locale),
15215                                     values.userSetLocale);
15216                }
15217
15218                mConfigurationSeq++;
15219                if (mConfigurationSeq <= 0) {
15220                    mConfigurationSeq = 1;
15221                }
15222                newConfig.seq = mConfigurationSeq;
15223                mConfiguration = newConfig;
15224                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15225                //mUsageStatsService.noteStartConfig(newConfig);
15226
15227                final Configuration configCopy = new Configuration(mConfiguration);
15228
15229                // TODO: If our config changes, should we auto dismiss any currently
15230                // showing dialogs?
15231                mShowDialogs = shouldShowDialogs(newConfig);
15232
15233                AttributeCache ac = AttributeCache.instance();
15234                if (ac != null) {
15235                    ac.updateConfiguration(configCopy);
15236                }
15237
15238                // Make sure all resources in our process are updated
15239                // right now, so that anyone who is going to retrieve
15240                // resource values after we return will be sure to get
15241                // the new ones.  This is especially important during
15242                // boot, where the first config change needs to guarantee
15243                // all resources have that config before following boot
15244                // code is executed.
15245                mSystemThread.applyConfigurationToResources(configCopy);
15246
15247                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15248                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15249                    msg.obj = new Configuration(configCopy);
15250                    mHandler.sendMessage(msg);
15251                }
15252
15253                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15254                    ProcessRecord app = mLruProcesses.get(i);
15255                    try {
15256                        if (app.thread != null) {
15257                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15258                                    + app.processName + " new config " + mConfiguration);
15259                            app.thread.scheduleConfigurationChanged(configCopy);
15260                        }
15261                    } catch (Exception e) {
15262                    }
15263                }
15264                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15265                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15266                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15267                        | Intent.FLAG_RECEIVER_FOREGROUND);
15268                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15269                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15270                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15271                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15272                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15273                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15274                    broadcastIntentLocked(null, null, intent,
15275                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15276                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15277                }
15278            }
15279        }
15280
15281        boolean kept = true;
15282        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15283        // mainStack is null during startup.
15284        if (mainStack != null) {
15285            if (changes != 0 && starting == null) {
15286                // If the configuration changed, and the caller is not already
15287                // in the process of starting an activity, then find the top
15288                // activity to check if its configuration needs to change.
15289                starting = mainStack.topRunningActivityLocked(null);
15290            }
15291
15292            if (starting != null) {
15293                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15294                // And we need to make sure at this point that all other activities
15295                // are made visible with the correct configuration.
15296                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15297            }
15298        }
15299
15300        if (values != null && mWindowManager != null) {
15301            mWindowManager.setNewConfiguration(mConfiguration);
15302        }
15303
15304        return kept;
15305    }
15306
15307    /**
15308     * Decide based on the configuration whether we should shouw the ANR,
15309     * crash, etc dialogs.  The idea is that if there is no affordnace to
15310     * press the on-screen buttons, we shouldn't show the dialog.
15311     *
15312     * A thought: SystemUI might also want to get told about this, the Power
15313     * dialog / global actions also might want different behaviors.
15314     */
15315    private static final boolean shouldShowDialogs(Configuration config) {
15316        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15317                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15318    }
15319
15320    /**
15321     * Save the locale.  You must be inside a synchronized (this) block.
15322     */
15323    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15324        if(isDiff) {
15325            SystemProperties.set("user.language", l.getLanguage());
15326            SystemProperties.set("user.region", l.getCountry());
15327        }
15328
15329        if(isPersist) {
15330            SystemProperties.set("persist.sys.language", l.getLanguage());
15331            SystemProperties.set("persist.sys.country", l.getCountry());
15332            SystemProperties.set("persist.sys.localevar", l.getVariant());
15333        }
15334    }
15335
15336    @Override
15337    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15338        ActivityRecord srec = ActivityRecord.forToken(token);
15339        return srec != null && srec.task.affinity != null &&
15340                srec.task.affinity.equals(destAffinity);
15341    }
15342
15343    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15344            Intent resultData) {
15345
15346        synchronized (this) {
15347            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15348            if (stack != null) {
15349                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15350            }
15351            return false;
15352        }
15353    }
15354
15355    public int getLaunchedFromUid(IBinder activityToken) {
15356        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15357        if (srec == null) {
15358            return -1;
15359        }
15360        return srec.launchedFromUid;
15361    }
15362
15363    public String getLaunchedFromPackage(IBinder activityToken) {
15364        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15365        if (srec == null) {
15366            return null;
15367        }
15368        return srec.launchedFromPackage;
15369    }
15370
15371    // =========================================================
15372    // LIFETIME MANAGEMENT
15373    // =========================================================
15374
15375    // Returns which broadcast queue the app is the current [or imminent] receiver
15376    // on, or 'null' if the app is not an active broadcast recipient.
15377    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15378        BroadcastRecord r = app.curReceiver;
15379        if (r != null) {
15380            return r.queue;
15381        }
15382
15383        // It's not the current receiver, but it might be starting up to become one
15384        synchronized (this) {
15385            for (BroadcastQueue queue : mBroadcastQueues) {
15386                r = queue.mPendingBroadcast;
15387                if (r != null && r.curApp == app) {
15388                    // found it; report which queue it's in
15389                    return queue;
15390                }
15391            }
15392        }
15393
15394        return null;
15395    }
15396
15397    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15398            boolean doingAll, long now) {
15399        if (mAdjSeq == app.adjSeq) {
15400            // This adjustment has already been computed.
15401            return app.curRawAdj;
15402        }
15403
15404        if (app.thread == null) {
15405            app.adjSeq = mAdjSeq;
15406            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15407            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15408            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15409        }
15410
15411        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15412        app.adjSource = null;
15413        app.adjTarget = null;
15414        app.empty = false;
15415        app.cached = false;
15416
15417        final int activitiesSize = app.activities.size();
15418
15419        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15420            // The max adjustment doesn't allow this app to be anything
15421            // below foreground, so it is not worth doing work for it.
15422            app.adjType = "fixed";
15423            app.adjSeq = mAdjSeq;
15424            app.curRawAdj = app.maxAdj;
15425            app.foregroundActivities = false;
15426            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15427            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15428            // System processes can do UI, and when they do we want to have
15429            // them trim their memory after the user leaves the UI.  To
15430            // facilitate this, here we need to determine whether or not it
15431            // is currently showing UI.
15432            app.systemNoUi = true;
15433            if (app == TOP_APP) {
15434                app.systemNoUi = false;
15435            } else if (activitiesSize > 0) {
15436                for (int j = 0; j < activitiesSize; j++) {
15437                    final ActivityRecord r = app.activities.get(j);
15438                    if (r.visible) {
15439                        app.systemNoUi = false;
15440                    }
15441                }
15442            }
15443            if (!app.systemNoUi) {
15444                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15445            }
15446            return (app.curAdj=app.maxAdj);
15447        }
15448
15449        app.systemNoUi = false;
15450
15451        // Determine the importance of the process, starting with most
15452        // important to least, and assign an appropriate OOM adjustment.
15453        int adj;
15454        int schedGroup;
15455        int procState;
15456        boolean foregroundActivities = false;
15457        BroadcastQueue queue;
15458        if (app == TOP_APP) {
15459            // The last app on the list is the foreground app.
15460            adj = ProcessList.FOREGROUND_APP_ADJ;
15461            schedGroup = Process.THREAD_GROUP_DEFAULT;
15462            app.adjType = "top-activity";
15463            foregroundActivities = true;
15464            procState = ActivityManager.PROCESS_STATE_TOP;
15465        } else if (app.instrumentationClass != null) {
15466            // Don't want to kill running instrumentation.
15467            adj = ProcessList.FOREGROUND_APP_ADJ;
15468            schedGroup = Process.THREAD_GROUP_DEFAULT;
15469            app.adjType = "instrumentation";
15470            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15471        } else if ((queue = isReceivingBroadcast(app)) != null) {
15472            // An app that is currently receiving a broadcast also
15473            // counts as being in the foreground for OOM killer purposes.
15474            // It's placed in a sched group based on the nature of the
15475            // broadcast as reflected by which queue it's active in.
15476            adj = ProcessList.FOREGROUND_APP_ADJ;
15477            schedGroup = (queue == mFgBroadcastQueue)
15478                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15479            app.adjType = "broadcast";
15480            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15481        } else if (app.executingServices.size() > 0) {
15482            // An app that is currently executing a service callback also
15483            // counts as being in the foreground.
15484            adj = ProcessList.FOREGROUND_APP_ADJ;
15485            schedGroup = app.execServicesFg ?
15486                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15487            app.adjType = "exec-service";
15488            procState = ActivityManager.PROCESS_STATE_SERVICE;
15489            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15490        } else {
15491            // As far as we know the process is empty.  We may change our mind later.
15492            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15493            // At this point we don't actually know the adjustment.  Use the cached adj
15494            // value that the caller wants us to.
15495            adj = cachedAdj;
15496            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15497            app.cached = true;
15498            app.empty = true;
15499            app.adjType = "cch-empty";
15500        }
15501
15502        // Examine all activities if not already foreground.
15503        if (!foregroundActivities && activitiesSize > 0) {
15504            for (int j = 0; j < activitiesSize; j++) {
15505                final ActivityRecord r = app.activities.get(j);
15506                if (r.app != app) {
15507                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15508                            + app + "?!?");
15509                    continue;
15510                }
15511                if (r.visible) {
15512                    // App has a visible activity; only upgrade adjustment.
15513                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15514                        adj = ProcessList.VISIBLE_APP_ADJ;
15515                        app.adjType = "visible";
15516                    }
15517                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15518                        procState = ActivityManager.PROCESS_STATE_TOP;
15519                    }
15520                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15521                    app.cached = false;
15522                    app.empty = false;
15523                    foregroundActivities = true;
15524                    break;
15525                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15526                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15527                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15528                        app.adjType = "pausing";
15529                    }
15530                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15531                        procState = ActivityManager.PROCESS_STATE_TOP;
15532                    }
15533                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15534                    app.cached = false;
15535                    app.empty = false;
15536                    foregroundActivities = true;
15537                } else if (r.state == ActivityState.STOPPING) {
15538                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15539                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15540                        app.adjType = "stopping";
15541                    }
15542                    // For the process state, we will at this point consider the
15543                    // process to be cached.  It will be cached either as an activity
15544                    // or empty depending on whether the activity is finishing.  We do
15545                    // this so that we can treat the process as cached for purposes of
15546                    // memory trimming (determing current memory level, trim command to
15547                    // send to process) since there can be an arbitrary number of stopping
15548                    // processes and they should soon all go into the cached state.
15549                    if (!r.finishing) {
15550                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15551                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15552                        }
15553                    }
15554                    app.cached = false;
15555                    app.empty = false;
15556                    foregroundActivities = true;
15557                } else {
15558                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15559                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15560                        app.adjType = "cch-act";
15561                    }
15562                }
15563            }
15564        }
15565
15566        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15567            if (app.foregroundServices) {
15568                // The user is aware of this app, so make it visible.
15569                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15570                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15571                app.cached = false;
15572                app.adjType = "fg-service";
15573                schedGroup = Process.THREAD_GROUP_DEFAULT;
15574            } else if (app.forcingToForeground != null) {
15575                // The user is aware of this app, so make it visible.
15576                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15577                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15578                app.cached = false;
15579                app.adjType = "force-fg";
15580                app.adjSource = app.forcingToForeground;
15581                schedGroup = Process.THREAD_GROUP_DEFAULT;
15582            }
15583        }
15584
15585        if (app == mHeavyWeightProcess) {
15586            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15587                // We don't want to kill the current heavy-weight process.
15588                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15589                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15590                app.cached = false;
15591                app.adjType = "heavy";
15592            }
15593            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15594                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15595            }
15596        }
15597
15598        if (app == mHomeProcess) {
15599            if (adj > ProcessList.HOME_APP_ADJ) {
15600                // This process is hosting what we currently consider to be the
15601                // home app, so we don't want to let it go into the background.
15602                adj = ProcessList.HOME_APP_ADJ;
15603                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15604                app.cached = false;
15605                app.adjType = "home";
15606            }
15607            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15608                procState = ActivityManager.PROCESS_STATE_HOME;
15609            }
15610        }
15611
15612        if (app == mPreviousProcess && app.activities.size() > 0) {
15613            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15614                // This was the previous process that showed UI to the user.
15615                // We want to try to keep it around more aggressively, to give
15616                // a good experience around switching between two apps.
15617                adj = ProcessList.PREVIOUS_APP_ADJ;
15618                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15619                app.cached = false;
15620                app.adjType = "previous";
15621            }
15622            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15623                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15624            }
15625        }
15626
15627        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15628                + " reason=" + app.adjType);
15629
15630        // By default, we use the computed adjustment.  It may be changed if
15631        // there are applications dependent on our services or providers, but
15632        // this gives us a baseline and makes sure we don't get into an
15633        // infinite recursion.
15634        app.adjSeq = mAdjSeq;
15635        app.curRawAdj = adj;
15636        app.hasStartedServices = false;
15637
15638        if (mBackupTarget != null && app == mBackupTarget.app) {
15639            // If possible we want to avoid killing apps while they're being backed up
15640            if (adj > ProcessList.BACKUP_APP_ADJ) {
15641                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15642                adj = ProcessList.BACKUP_APP_ADJ;
15643                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15644                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15645                }
15646                app.adjType = "backup";
15647                app.cached = false;
15648            }
15649            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15650                procState = ActivityManager.PROCESS_STATE_BACKUP;
15651            }
15652        }
15653
15654        boolean mayBeTop = false;
15655
15656        for (int is = app.services.size()-1;
15657                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15658                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15659                        || procState > ActivityManager.PROCESS_STATE_TOP);
15660                is--) {
15661            ServiceRecord s = app.services.valueAt(is);
15662            if (s.startRequested) {
15663                app.hasStartedServices = true;
15664                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15665                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15666                }
15667                if (app.hasShownUi && app != mHomeProcess) {
15668                    // If this process has shown some UI, let it immediately
15669                    // go to the LRU list because it may be pretty heavy with
15670                    // UI stuff.  We'll tag it with a label just to help
15671                    // debug and understand what is going on.
15672                    if (adj > ProcessList.SERVICE_ADJ) {
15673                        app.adjType = "cch-started-ui-services";
15674                    }
15675                } else {
15676                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15677                        // This service has seen some activity within
15678                        // recent memory, so we will keep its process ahead
15679                        // of the background processes.
15680                        if (adj > ProcessList.SERVICE_ADJ) {
15681                            adj = ProcessList.SERVICE_ADJ;
15682                            app.adjType = "started-services";
15683                            app.cached = false;
15684                        }
15685                    }
15686                    // If we have let the service slide into the background
15687                    // state, still have some text describing what it is doing
15688                    // even though the service no longer has an impact.
15689                    if (adj > ProcessList.SERVICE_ADJ) {
15690                        app.adjType = "cch-started-services";
15691                    }
15692                }
15693            }
15694            for (int conni = s.connections.size()-1;
15695                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15696                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15697                            || procState > ActivityManager.PROCESS_STATE_TOP);
15698                    conni--) {
15699                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15700                for (int i = 0;
15701                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15702                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15703                                || procState > ActivityManager.PROCESS_STATE_TOP);
15704                        i++) {
15705                    // XXX should compute this based on the max of
15706                    // all connected clients.
15707                    ConnectionRecord cr = clist.get(i);
15708                    if (cr.binding.client == app) {
15709                        // Binding to ourself is not interesting.
15710                        continue;
15711                    }
15712                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15713                        ProcessRecord client = cr.binding.client;
15714                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15715                                TOP_APP, doingAll, now);
15716                        int clientProcState = client.curProcState;
15717                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15718                            // If the other app is cached for any reason, for purposes here
15719                            // we are going to consider it empty.  The specific cached state
15720                            // doesn't propagate except under certain conditions.
15721                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15722                        }
15723                        String adjType = null;
15724                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15725                            // Not doing bind OOM management, so treat
15726                            // this guy more like a started service.
15727                            if (app.hasShownUi && app != mHomeProcess) {
15728                                // If this process has shown some UI, let it immediately
15729                                // go to the LRU list because it may be pretty heavy with
15730                                // UI stuff.  We'll tag it with a label just to help
15731                                // debug and understand what is going on.
15732                                if (adj > clientAdj) {
15733                                    adjType = "cch-bound-ui-services";
15734                                }
15735                                app.cached = false;
15736                                clientAdj = adj;
15737                                clientProcState = procState;
15738                            } else {
15739                                if (now >= (s.lastActivity
15740                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15741                                    // This service has not seen activity within
15742                                    // recent memory, so allow it to drop to the
15743                                    // LRU list if there is no other reason to keep
15744                                    // it around.  We'll also tag it with a label just
15745                                    // to help debug and undertand what is going on.
15746                                    if (adj > clientAdj) {
15747                                        adjType = "cch-bound-services";
15748                                    }
15749                                    clientAdj = adj;
15750                                }
15751                            }
15752                        }
15753                        if (adj > clientAdj) {
15754                            // If this process has recently shown UI, and
15755                            // the process that is binding to it is less
15756                            // important than being visible, then we don't
15757                            // care about the binding as much as we care
15758                            // about letting this process get into the LRU
15759                            // list to be killed and restarted if needed for
15760                            // memory.
15761                            if (app.hasShownUi && app != mHomeProcess
15762                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15763                                adjType = "cch-bound-ui-services";
15764                            } else {
15765                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15766                                        |Context.BIND_IMPORTANT)) != 0) {
15767                                    adj = clientAdj;
15768                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15769                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15770                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15771                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15772                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15773                                    adj = clientAdj;
15774                                } else {
15775                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15776                                        adj = ProcessList.VISIBLE_APP_ADJ;
15777                                    }
15778                                }
15779                                if (!client.cached) {
15780                                    app.cached = false;
15781                                }
15782                                adjType = "service";
15783                            }
15784                        }
15785                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15786                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15787                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15788                            }
15789                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15790                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15791                                    // Special handling of clients who are in the top state.
15792                                    // We *may* want to consider this process to be in the
15793                                    // top state as well, but only if there is not another
15794                                    // reason for it to be running.  Being on the top is a
15795                                    // special state, meaning you are specifically running
15796                                    // for the current top app.  If the process is already
15797                                    // running in the background for some other reason, it
15798                                    // is more important to continue considering it to be
15799                                    // in the background state.
15800                                    mayBeTop = true;
15801                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15802                                } else {
15803                                    // Special handling for above-top states (persistent
15804                                    // processes).  These should not bring the current process
15805                                    // into the top state, since they are not on top.  Instead
15806                                    // give them the best state after that.
15807                                    clientProcState =
15808                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15809                                }
15810                            }
15811                        } else {
15812                            if (clientProcState <
15813                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15814                                clientProcState =
15815                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15816                            }
15817                        }
15818                        if (procState > clientProcState) {
15819                            procState = clientProcState;
15820                        }
15821                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15822                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15823                            app.pendingUiClean = true;
15824                        }
15825                        if (adjType != null) {
15826                            app.adjType = adjType;
15827                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15828                                    .REASON_SERVICE_IN_USE;
15829                            app.adjSource = cr.binding.client;
15830                            app.adjSourceProcState = clientProcState;
15831                            app.adjTarget = s.name;
15832                        }
15833                    }
15834                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15835                        app.treatLikeActivity = true;
15836                    }
15837                    final ActivityRecord a = cr.activity;
15838                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15839                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15840                                (a.visible || a.state == ActivityState.RESUMED
15841                                 || a.state == ActivityState.PAUSING)) {
15842                            adj = ProcessList.FOREGROUND_APP_ADJ;
15843                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15844                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15845                            }
15846                            app.cached = false;
15847                            app.adjType = "service";
15848                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15849                                    .REASON_SERVICE_IN_USE;
15850                            app.adjSource = a;
15851                            app.adjSourceProcState = procState;
15852                            app.adjTarget = s.name;
15853                        }
15854                    }
15855                }
15856            }
15857        }
15858
15859        for (int provi = app.pubProviders.size()-1;
15860                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15861                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15862                        || procState > ActivityManager.PROCESS_STATE_TOP);
15863                provi--) {
15864            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15865            for (int i = cpr.connections.size()-1;
15866                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15867                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15868                            || procState > ActivityManager.PROCESS_STATE_TOP);
15869                    i--) {
15870                ContentProviderConnection conn = cpr.connections.get(i);
15871                ProcessRecord client = conn.client;
15872                if (client == app) {
15873                    // Being our own client is not interesting.
15874                    continue;
15875                }
15876                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15877                int clientProcState = client.curProcState;
15878                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15879                    // If the other app is cached for any reason, for purposes here
15880                    // we are going to consider it empty.
15881                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15882                }
15883                if (adj > clientAdj) {
15884                    if (app.hasShownUi && app != mHomeProcess
15885                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15886                        app.adjType = "cch-ui-provider";
15887                    } else {
15888                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15889                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15890                        app.adjType = "provider";
15891                    }
15892                    app.cached &= client.cached;
15893                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15894                            .REASON_PROVIDER_IN_USE;
15895                    app.adjSource = client;
15896                    app.adjSourceProcState = clientProcState;
15897                    app.adjTarget = cpr.name;
15898                }
15899                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15900                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15901                        // Special handling of clients who are in the top state.
15902                        // We *may* want to consider this process to be in the
15903                        // top state as well, but only if there is not another
15904                        // reason for it to be running.  Being on the top is a
15905                        // special state, meaning you are specifically running
15906                        // for the current top app.  If the process is already
15907                        // running in the background for some other reason, it
15908                        // is more important to continue considering it to be
15909                        // in the background state.
15910                        mayBeTop = true;
15911                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15912                    } else {
15913                        // Special handling for above-top states (persistent
15914                        // processes).  These should not bring the current process
15915                        // into the top state, since they are not on top.  Instead
15916                        // give them the best state after that.
15917                        clientProcState =
15918                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15919                    }
15920                }
15921                if (procState > clientProcState) {
15922                    procState = clientProcState;
15923                }
15924                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15925                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15926                }
15927            }
15928            // If the provider has external (non-framework) process
15929            // dependencies, ensure that its adjustment is at least
15930            // FOREGROUND_APP_ADJ.
15931            if (cpr.hasExternalProcessHandles()) {
15932                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15933                    adj = ProcessList.FOREGROUND_APP_ADJ;
15934                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15935                    app.cached = false;
15936                    app.adjType = "provider";
15937                    app.adjTarget = cpr.name;
15938                }
15939                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15940                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15941                }
15942            }
15943        }
15944
15945        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15946            // A client of one of our services or providers is in the top state.  We
15947            // *may* want to be in the top state, but not if we are already running in
15948            // the background for some other reason.  For the decision here, we are going
15949            // to pick out a few specific states that we want to remain in when a client
15950            // is top (states that tend to be longer-term) and otherwise allow it to go
15951            // to the top state.
15952            switch (procState) {
15953                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15954                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15955                case ActivityManager.PROCESS_STATE_SERVICE:
15956                    // These all are longer-term states, so pull them up to the top
15957                    // of the background states, but not all the way to the top state.
15958                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15959                    break;
15960                default:
15961                    // Otherwise, top is a better choice, so take it.
15962                    procState = ActivityManager.PROCESS_STATE_TOP;
15963                    break;
15964            }
15965        }
15966
15967        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15968            if (app.hasClientActivities) {
15969                // This is a cached process, but with client activities.  Mark it so.
15970                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15971                app.adjType = "cch-client-act";
15972            } else if (app.treatLikeActivity) {
15973                // This is a cached process, but somebody wants us to treat it like it has
15974                // an activity, okay!
15975                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15976                app.adjType = "cch-as-act";
15977            }
15978        }
15979
15980        if (adj == ProcessList.SERVICE_ADJ) {
15981            if (doingAll) {
15982                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15983                mNewNumServiceProcs++;
15984                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15985                if (!app.serviceb) {
15986                    // This service isn't far enough down on the LRU list to
15987                    // normally be a B service, but if we are low on RAM and it
15988                    // is large we want to force it down since we would prefer to
15989                    // keep launcher over it.
15990                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15991                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15992                        app.serviceHighRam = true;
15993                        app.serviceb = true;
15994                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15995                    } else {
15996                        mNewNumAServiceProcs++;
15997                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15998                    }
15999                } else {
16000                    app.serviceHighRam = false;
16001                }
16002            }
16003            if (app.serviceb) {
16004                adj = ProcessList.SERVICE_B_ADJ;
16005            }
16006        }
16007
16008        app.curRawAdj = adj;
16009
16010        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16011        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16012        if (adj > app.maxAdj) {
16013            adj = app.maxAdj;
16014            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16015                schedGroup = Process.THREAD_GROUP_DEFAULT;
16016            }
16017        }
16018
16019        // Do final modification to adj.  Everything we do between here and applying
16020        // the final setAdj must be done in this function, because we will also use
16021        // it when computing the final cached adj later.  Note that we don't need to
16022        // worry about this for max adj above, since max adj will always be used to
16023        // keep it out of the cached vaues.
16024        app.curAdj = app.modifyRawOomAdj(adj);
16025        app.curSchedGroup = schedGroup;
16026        app.curProcState = procState;
16027        app.foregroundActivities = foregroundActivities;
16028
16029        return app.curRawAdj;
16030    }
16031
16032    /**
16033     * Schedule PSS collection of a process.
16034     */
16035    void requestPssLocked(ProcessRecord proc, int procState) {
16036        if (mPendingPssProcesses.contains(proc)) {
16037            return;
16038        }
16039        if (mPendingPssProcesses.size() == 0) {
16040            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16041        }
16042        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16043        proc.pssProcState = procState;
16044        mPendingPssProcesses.add(proc);
16045    }
16046
16047    /**
16048     * Schedule PSS collection of all processes.
16049     */
16050    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16051        if (!always) {
16052            if (now < (mLastFullPssTime +
16053                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16054                return;
16055            }
16056        }
16057        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16058        mLastFullPssTime = now;
16059        mFullPssPending = true;
16060        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16061        mPendingPssProcesses.clear();
16062        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16063            ProcessRecord app = mLruProcesses.get(i);
16064            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16065                app.pssProcState = app.setProcState;
16066                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16067                        isSleeping(), now);
16068                mPendingPssProcesses.add(app);
16069            }
16070        }
16071        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16072    }
16073
16074    /**
16075     * Ask a given process to GC right now.
16076     */
16077    final void performAppGcLocked(ProcessRecord app) {
16078        try {
16079            app.lastRequestedGc = SystemClock.uptimeMillis();
16080            if (app.thread != null) {
16081                if (app.reportLowMemory) {
16082                    app.reportLowMemory = false;
16083                    app.thread.scheduleLowMemory();
16084                } else {
16085                    app.thread.processInBackground();
16086                }
16087            }
16088        } catch (Exception e) {
16089            // whatever.
16090        }
16091    }
16092
16093    /**
16094     * Returns true if things are idle enough to perform GCs.
16095     */
16096    private final boolean canGcNowLocked() {
16097        boolean processingBroadcasts = false;
16098        for (BroadcastQueue q : mBroadcastQueues) {
16099            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16100                processingBroadcasts = true;
16101            }
16102        }
16103        return !processingBroadcasts
16104                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16105    }
16106
16107    /**
16108     * Perform GCs on all processes that are waiting for it, but only
16109     * if things are idle.
16110     */
16111    final void performAppGcsLocked() {
16112        final int N = mProcessesToGc.size();
16113        if (N <= 0) {
16114            return;
16115        }
16116        if (canGcNowLocked()) {
16117            while (mProcessesToGc.size() > 0) {
16118                ProcessRecord proc = mProcessesToGc.remove(0);
16119                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16120                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16121                            <= SystemClock.uptimeMillis()) {
16122                        // To avoid spamming the system, we will GC processes one
16123                        // at a time, waiting a few seconds between each.
16124                        performAppGcLocked(proc);
16125                        scheduleAppGcsLocked();
16126                        return;
16127                    } else {
16128                        // It hasn't been long enough since we last GCed this
16129                        // process...  put it in the list to wait for its time.
16130                        addProcessToGcListLocked(proc);
16131                        break;
16132                    }
16133                }
16134            }
16135
16136            scheduleAppGcsLocked();
16137        }
16138    }
16139
16140    /**
16141     * If all looks good, perform GCs on all processes waiting for them.
16142     */
16143    final void performAppGcsIfAppropriateLocked() {
16144        if (canGcNowLocked()) {
16145            performAppGcsLocked();
16146            return;
16147        }
16148        // Still not idle, wait some more.
16149        scheduleAppGcsLocked();
16150    }
16151
16152    /**
16153     * Schedule the execution of all pending app GCs.
16154     */
16155    final void scheduleAppGcsLocked() {
16156        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16157
16158        if (mProcessesToGc.size() > 0) {
16159            // Schedule a GC for the time to the next process.
16160            ProcessRecord proc = mProcessesToGc.get(0);
16161            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16162
16163            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16164            long now = SystemClock.uptimeMillis();
16165            if (when < (now+GC_TIMEOUT)) {
16166                when = now + GC_TIMEOUT;
16167            }
16168            mHandler.sendMessageAtTime(msg, when);
16169        }
16170    }
16171
16172    /**
16173     * Add a process to the array of processes waiting to be GCed.  Keeps the
16174     * list in sorted order by the last GC time.  The process can't already be
16175     * on the list.
16176     */
16177    final void addProcessToGcListLocked(ProcessRecord proc) {
16178        boolean added = false;
16179        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16180            if (mProcessesToGc.get(i).lastRequestedGc <
16181                    proc.lastRequestedGc) {
16182                added = true;
16183                mProcessesToGc.add(i+1, proc);
16184                break;
16185            }
16186        }
16187        if (!added) {
16188            mProcessesToGc.add(0, proc);
16189        }
16190    }
16191
16192    /**
16193     * Set up to ask a process to GC itself.  This will either do it
16194     * immediately, or put it on the list of processes to gc the next
16195     * time things are idle.
16196     */
16197    final void scheduleAppGcLocked(ProcessRecord app) {
16198        long now = SystemClock.uptimeMillis();
16199        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16200            return;
16201        }
16202        if (!mProcessesToGc.contains(app)) {
16203            addProcessToGcListLocked(app);
16204            scheduleAppGcsLocked();
16205        }
16206    }
16207
16208    final void checkExcessivePowerUsageLocked(boolean doKills) {
16209        updateCpuStatsNow();
16210
16211        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16212        boolean doWakeKills = doKills;
16213        boolean doCpuKills = doKills;
16214        if (mLastPowerCheckRealtime == 0) {
16215            doWakeKills = false;
16216        }
16217        if (mLastPowerCheckUptime == 0) {
16218            doCpuKills = false;
16219        }
16220        if (stats.isScreenOn()) {
16221            doWakeKills = false;
16222        }
16223        final long curRealtime = SystemClock.elapsedRealtime();
16224        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16225        final long curUptime = SystemClock.uptimeMillis();
16226        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16227        mLastPowerCheckRealtime = curRealtime;
16228        mLastPowerCheckUptime = curUptime;
16229        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16230            doWakeKills = false;
16231        }
16232        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16233            doCpuKills = false;
16234        }
16235        int i = mLruProcesses.size();
16236        while (i > 0) {
16237            i--;
16238            ProcessRecord app = mLruProcesses.get(i);
16239            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16240                long wtime;
16241                synchronized (stats) {
16242                    wtime = stats.getProcessWakeTime(app.info.uid,
16243                            app.pid, curRealtime);
16244                }
16245                long wtimeUsed = wtime - app.lastWakeTime;
16246                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16247                if (DEBUG_POWER) {
16248                    StringBuilder sb = new StringBuilder(128);
16249                    sb.append("Wake for ");
16250                    app.toShortString(sb);
16251                    sb.append(": over ");
16252                    TimeUtils.formatDuration(realtimeSince, sb);
16253                    sb.append(" used ");
16254                    TimeUtils.formatDuration(wtimeUsed, sb);
16255                    sb.append(" (");
16256                    sb.append((wtimeUsed*100)/realtimeSince);
16257                    sb.append("%)");
16258                    Slog.i(TAG, sb.toString());
16259                    sb.setLength(0);
16260                    sb.append("CPU for ");
16261                    app.toShortString(sb);
16262                    sb.append(": over ");
16263                    TimeUtils.formatDuration(uptimeSince, sb);
16264                    sb.append(" used ");
16265                    TimeUtils.formatDuration(cputimeUsed, sb);
16266                    sb.append(" (");
16267                    sb.append((cputimeUsed*100)/uptimeSince);
16268                    sb.append("%)");
16269                    Slog.i(TAG, sb.toString());
16270                }
16271                // If a process has held a wake lock for more
16272                // than 50% of the time during this period,
16273                // that sounds bad.  Kill!
16274                if (doWakeKills && realtimeSince > 0
16275                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16276                    synchronized (stats) {
16277                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16278                                realtimeSince, wtimeUsed);
16279                    }
16280                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16281                            + " during " + realtimeSince);
16282                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16283                } else if (doCpuKills && uptimeSince > 0
16284                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16285                    synchronized (stats) {
16286                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16287                                uptimeSince, cputimeUsed);
16288                    }
16289                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16290                            + " during " + uptimeSince);
16291                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16292                } else {
16293                    app.lastWakeTime = wtime;
16294                    app.lastCpuTime = app.curCpuTime;
16295                }
16296            }
16297        }
16298    }
16299
16300    private final boolean applyOomAdjLocked(ProcessRecord app,
16301            ProcessRecord TOP_APP, boolean doingAll, long now) {
16302        boolean success = true;
16303
16304        if (app.curRawAdj != app.setRawAdj) {
16305            app.setRawAdj = app.curRawAdj;
16306        }
16307
16308        int changes = 0;
16309
16310        if (app.curAdj != app.setAdj) {
16311            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16312            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16313                TAG, "Set " + app.pid + " " + app.processName +
16314                " adj " + app.curAdj + ": " + app.adjType);
16315            app.setAdj = app.curAdj;
16316        }
16317
16318        if (app.setSchedGroup != app.curSchedGroup) {
16319            app.setSchedGroup = app.curSchedGroup;
16320            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16321                    "Setting process group of " + app.processName
16322                    + " to " + app.curSchedGroup);
16323            if (app.waitingToKill != null &&
16324                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16325                killUnneededProcessLocked(app, app.waitingToKill);
16326                success = false;
16327            } else {
16328                if (true) {
16329                    long oldId = Binder.clearCallingIdentity();
16330                    try {
16331                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16332                    } catch (Exception e) {
16333                        Slog.w(TAG, "Failed setting process group of " + app.pid
16334                                + " to " + app.curSchedGroup);
16335                        e.printStackTrace();
16336                    } finally {
16337                        Binder.restoreCallingIdentity(oldId);
16338                    }
16339                } else {
16340                    if (app.thread != null) {
16341                        try {
16342                            app.thread.setSchedulingGroup(app.curSchedGroup);
16343                        } catch (RemoteException e) {
16344                        }
16345                    }
16346                }
16347                Process.setSwappiness(app.pid,
16348                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16349            }
16350        }
16351        if (app.repForegroundActivities != app.foregroundActivities) {
16352            app.repForegroundActivities = app.foregroundActivities;
16353            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16354        }
16355        if (app.repProcState != app.curProcState) {
16356            app.repProcState = app.curProcState;
16357            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16358            if (app.thread != null) {
16359                try {
16360                    if (false) {
16361                        //RuntimeException h = new RuntimeException("here");
16362                        Slog.i(TAG, "Sending new process state " + app.repProcState
16363                                + " to " + app /*, h*/);
16364                    }
16365                    app.thread.setProcessState(app.repProcState);
16366                } catch (RemoteException e) {
16367                }
16368            }
16369        }
16370        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16371                app.setProcState)) {
16372            app.lastStateTime = now;
16373            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16374                    isSleeping(), now);
16375            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16376                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16377                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16378                    + (app.nextPssTime-now) + ": " + app);
16379        } else {
16380            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16381                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16382                requestPssLocked(app, app.setProcState);
16383                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16384                        isSleeping(), now);
16385            } else if (false && DEBUG_PSS) {
16386                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16387            }
16388        }
16389        if (app.setProcState != app.curProcState) {
16390            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16391                    "Proc state change of " + app.processName
16392                    + " to " + app.curProcState);
16393            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16394            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16395            if (setImportant && !curImportant) {
16396                // This app is no longer something we consider important enough to allow to
16397                // use arbitrary amounts of battery power.  Note
16398                // its current wake lock time to later know to kill it if
16399                // it is not behaving well.
16400                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16401                synchronized (stats) {
16402                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16403                            app.pid, SystemClock.elapsedRealtime());
16404                }
16405                app.lastCpuTime = app.curCpuTime;
16406
16407            }
16408            app.setProcState = app.curProcState;
16409            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16410                app.notCachedSinceIdle = false;
16411            }
16412            if (!doingAll) {
16413                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16414            } else {
16415                app.procStateChanged = true;
16416            }
16417        }
16418
16419        if (changes != 0) {
16420            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16421            int i = mPendingProcessChanges.size()-1;
16422            ProcessChangeItem item = null;
16423            while (i >= 0) {
16424                item = mPendingProcessChanges.get(i);
16425                if (item.pid == app.pid) {
16426                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16427                    break;
16428                }
16429                i--;
16430            }
16431            if (i < 0) {
16432                // No existing item in pending changes; need a new one.
16433                final int NA = mAvailProcessChanges.size();
16434                if (NA > 0) {
16435                    item = mAvailProcessChanges.remove(NA-1);
16436                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16437                } else {
16438                    item = new ProcessChangeItem();
16439                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16440                }
16441                item.changes = 0;
16442                item.pid = app.pid;
16443                item.uid = app.info.uid;
16444                if (mPendingProcessChanges.size() == 0) {
16445                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16446                            "*** Enqueueing dispatch processes changed!");
16447                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16448                }
16449                mPendingProcessChanges.add(item);
16450            }
16451            item.changes |= changes;
16452            item.processState = app.repProcState;
16453            item.foregroundActivities = app.repForegroundActivities;
16454            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16455                    + Integer.toHexString(System.identityHashCode(item))
16456                    + " " + app.toShortString() + ": changes=" + item.changes
16457                    + " procState=" + item.processState
16458                    + " foreground=" + item.foregroundActivities
16459                    + " type=" + app.adjType + " source=" + app.adjSource
16460                    + " target=" + app.adjTarget);
16461        }
16462
16463        return success;
16464    }
16465
16466    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16467        if (proc.thread != null) {
16468            if (proc.baseProcessTracker != null) {
16469                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16470            }
16471            if (proc.repProcState >= 0) {
16472                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16473                        proc.repProcState);
16474            }
16475        }
16476    }
16477
16478    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16479            ProcessRecord TOP_APP, boolean doingAll, long now) {
16480        if (app.thread == null) {
16481            return false;
16482        }
16483
16484        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16485
16486        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16487    }
16488
16489    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16490            boolean oomAdj) {
16491        if (isForeground != proc.foregroundServices) {
16492            proc.foregroundServices = isForeground;
16493            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16494                    proc.info.uid);
16495            if (isForeground) {
16496                if (curProcs == null) {
16497                    curProcs = new ArrayList<ProcessRecord>();
16498                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16499                }
16500                if (!curProcs.contains(proc)) {
16501                    curProcs.add(proc);
16502                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16503                            proc.info.packageName, proc.info.uid);
16504                }
16505            } else {
16506                if (curProcs != null) {
16507                    if (curProcs.remove(proc)) {
16508                        mBatteryStatsService.noteEvent(
16509                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16510                                proc.info.packageName, proc.info.uid);
16511                        if (curProcs.size() <= 0) {
16512                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16513                        }
16514                    }
16515                }
16516            }
16517            if (oomAdj) {
16518                updateOomAdjLocked();
16519            }
16520        }
16521    }
16522
16523    private final ActivityRecord resumedAppLocked() {
16524        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16525        String pkg;
16526        int uid;
16527        if (act != null) {
16528            pkg = act.packageName;
16529            uid = act.info.applicationInfo.uid;
16530        } else {
16531            pkg = null;
16532            uid = -1;
16533        }
16534        // Has the UID or resumed package name changed?
16535        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16536                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16537            if (mCurResumedPackage != null) {
16538                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16539                        mCurResumedPackage, mCurResumedUid);
16540            }
16541            mCurResumedPackage = pkg;
16542            mCurResumedUid = uid;
16543            if (mCurResumedPackage != null) {
16544                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16545                        mCurResumedPackage, mCurResumedUid);
16546            }
16547        }
16548        return act;
16549    }
16550
16551    final boolean updateOomAdjLocked(ProcessRecord app) {
16552        final ActivityRecord TOP_ACT = resumedAppLocked();
16553        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16554        final boolean wasCached = app.cached;
16555
16556        mAdjSeq++;
16557
16558        // This is the desired cached adjusment we want to tell it to use.
16559        // If our app is currently cached, we know it, and that is it.  Otherwise,
16560        // we don't know it yet, and it needs to now be cached we will then
16561        // need to do a complete oom adj.
16562        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16563                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16564        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16565                SystemClock.uptimeMillis());
16566        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16567            // Changed to/from cached state, so apps after it in the LRU
16568            // list may also be changed.
16569            updateOomAdjLocked();
16570        }
16571        return success;
16572    }
16573
16574    final void updateOomAdjLocked() {
16575        final ActivityRecord TOP_ACT = resumedAppLocked();
16576        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16577        final long now = SystemClock.uptimeMillis();
16578        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16579        final int N = mLruProcesses.size();
16580
16581        if (false) {
16582            RuntimeException e = new RuntimeException();
16583            e.fillInStackTrace();
16584            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16585        }
16586
16587        mAdjSeq++;
16588        mNewNumServiceProcs = 0;
16589        mNewNumAServiceProcs = 0;
16590
16591        final int emptyProcessLimit;
16592        final int cachedProcessLimit;
16593        if (mProcessLimit <= 0) {
16594            emptyProcessLimit = cachedProcessLimit = 0;
16595        } else if (mProcessLimit == 1) {
16596            emptyProcessLimit = 1;
16597            cachedProcessLimit = 0;
16598        } else {
16599            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16600            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16601        }
16602
16603        // Let's determine how many processes we have running vs.
16604        // how many slots we have for background processes; we may want
16605        // to put multiple processes in a slot of there are enough of
16606        // them.
16607        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16608                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16609        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16610        if (numEmptyProcs > cachedProcessLimit) {
16611            // If there are more empty processes than our limit on cached
16612            // processes, then use the cached process limit for the factor.
16613            // This ensures that the really old empty processes get pushed
16614            // down to the bottom, so if we are running low on memory we will
16615            // have a better chance at keeping around more cached processes
16616            // instead of a gazillion empty processes.
16617            numEmptyProcs = cachedProcessLimit;
16618        }
16619        int emptyFactor = numEmptyProcs/numSlots;
16620        if (emptyFactor < 1) emptyFactor = 1;
16621        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16622        if (cachedFactor < 1) cachedFactor = 1;
16623        int stepCached = 0;
16624        int stepEmpty = 0;
16625        int numCached = 0;
16626        int numEmpty = 0;
16627        int numTrimming = 0;
16628
16629        mNumNonCachedProcs = 0;
16630        mNumCachedHiddenProcs = 0;
16631
16632        // First update the OOM adjustment for each of the
16633        // application processes based on their current state.
16634        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16635        int nextCachedAdj = curCachedAdj+1;
16636        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16637        int nextEmptyAdj = curEmptyAdj+2;
16638        for (int i=N-1; i>=0; i--) {
16639            ProcessRecord app = mLruProcesses.get(i);
16640            if (!app.killedByAm && app.thread != null) {
16641                app.procStateChanged = false;
16642                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16643
16644                // If we haven't yet assigned the final cached adj
16645                // to the process, do that now.
16646                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16647                    switch (app.curProcState) {
16648                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16649                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16650                            // This process is a cached process holding activities...
16651                            // assign it the next cached value for that type, and then
16652                            // step that cached level.
16653                            app.curRawAdj = curCachedAdj;
16654                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16655                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16656                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16657                                    + ")");
16658                            if (curCachedAdj != nextCachedAdj) {
16659                                stepCached++;
16660                                if (stepCached >= cachedFactor) {
16661                                    stepCached = 0;
16662                                    curCachedAdj = nextCachedAdj;
16663                                    nextCachedAdj += 2;
16664                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16665                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16666                                    }
16667                                }
16668                            }
16669                            break;
16670                        default:
16671                            // For everything else, assign next empty cached process
16672                            // level and bump that up.  Note that this means that
16673                            // long-running services that have dropped down to the
16674                            // cached level will be treated as empty (since their process
16675                            // state is still as a service), which is what we want.
16676                            app.curRawAdj = curEmptyAdj;
16677                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16678                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16679                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16680                                    + ")");
16681                            if (curEmptyAdj != nextEmptyAdj) {
16682                                stepEmpty++;
16683                                if (stepEmpty >= emptyFactor) {
16684                                    stepEmpty = 0;
16685                                    curEmptyAdj = nextEmptyAdj;
16686                                    nextEmptyAdj += 2;
16687                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16688                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16689                                    }
16690                                }
16691                            }
16692                            break;
16693                    }
16694                }
16695
16696                applyOomAdjLocked(app, TOP_APP, true, now);
16697
16698                // Count the number of process types.
16699                switch (app.curProcState) {
16700                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16701                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16702                        mNumCachedHiddenProcs++;
16703                        numCached++;
16704                        if (numCached > cachedProcessLimit) {
16705                            killUnneededProcessLocked(app, "cached #" + numCached);
16706                        }
16707                        break;
16708                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16709                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16710                                && app.lastActivityTime < oldTime) {
16711                            killUnneededProcessLocked(app, "empty for "
16712                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16713                                    / 1000) + "s");
16714                        } else {
16715                            numEmpty++;
16716                            if (numEmpty > emptyProcessLimit) {
16717                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16718                            }
16719                        }
16720                        break;
16721                    default:
16722                        mNumNonCachedProcs++;
16723                        break;
16724                }
16725
16726                if (app.isolated && app.services.size() <= 0) {
16727                    // If this is an isolated process, and there are no
16728                    // services running in it, then the process is no longer
16729                    // needed.  We agressively kill these because we can by
16730                    // definition not re-use the same process again, and it is
16731                    // good to avoid having whatever code was running in them
16732                    // left sitting around after no longer needed.
16733                    killUnneededProcessLocked(app, "isolated not needed");
16734                }
16735
16736                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16737                        && !app.killedByAm) {
16738                    numTrimming++;
16739                }
16740            }
16741        }
16742
16743        mNumServiceProcs = mNewNumServiceProcs;
16744
16745        // Now determine the memory trimming level of background processes.
16746        // Unfortunately we need to start at the back of the list to do this
16747        // properly.  We only do this if the number of background apps we
16748        // are managing to keep around is less than half the maximum we desire;
16749        // if we are keeping a good number around, we'll let them use whatever
16750        // memory they want.
16751        final int numCachedAndEmpty = numCached + numEmpty;
16752        int memFactor;
16753        if (numCached <= ProcessList.TRIM_CACHED_APPS
16754                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16755            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16756                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16757            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16758                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16759            } else {
16760                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16761            }
16762        } else {
16763            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16764        }
16765        // We always allow the memory level to go up (better).  We only allow it to go
16766        // down if we are in a state where that is allowed, *and* the total number of processes
16767        // has gone down since last time.
16768        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16769                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16770                + " last=" + mLastNumProcesses);
16771        if (memFactor > mLastMemoryLevel) {
16772            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16773                memFactor = mLastMemoryLevel;
16774                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16775            }
16776        }
16777        mLastMemoryLevel = memFactor;
16778        mLastNumProcesses = mLruProcesses.size();
16779        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16780        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16781        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16782            if (mLowRamStartTime == 0) {
16783                mLowRamStartTime = now;
16784            }
16785            int step = 0;
16786            int fgTrimLevel;
16787            switch (memFactor) {
16788                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16789                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16790                    break;
16791                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16792                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16793                    break;
16794                default:
16795                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16796                    break;
16797            }
16798            int factor = numTrimming/3;
16799            int minFactor = 2;
16800            if (mHomeProcess != null) minFactor++;
16801            if (mPreviousProcess != null) minFactor++;
16802            if (factor < minFactor) factor = minFactor;
16803            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16804            for (int i=N-1; i>=0; i--) {
16805                ProcessRecord app = mLruProcesses.get(i);
16806                if (allChanged || app.procStateChanged) {
16807                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16808                    app.procStateChanged = false;
16809                }
16810                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16811                        && !app.killedByAm) {
16812                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16813                        try {
16814                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16815                                    "Trimming memory of " + app.processName
16816                                    + " to " + curLevel);
16817                            app.thread.scheduleTrimMemory(curLevel);
16818                        } catch (RemoteException e) {
16819                        }
16820                        if (false) {
16821                            // For now we won't do this; our memory trimming seems
16822                            // to be good enough at this point that destroying
16823                            // activities causes more harm than good.
16824                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16825                                    && app != mHomeProcess && app != mPreviousProcess) {
16826                                // Need to do this on its own message because the stack may not
16827                                // be in a consistent state at this point.
16828                                // For these apps we will also finish their activities
16829                                // to help them free memory.
16830                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16831                            }
16832                        }
16833                    }
16834                    app.trimMemoryLevel = curLevel;
16835                    step++;
16836                    if (step >= factor) {
16837                        step = 0;
16838                        switch (curLevel) {
16839                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16840                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16841                                break;
16842                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16843                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16844                                break;
16845                        }
16846                    }
16847                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16848                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16849                            && app.thread != null) {
16850                        try {
16851                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16852                                    "Trimming memory of heavy-weight " + app.processName
16853                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16854                            app.thread.scheduleTrimMemory(
16855                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16856                        } catch (RemoteException e) {
16857                        }
16858                    }
16859                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16860                } else {
16861                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16862                            || app.systemNoUi) && app.pendingUiClean) {
16863                        // If this application is now in the background and it
16864                        // had done UI, then give it the special trim level to
16865                        // have it free UI resources.
16866                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16867                        if (app.trimMemoryLevel < level && app.thread != null) {
16868                            try {
16869                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16870                                        "Trimming memory of bg-ui " + app.processName
16871                                        + " to " + level);
16872                                app.thread.scheduleTrimMemory(level);
16873                            } catch (RemoteException e) {
16874                            }
16875                        }
16876                        app.pendingUiClean = false;
16877                    }
16878                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16879                        try {
16880                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16881                                    "Trimming memory of fg " + app.processName
16882                                    + " to " + fgTrimLevel);
16883                            app.thread.scheduleTrimMemory(fgTrimLevel);
16884                        } catch (RemoteException e) {
16885                        }
16886                    }
16887                    app.trimMemoryLevel = fgTrimLevel;
16888                }
16889            }
16890        } else {
16891            if (mLowRamStartTime != 0) {
16892                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16893                mLowRamStartTime = 0;
16894            }
16895            for (int i=N-1; i>=0; i--) {
16896                ProcessRecord app = mLruProcesses.get(i);
16897                if (allChanged || app.procStateChanged) {
16898                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16899                    app.procStateChanged = false;
16900                }
16901                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16902                        || app.systemNoUi) && app.pendingUiClean) {
16903                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16904                            && app.thread != null) {
16905                        try {
16906                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16907                                    "Trimming memory of ui hidden " + app.processName
16908                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16909                            app.thread.scheduleTrimMemory(
16910                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16911                        } catch (RemoteException e) {
16912                        }
16913                    }
16914                    app.pendingUiClean = false;
16915                }
16916                app.trimMemoryLevel = 0;
16917            }
16918        }
16919
16920        if (mAlwaysFinishActivities) {
16921            // Need to do this on its own message because the stack may not
16922            // be in a consistent state at this point.
16923            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16924        }
16925
16926        if (allChanged) {
16927            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16928        }
16929
16930        if (mProcessStats.shouldWriteNowLocked(now)) {
16931            mHandler.post(new Runnable() {
16932                @Override public void run() {
16933                    synchronized (ActivityManagerService.this) {
16934                        mProcessStats.writeStateAsyncLocked();
16935                    }
16936                }
16937            });
16938        }
16939
16940        if (DEBUG_OOM_ADJ) {
16941            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16942        }
16943    }
16944
16945    final void trimApplications() {
16946        synchronized (this) {
16947            int i;
16948
16949            // First remove any unused application processes whose package
16950            // has been removed.
16951            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16952                final ProcessRecord app = mRemovedProcesses.get(i);
16953                if (app.activities.size() == 0
16954                        && app.curReceiver == null && app.services.size() == 0) {
16955                    Slog.i(
16956                        TAG, "Exiting empty application process "
16957                        + app.processName + " ("
16958                        + (app.thread != null ? app.thread.asBinder() : null)
16959                        + ")\n");
16960                    if (app.pid > 0 && app.pid != MY_PID) {
16961                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16962                                app.processName, app.setAdj, "empty");
16963                        app.killedByAm = true;
16964                        Process.killProcessQuiet(app.pid);
16965                        Process.killProcessGroup(app.info.uid, app.pid);
16966                    } else {
16967                        try {
16968                            app.thread.scheduleExit();
16969                        } catch (Exception e) {
16970                            // Ignore exceptions.
16971                        }
16972                    }
16973                    cleanUpApplicationRecordLocked(app, false, true, -1);
16974                    mRemovedProcesses.remove(i);
16975
16976                    if (app.persistent) {
16977                        addAppLocked(app.info, false, null /* ABI override */);
16978                    }
16979                }
16980            }
16981
16982            // Now update the oom adj for all processes.
16983            updateOomAdjLocked();
16984        }
16985    }
16986
16987    /** This method sends the specified signal to each of the persistent apps */
16988    public void signalPersistentProcesses(int sig) throws RemoteException {
16989        if (sig != Process.SIGNAL_USR1) {
16990            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16991        }
16992
16993        synchronized (this) {
16994            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16995                    != PackageManager.PERMISSION_GRANTED) {
16996                throw new SecurityException("Requires permission "
16997                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16998            }
16999
17000            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17001                ProcessRecord r = mLruProcesses.get(i);
17002                if (r.thread != null && r.persistent) {
17003                    Process.sendSignal(r.pid, sig);
17004                }
17005            }
17006        }
17007    }
17008
17009    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17010        if (proc == null || proc == mProfileProc) {
17011            proc = mProfileProc;
17012            path = mProfileFile;
17013            profileType = mProfileType;
17014            clearProfilerLocked();
17015        }
17016        if (proc == null) {
17017            return;
17018        }
17019        try {
17020            proc.thread.profilerControl(false, path, null, profileType);
17021        } catch (RemoteException e) {
17022            throw new IllegalStateException("Process disappeared");
17023        }
17024    }
17025
17026    private void clearProfilerLocked() {
17027        if (mProfileFd != null) {
17028            try {
17029                mProfileFd.close();
17030            } catch (IOException e) {
17031            }
17032        }
17033        mProfileApp = null;
17034        mProfileProc = null;
17035        mProfileFile = null;
17036        mProfileType = 0;
17037        mAutoStopProfiler = false;
17038    }
17039
17040    public boolean profileControl(String process, int userId, boolean start,
17041            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17042
17043        try {
17044            synchronized (this) {
17045                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17046                // its own permission.
17047                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17048                        != PackageManager.PERMISSION_GRANTED) {
17049                    throw new SecurityException("Requires permission "
17050                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17051                }
17052
17053                if (start && fd == null) {
17054                    throw new IllegalArgumentException("null fd");
17055                }
17056
17057                ProcessRecord proc = null;
17058                if (process != null) {
17059                    proc = findProcessLocked(process, userId, "profileControl");
17060                }
17061
17062                if (start && (proc == null || proc.thread == null)) {
17063                    throw new IllegalArgumentException("Unknown process: " + process);
17064                }
17065
17066                if (start) {
17067                    stopProfilerLocked(null, null, 0);
17068                    setProfileApp(proc.info, proc.processName, path, fd, false);
17069                    mProfileProc = proc;
17070                    mProfileType = profileType;
17071                    try {
17072                        fd = fd.dup();
17073                    } catch (IOException e) {
17074                        fd = null;
17075                    }
17076                    proc.thread.profilerControl(start, path, fd, profileType);
17077                    fd = null;
17078                    mProfileFd = null;
17079                } else {
17080                    stopProfilerLocked(proc, path, profileType);
17081                    if (fd != null) {
17082                        try {
17083                            fd.close();
17084                        } catch (IOException e) {
17085                        }
17086                    }
17087                }
17088
17089                return true;
17090            }
17091        } catch (RemoteException e) {
17092            throw new IllegalStateException("Process disappeared");
17093        } finally {
17094            if (fd != null) {
17095                try {
17096                    fd.close();
17097                } catch (IOException e) {
17098                }
17099            }
17100        }
17101    }
17102
17103    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17104        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17105                userId, true, ALLOW_FULL_ONLY, callName, null);
17106        ProcessRecord proc = null;
17107        try {
17108            int pid = Integer.parseInt(process);
17109            synchronized (mPidsSelfLocked) {
17110                proc = mPidsSelfLocked.get(pid);
17111            }
17112        } catch (NumberFormatException e) {
17113        }
17114
17115        if (proc == null) {
17116            ArrayMap<String, SparseArray<ProcessRecord>> all
17117                    = mProcessNames.getMap();
17118            SparseArray<ProcessRecord> procs = all.get(process);
17119            if (procs != null && procs.size() > 0) {
17120                proc = procs.valueAt(0);
17121                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17122                    for (int i=1; i<procs.size(); i++) {
17123                        ProcessRecord thisProc = procs.valueAt(i);
17124                        if (thisProc.userId == userId) {
17125                            proc = thisProc;
17126                            break;
17127                        }
17128                    }
17129                }
17130            }
17131        }
17132
17133        return proc;
17134    }
17135
17136    public boolean dumpHeap(String process, int userId, boolean managed,
17137            String path, ParcelFileDescriptor fd) throws RemoteException {
17138
17139        try {
17140            synchronized (this) {
17141                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17142                // its own permission (same as profileControl).
17143                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17144                        != PackageManager.PERMISSION_GRANTED) {
17145                    throw new SecurityException("Requires permission "
17146                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17147                }
17148
17149                if (fd == null) {
17150                    throw new IllegalArgumentException("null fd");
17151                }
17152
17153                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17154                if (proc == null || proc.thread == null) {
17155                    throw new IllegalArgumentException("Unknown process: " + process);
17156                }
17157
17158                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17159                if (!isDebuggable) {
17160                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17161                        throw new SecurityException("Process not debuggable: " + proc);
17162                    }
17163                }
17164
17165                proc.thread.dumpHeap(managed, path, fd);
17166                fd = null;
17167                return true;
17168            }
17169        } catch (RemoteException e) {
17170            throw new IllegalStateException("Process disappeared");
17171        } finally {
17172            if (fd != null) {
17173                try {
17174                    fd.close();
17175                } catch (IOException e) {
17176                }
17177            }
17178        }
17179    }
17180
17181    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17182    public void monitor() {
17183        synchronized (this) { }
17184    }
17185
17186    void onCoreSettingsChange(Bundle settings) {
17187        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17188            ProcessRecord processRecord = mLruProcesses.get(i);
17189            try {
17190                if (processRecord.thread != null) {
17191                    processRecord.thread.setCoreSettings(settings);
17192                }
17193            } catch (RemoteException re) {
17194                /* ignore */
17195            }
17196        }
17197    }
17198
17199    // Multi-user methods
17200
17201    /**
17202     * Start user, if its not already running, but don't bring it to foreground.
17203     */
17204    @Override
17205    public boolean startUserInBackground(final int userId) {
17206        return startUser(userId, /* foreground */ false);
17207    }
17208
17209    /**
17210     * Refreshes the list of users related to the current user when either a
17211     * user switch happens or when a new related user is started in the
17212     * background.
17213     */
17214    private void updateCurrentProfileIdsLocked() {
17215        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17216                mCurrentUserId, false /* enabledOnly */);
17217        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17218        for (int i = 0; i < currentProfileIds.length; i++) {
17219            currentProfileIds[i] = profiles.get(i).id;
17220        }
17221        mCurrentProfileIds = currentProfileIds;
17222
17223        synchronized (mUserProfileGroupIdsSelfLocked) {
17224            mUserProfileGroupIdsSelfLocked.clear();
17225            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17226            for (int i = 0; i < users.size(); i++) {
17227                UserInfo user = users.get(i);
17228                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17229                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17230                }
17231            }
17232        }
17233    }
17234
17235    private Set getProfileIdsLocked(int userId) {
17236        Set userIds = new HashSet<Integer>();
17237        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17238                userId, false /* enabledOnly */);
17239        for (UserInfo user : profiles) {
17240            userIds.add(Integer.valueOf(user.id));
17241        }
17242        return userIds;
17243    }
17244
17245    @Override
17246    public boolean switchUser(final int userId) {
17247        return startUser(userId, /* foregound */ true);
17248    }
17249
17250    private boolean startUser(final int userId, boolean foreground) {
17251        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17252                != PackageManager.PERMISSION_GRANTED) {
17253            String msg = "Permission Denial: switchUser() from pid="
17254                    + Binder.getCallingPid()
17255                    + ", uid=" + Binder.getCallingUid()
17256                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17257            Slog.w(TAG, msg);
17258            throw new SecurityException(msg);
17259        }
17260
17261        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17262
17263        final long ident = Binder.clearCallingIdentity();
17264        try {
17265            synchronized (this) {
17266                final int oldUserId = mCurrentUserId;
17267                if (oldUserId == userId) {
17268                    return true;
17269                }
17270
17271                mStackSupervisor.setLockTaskModeLocked(null, false);
17272
17273                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17274                if (userInfo == null) {
17275                    Slog.w(TAG, "No user info for user #" + userId);
17276                    return false;
17277                }
17278                if (foreground && userInfo.isManagedProfile()) {
17279                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17280                    return false;
17281                }
17282
17283                if (foreground) {
17284                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17285                            R.anim.screen_user_enter);
17286                }
17287
17288                boolean needStart = false;
17289
17290                // If the user we are switching to is not currently started, then
17291                // we need to start it now.
17292                if (mStartedUsers.get(userId) == null) {
17293                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17294                    updateStartedUserArrayLocked();
17295                    needStart = true;
17296                }
17297
17298                final Integer userIdInt = Integer.valueOf(userId);
17299                mUserLru.remove(userIdInt);
17300                mUserLru.add(userIdInt);
17301
17302                if (foreground) {
17303                    mCurrentUserId = userId;
17304                    updateCurrentProfileIdsLocked();
17305                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17306                    // Once the internal notion of the active user has switched, we lock the device
17307                    // with the option to show the user switcher on the keyguard.
17308                    mWindowManager.lockNow(null);
17309                } else {
17310                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17311                    updateCurrentProfileIdsLocked();
17312                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17313                    mUserLru.remove(currentUserIdInt);
17314                    mUserLru.add(currentUserIdInt);
17315                }
17316
17317                final UserStartedState uss = mStartedUsers.get(userId);
17318
17319                // Make sure user is in the started state.  If it is currently
17320                // stopping, we need to knock that off.
17321                if (uss.mState == UserStartedState.STATE_STOPPING) {
17322                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17323                    // so we can just fairly silently bring the user back from
17324                    // the almost-dead.
17325                    uss.mState = UserStartedState.STATE_RUNNING;
17326                    updateStartedUserArrayLocked();
17327                    needStart = true;
17328                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17329                    // This means ACTION_SHUTDOWN has been sent, so we will
17330                    // need to treat this as a new boot of the user.
17331                    uss.mState = UserStartedState.STATE_BOOTING;
17332                    updateStartedUserArrayLocked();
17333                    needStart = true;
17334                }
17335
17336                if (uss.mState == UserStartedState.STATE_BOOTING) {
17337                    // Booting up a new user, need to tell system services about it.
17338                    // Note that this is on the same handler as scheduling of broadcasts,
17339                    // which is important because it needs to go first.
17340                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17341                }
17342
17343                if (foreground) {
17344                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17345                            oldUserId));
17346                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17347                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17348                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17349                            oldUserId, userId, uss));
17350                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17351                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17352                }
17353
17354                if (needStart) {
17355                    // Send USER_STARTED broadcast
17356                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17357                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17358                            | Intent.FLAG_RECEIVER_FOREGROUND);
17359                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17360                    broadcastIntentLocked(null, null, intent,
17361                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17362                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17363                }
17364
17365                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17366                    if (userId != UserHandle.USER_OWNER) {
17367                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17368                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17369                        broadcastIntentLocked(null, null, intent, null,
17370                                new IIntentReceiver.Stub() {
17371                                    public void performReceive(Intent intent, int resultCode,
17372                                            String data, Bundle extras, boolean ordered,
17373                                            boolean sticky, int sendingUser) {
17374                                        userInitialized(uss, userId);
17375                                    }
17376                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17377                                true, false, MY_PID, Process.SYSTEM_UID,
17378                                userId);
17379                        uss.initializing = true;
17380                    } else {
17381                        getUserManagerLocked().makeInitialized(userInfo.id);
17382                    }
17383                }
17384
17385                if (foreground) {
17386                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17387                    if (homeInFront) {
17388                        startHomeActivityLocked(userId);
17389                    } else {
17390                        mStackSupervisor.resumeTopActivitiesLocked();
17391                    }
17392                    EventLogTags.writeAmSwitchUser(userId);
17393                    getUserManagerLocked().userForeground(userId);
17394                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17395                } else {
17396                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17397                }
17398
17399                if (needStart) {
17400                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17401                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17402                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17403                    broadcastIntentLocked(null, null, intent,
17404                            null, new IIntentReceiver.Stub() {
17405                                @Override
17406                                public void performReceive(Intent intent, int resultCode, String data,
17407                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17408                                        throws RemoteException {
17409                                }
17410                            }, 0, null, null,
17411                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17412                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17413                }
17414            }
17415        } finally {
17416            Binder.restoreCallingIdentity(ident);
17417        }
17418
17419        return true;
17420    }
17421
17422    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17423        long ident = Binder.clearCallingIdentity();
17424        try {
17425            Intent intent;
17426            if (oldUserId >= 0) {
17427                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17428                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17429                int count = profiles.size();
17430                for (int i = 0; i < count; i++) {
17431                    int profileUserId = profiles.get(i).id;
17432                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17433                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17434                            | Intent.FLAG_RECEIVER_FOREGROUND);
17435                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17436                    broadcastIntentLocked(null, null, intent,
17437                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17438                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17439                }
17440            }
17441            if (newUserId >= 0) {
17442                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17443                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17444                int count = profiles.size();
17445                for (int i = 0; i < count; i++) {
17446                    int profileUserId = profiles.get(i).id;
17447                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17448                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17449                            | Intent.FLAG_RECEIVER_FOREGROUND);
17450                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17451                    broadcastIntentLocked(null, null, intent,
17452                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17453                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17454                }
17455                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17456                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17457                        | Intent.FLAG_RECEIVER_FOREGROUND);
17458                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17459                broadcastIntentLocked(null, null, intent,
17460                        null, null, 0, null, null,
17461                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17462                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17463            }
17464        } finally {
17465            Binder.restoreCallingIdentity(ident);
17466        }
17467    }
17468
17469    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17470            final int newUserId) {
17471        final int N = mUserSwitchObservers.beginBroadcast();
17472        if (N > 0) {
17473            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17474                int mCount = 0;
17475                @Override
17476                public void sendResult(Bundle data) throws RemoteException {
17477                    synchronized (ActivityManagerService.this) {
17478                        if (mCurUserSwitchCallback == this) {
17479                            mCount++;
17480                            if (mCount == N) {
17481                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17482                            }
17483                        }
17484                    }
17485                }
17486            };
17487            synchronized (this) {
17488                uss.switching = true;
17489                mCurUserSwitchCallback = callback;
17490            }
17491            for (int i=0; i<N; i++) {
17492                try {
17493                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17494                            newUserId, callback);
17495                } catch (RemoteException e) {
17496                }
17497            }
17498        } else {
17499            synchronized (this) {
17500                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17501            }
17502        }
17503        mUserSwitchObservers.finishBroadcast();
17504    }
17505
17506    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17507        synchronized (this) {
17508            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17509            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17510        }
17511    }
17512
17513    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17514        mCurUserSwitchCallback = null;
17515        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17516        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17517                oldUserId, newUserId, uss));
17518    }
17519
17520    void userInitialized(UserStartedState uss, int newUserId) {
17521        completeSwitchAndInitalize(uss, newUserId, true, false);
17522    }
17523
17524    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17525        completeSwitchAndInitalize(uss, newUserId, false, true);
17526    }
17527
17528    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17529            boolean clearInitializing, boolean clearSwitching) {
17530        boolean unfrozen = false;
17531        synchronized (this) {
17532            if (clearInitializing) {
17533                uss.initializing = false;
17534                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17535            }
17536            if (clearSwitching) {
17537                uss.switching = false;
17538            }
17539            if (!uss.switching && !uss.initializing) {
17540                mWindowManager.stopFreezingScreen();
17541                unfrozen = true;
17542            }
17543        }
17544        if (unfrozen) {
17545            final int N = mUserSwitchObservers.beginBroadcast();
17546            for (int i=0; i<N; i++) {
17547                try {
17548                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17549                } catch (RemoteException e) {
17550                }
17551            }
17552            mUserSwitchObservers.finishBroadcast();
17553        }
17554    }
17555
17556    void scheduleStartProfilesLocked() {
17557        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17558            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17559                    DateUtils.SECOND_IN_MILLIS);
17560        }
17561    }
17562
17563    void startProfilesLocked() {
17564        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17565        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17566                mCurrentUserId, false /* enabledOnly */);
17567        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17568        for (UserInfo user : profiles) {
17569            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17570                    && user.id != mCurrentUserId) {
17571                toStart.add(user);
17572            }
17573        }
17574        final int n = toStart.size();
17575        int i = 0;
17576        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17577            startUserInBackground(toStart.get(i).id);
17578        }
17579        if (i < n) {
17580            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17581        }
17582    }
17583
17584    void finishUserBoot(UserStartedState uss) {
17585        synchronized (this) {
17586            if (uss.mState == UserStartedState.STATE_BOOTING
17587                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17588                uss.mState = UserStartedState.STATE_RUNNING;
17589                final int userId = uss.mHandle.getIdentifier();
17590                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17591                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17592                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17593                broadcastIntentLocked(null, null, intent,
17594                        null, null, 0, null, null,
17595                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17596                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17597            }
17598        }
17599    }
17600
17601    void finishUserSwitch(UserStartedState uss) {
17602        synchronized (this) {
17603            finishUserBoot(uss);
17604
17605            startProfilesLocked();
17606
17607            int num = mUserLru.size();
17608            int i = 0;
17609            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17610                Integer oldUserId = mUserLru.get(i);
17611                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17612                if (oldUss == null) {
17613                    // Shouldn't happen, but be sane if it does.
17614                    mUserLru.remove(i);
17615                    num--;
17616                    continue;
17617                }
17618                if (oldUss.mState == UserStartedState.STATE_STOPPING
17619                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17620                    // This user is already stopping, doesn't count.
17621                    num--;
17622                    i++;
17623                    continue;
17624                }
17625                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17626                    // Owner and current can't be stopped, but count as running.
17627                    i++;
17628                    continue;
17629                }
17630                // This is a user to be stopped.
17631                stopUserLocked(oldUserId, null);
17632                num--;
17633                i++;
17634            }
17635        }
17636    }
17637
17638    @Override
17639    public int stopUser(final int userId, final IStopUserCallback callback) {
17640        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17641                != PackageManager.PERMISSION_GRANTED) {
17642            String msg = "Permission Denial: switchUser() from pid="
17643                    + Binder.getCallingPid()
17644                    + ", uid=" + Binder.getCallingUid()
17645                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17646            Slog.w(TAG, msg);
17647            throw new SecurityException(msg);
17648        }
17649        if (userId <= 0) {
17650            throw new IllegalArgumentException("Can't stop primary user " + userId);
17651        }
17652        synchronized (this) {
17653            return stopUserLocked(userId, callback);
17654        }
17655    }
17656
17657    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17658        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17659        if (mCurrentUserId == userId) {
17660            return ActivityManager.USER_OP_IS_CURRENT;
17661        }
17662
17663        final UserStartedState uss = mStartedUsers.get(userId);
17664        if (uss == null) {
17665            // User is not started, nothing to do...  but we do need to
17666            // callback if requested.
17667            if (callback != null) {
17668                mHandler.post(new Runnable() {
17669                    @Override
17670                    public void run() {
17671                        try {
17672                            callback.userStopped(userId);
17673                        } catch (RemoteException e) {
17674                        }
17675                    }
17676                });
17677            }
17678            return ActivityManager.USER_OP_SUCCESS;
17679        }
17680
17681        if (callback != null) {
17682            uss.mStopCallbacks.add(callback);
17683        }
17684
17685        if (uss.mState != UserStartedState.STATE_STOPPING
17686                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17687            uss.mState = UserStartedState.STATE_STOPPING;
17688            updateStartedUserArrayLocked();
17689
17690            long ident = Binder.clearCallingIdentity();
17691            try {
17692                // We are going to broadcast ACTION_USER_STOPPING and then
17693                // once that is done send a final ACTION_SHUTDOWN and then
17694                // stop the user.
17695                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17696                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17697                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17698                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17699                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17700                // This is the result receiver for the final shutdown broadcast.
17701                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17702                    @Override
17703                    public void performReceive(Intent intent, int resultCode, String data,
17704                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17705                        finishUserStop(uss);
17706                    }
17707                };
17708                // This is the result receiver for the initial stopping broadcast.
17709                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17710                    @Override
17711                    public void performReceive(Intent intent, int resultCode, String data,
17712                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17713                        // On to the next.
17714                        synchronized (ActivityManagerService.this) {
17715                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17716                                // Whoops, we are being started back up.  Abort, abort!
17717                                return;
17718                            }
17719                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17720                        }
17721                        mBatteryStatsService.noteEvent(
17722                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17723                                Integer.toString(userId), userId);
17724                        mSystemServiceManager.stopUser(userId);
17725                        broadcastIntentLocked(null, null, shutdownIntent,
17726                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17727                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17728                    }
17729                };
17730                // Kick things off.
17731                broadcastIntentLocked(null, null, stoppingIntent,
17732                        null, stoppingReceiver, 0, null, null,
17733                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17734                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17735            } finally {
17736                Binder.restoreCallingIdentity(ident);
17737            }
17738        }
17739
17740        return ActivityManager.USER_OP_SUCCESS;
17741    }
17742
17743    void finishUserStop(UserStartedState uss) {
17744        final int userId = uss.mHandle.getIdentifier();
17745        boolean stopped;
17746        ArrayList<IStopUserCallback> callbacks;
17747        synchronized (this) {
17748            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17749            if (mStartedUsers.get(userId) != uss) {
17750                stopped = false;
17751            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17752                stopped = false;
17753            } else {
17754                stopped = true;
17755                // User can no longer run.
17756                mStartedUsers.remove(userId);
17757                mUserLru.remove(Integer.valueOf(userId));
17758                updateStartedUserArrayLocked();
17759
17760                // Clean up all state and processes associated with the user.
17761                // Kill all the processes for the user.
17762                forceStopUserLocked(userId, "finish user");
17763            }
17764
17765            // Explicitly remove the old information in mRecentTasks.
17766            removeRecentTasksForUserLocked(userId);
17767        }
17768
17769        for (int i=0; i<callbacks.size(); i++) {
17770            try {
17771                if (stopped) callbacks.get(i).userStopped(userId);
17772                else callbacks.get(i).userStopAborted(userId);
17773            } catch (RemoteException e) {
17774            }
17775        }
17776
17777        if (stopped) {
17778            mSystemServiceManager.cleanupUser(userId);
17779            synchronized (this) {
17780                mStackSupervisor.removeUserLocked(userId);
17781            }
17782        }
17783    }
17784
17785    @Override
17786    public UserInfo getCurrentUser() {
17787        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17788                != PackageManager.PERMISSION_GRANTED) && (
17789                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17790                != PackageManager.PERMISSION_GRANTED)) {
17791            String msg = "Permission Denial: getCurrentUser() from pid="
17792                    + Binder.getCallingPid()
17793                    + ", uid=" + Binder.getCallingUid()
17794                    + " requires " + INTERACT_ACROSS_USERS;
17795            Slog.w(TAG, msg);
17796            throw new SecurityException(msg);
17797        }
17798        synchronized (this) {
17799            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17800        }
17801    }
17802
17803    int getCurrentUserIdLocked() {
17804        return mCurrentUserId;
17805    }
17806
17807    @Override
17808    public boolean isUserRunning(int userId, boolean orStopped) {
17809        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17810                != PackageManager.PERMISSION_GRANTED) {
17811            String msg = "Permission Denial: isUserRunning() from pid="
17812                    + Binder.getCallingPid()
17813                    + ", uid=" + Binder.getCallingUid()
17814                    + " requires " + INTERACT_ACROSS_USERS;
17815            Slog.w(TAG, msg);
17816            throw new SecurityException(msg);
17817        }
17818        synchronized (this) {
17819            return isUserRunningLocked(userId, orStopped);
17820        }
17821    }
17822
17823    boolean isUserRunningLocked(int userId, boolean orStopped) {
17824        UserStartedState state = mStartedUsers.get(userId);
17825        if (state == null) {
17826            return false;
17827        }
17828        if (orStopped) {
17829            return true;
17830        }
17831        return state.mState != UserStartedState.STATE_STOPPING
17832                && state.mState != UserStartedState.STATE_SHUTDOWN;
17833    }
17834
17835    @Override
17836    public int[] getRunningUserIds() {
17837        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17838                != PackageManager.PERMISSION_GRANTED) {
17839            String msg = "Permission Denial: isUserRunning() from pid="
17840                    + Binder.getCallingPid()
17841                    + ", uid=" + Binder.getCallingUid()
17842                    + " requires " + INTERACT_ACROSS_USERS;
17843            Slog.w(TAG, msg);
17844            throw new SecurityException(msg);
17845        }
17846        synchronized (this) {
17847            return mStartedUserArray;
17848        }
17849    }
17850
17851    private void updateStartedUserArrayLocked() {
17852        int num = 0;
17853        for (int i=0; i<mStartedUsers.size();  i++) {
17854            UserStartedState uss = mStartedUsers.valueAt(i);
17855            // This list does not include stopping users.
17856            if (uss.mState != UserStartedState.STATE_STOPPING
17857                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17858                num++;
17859            }
17860        }
17861        mStartedUserArray = new int[num];
17862        num = 0;
17863        for (int i=0; i<mStartedUsers.size();  i++) {
17864            UserStartedState uss = mStartedUsers.valueAt(i);
17865            if (uss.mState != UserStartedState.STATE_STOPPING
17866                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17867                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17868                num++;
17869            }
17870        }
17871    }
17872
17873    @Override
17874    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17875        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17876                != PackageManager.PERMISSION_GRANTED) {
17877            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17878                    + Binder.getCallingPid()
17879                    + ", uid=" + Binder.getCallingUid()
17880                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17881            Slog.w(TAG, msg);
17882            throw new SecurityException(msg);
17883        }
17884
17885        mUserSwitchObservers.register(observer);
17886    }
17887
17888    @Override
17889    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17890        mUserSwitchObservers.unregister(observer);
17891    }
17892
17893    private boolean userExists(int userId) {
17894        if (userId == 0) {
17895            return true;
17896        }
17897        UserManagerService ums = getUserManagerLocked();
17898        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17899    }
17900
17901    int[] getUsersLocked() {
17902        UserManagerService ums = getUserManagerLocked();
17903        return ums != null ? ums.getUserIds() : new int[] { 0 };
17904    }
17905
17906    UserManagerService getUserManagerLocked() {
17907        if (mUserManager == null) {
17908            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17909            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17910        }
17911        return mUserManager;
17912    }
17913
17914    private int applyUserId(int uid, int userId) {
17915        return UserHandle.getUid(userId, uid);
17916    }
17917
17918    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17919        if (info == null) return null;
17920        ApplicationInfo newInfo = new ApplicationInfo(info);
17921        newInfo.uid = applyUserId(info.uid, userId);
17922        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17923                + info.packageName;
17924        return newInfo;
17925    }
17926
17927    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17928        if (aInfo == null
17929                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17930            return aInfo;
17931        }
17932
17933        ActivityInfo info = new ActivityInfo(aInfo);
17934        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17935        return info;
17936    }
17937
17938    private final class LocalService extends ActivityManagerInternal {
17939        @Override
17940        public void goingToSleep() {
17941            ActivityManagerService.this.goingToSleep();
17942        }
17943
17944        @Override
17945        public void wakingUp() {
17946            ActivityManagerService.this.wakingUp();
17947        }
17948
17949        @Override
17950        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17951                String processName, String abiOverride, int uid, Runnable crashHandler) {
17952            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17953                    processName, abiOverride, uid, crashHandler);
17954        }
17955    }
17956
17957    /**
17958     * An implementation of IAppTask, that allows an app to manage its own tasks via
17959     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17960     * only the process that calls getAppTasks() can call the AppTask methods.
17961     */
17962    class AppTaskImpl extends IAppTask.Stub {
17963        private int mTaskId;
17964        private int mCallingUid;
17965
17966        public AppTaskImpl(int taskId, int callingUid) {
17967            mTaskId = taskId;
17968            mCallingUid = callingUid;
17969        }
17970
17971        @Override
17972        public void finishAndRemoveTask() {
17973            // Ensure that we are called from the same process that created this AppTask
17974            if (mCallingUid != Binder.getCallingUid()) {
17975                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17976                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17977                return;
17978            }
17979
17980            synchronized (ActivityManagerService.this) {
17981                long origId = Binder.clearCallingIdentity();
17982                try {
17983                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17984                    if (tr != null) {
17985                        // Only kill the process if we are not a new document
17986                        int flags = tr.getBaseIntent().getFlags();
17987                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17988                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17989                        removeTaskByIdLocked(mTaskId,
17990                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17991                    }
17992                } finally {
17993                    Binder.restoreCallingIdentity(origId);
17994                }
17995            }
17996        }
17997
17998        @Override
17999        public ActivityManager.RecentTaskInfo getTaskInfo() {
18000            // Ensure that we are called from the same process that created this AppTask
18001            if (mCallingUid != Binder.getCallingUid()) {
18002                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18003                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18004                return null;
18005            }
18006
18007            synchronized (ActivityManagerService.this) {
18008                long origId = Binder.clearCallingIdentity();
18009                try {
18010                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18011                    if (tr != null) {
18012                        return createRecentTaskInfoFromTaskRecord(tr);
18013                    }
18014                } finally {
18015                    Binder.restoreCallingIdentity(origId);
18016                }
18017                return null;
18018            }
18019        }
18020    }
18021}
18022