ActivityManagerService.java revision a351ab96987381ffe7ea29a7cdec1e7fbd1497d5
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
4670            try {
4671                // Clear application user data
4672                pm.clearApplicationUserData(packageName, observer, userId);
4673
4674                // Remove all permissions granted from/to this package
4675                removeUriPermissionsForPackageLocked(packageName, userId, true);
4676
4677                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4678                        Uri.fromParts("package", packageName, null));
4679                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4680                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4681                        null, null, 0, null, null, null, false, false, userId);
4682            } catch (RemoteException e) {
4683            }
4684        } finally {
4685            Binder.restoreCallingIdentity(callingId);
4686        }
4687        return true;
4688    }
4689
4690    @Override
4691    public void killBackgroundProcesses(final String packageName, int userId) {
4692        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4693                != PackageManager.PERMISSION_GRANTED &&
4694                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4695                        != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703
4704        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4705                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            synchronized(this) {
4710                int appId = -1;
4711                try {
4712                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4713                } catch (RemoteException e) {
4714                }
4715                if (appId == -1) {
4716                    Slog.w(TAG, "Invalid packageName: " + packageName);
4717                    return;
4718                }
4719                killPackageProcessesLocked(packageName, appId, userId,
4720                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(callingId);
4724        }
4725    }
4726
4727    @Override
4728    public void killAllBackgroundProcesses() {
4729        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4730                != PackageManager.PERMISSION_GRANTED) {
4731            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4732                    + Binder.getCallingPid()
4733                    + ", uid=" + Binder.getCallingUid()
4734                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4735            Slog.w(TAG, msg);
4736            throw new SecurityException(msg);
4737        }
4738
4739        long callingId = Binder.clearCallingIdentity();
4740        try {
4741            synchronized(this) {
4742                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4743                final int NP = mProcessNames.getMap().size();
4744                for (int ip=0; ip<NP; ip++) {
4745                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4746                    final int NA = apps.size();
4747                    for (int ia=0; ia<NA; ia++) {
4748                        ProcessRecord app = apps.valueAt(ia);
4749                        if (app.persistent) {
4750                            // we don't kill persistent processes
4751                            continue;
4752                        }
4753                        if (app.removed) {
4754                            procs.add(app);
4755                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4756                            app.removed = true;
4757                            procs.add(app);
4758                        }
4759                    }
4760                }
4761
4762                int N = procs.size();
4763                for (int i=0; i<N; i++) {
4764                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4765                }
4766                mAllowLowerMemLevel = true;
4767                updateOomAdjLocked();
4768                doLowMemReportIfNeededLocked(null);
4769            }
4770        } finally {
4771            Binder.restoreCallingIdentity(callingId);
4772        }
4773    }
4774
4775    @Override
4776    public void forceStopPackage(final String packageName, int userId) {
4777        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4778                != PackageManager.PERMISSION_GRANTED) {
4779            String msg = "Permission Denial: forceStopPackage() from pid="
4780                    + Binder.getCallingPid()
4781                    + ", uid=" + Binder.getCallingUid()
4782                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4783            Slog.w(TAG, msg);
4784            throw new SecurityException(msg);
4785        }
4786        final int callingPid = Binder.getCallingPid();
4787        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4788                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4789        long callingId = Binder.clearCallingIdentity();
4790        try {
4791            IPackageManager pm = AppGlobals.getPackageManager();
4792            synchronized(this) {
4793                int[] users = userId == UserHandle.USER_ALL
4794                        ? getUsersLocked() : new int[] { userId };
4795                for (int user : users) {
4796                    int pkgUid = -1;
4797                    try {
4798                        pkgUid = pm.getPackageUid(packageName, user);
4799                    } catch (RemoteException e) {
4800                    }
4801                    if (pkgUid == -1) {
4802                        Slog.w(TAG, "Invalid packageName: " + packageName);
4803                        continue;
4804                    }
4805                    try {
4806                        pm.setPackageStoppedState(packageName, true, user);
4807                    } catch (RemoteException e) {
4808                    } catch (IllegalArgumentException e) {
4809                        Slog.w(TAG, "Failed trying to unstop package "
4810                                + packageName + ": " + e);
4811                    }
4812                    if (isUserRunningLocked(user, false)) {
4813                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4814                    }
4815                }
4816            }
4817        } finally {
4818            Binder.restoreCallingIdentity(callingId);
4819        }
4820    }
4821
4822    @Override
4823    public void addPackageDependency(String packageName) {
4824        synchronized (this) {
4825            int callingPid = Binder.getCallingPid();
4826            if (callingPid == Process.myPid()) {
4827                //  Yeah, um, no.
4828                Slog.w(TAG, "Can't addPackageDependency on system process");
4829                return;
4830            }
4831            ProcessRecord proc;
4832            synchronized (mPidsSelfLocked) {
4833                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4834            }
4835            if (proc != null) {
4836                if (proc.pkgDeps == null) {
4837                    proc.pkgDeps = new ArraySet<String>(1);
4838                }
4839                proc.pkgDeps.add(packageName);
4840            }
4841        }
4842    }
4843
4844    /*
4845     * The pkg name and app id have to be specified.
4846     */
4847    @Override
4848    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4849        if (pkg == null) {
4850            return;
4851        }
4852        // Make sure the uid is valid.
4853        if (appid < 0) {
4854            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4855            return;
4856        }
4857        int callerUid = Binder.getCallingUid();
4858        // Only the system server can kill an application
4859        if (callerUid == Process.SYSTEM_UID) {
4860            // Post an aysnc message to kill the application
4861            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4862            msg.arg1 = appid;
4863            msg.arg2 = 0;
4864            Bundle bundle = new Bundle();
4865            bundle.putString("pkg", pkg);
4866            bundle.putString("reason", reason);
4867            msg.obj = bundle;
4868            mHandler.sendMessage(msg);
4869        } else {
4870            throw new SecurityException(callerUid + " cannot kill pkg: " +
4871                    pkg);
4872        }
4873    }
4874
4875    @Override
4876    public void closeSystemDialogs(String reason) {
4877        enforceNotIsolatedCaller("closeSystemDialogs");
4878
4879        final int pid = Binder.getCallingPid();
4880        final int uid = Binder.getCallingUid();
4881        final long origId = Binder.clearCallingIdentity();
4882        try {
4883            synchronized (this) {
4884                // Only allow this from foreground processes, so that background
4885                // applications can't abuse it to prevent system UI from being shown.
4886                if (uid >= Process.FIRST_APPLICATION_UID) {
4887                    ProcessRecord proc;
4888                    synchronized (mPidsSelfLocked) {
4889                        proc = mPidsSelfLocked.get(pid);
4890                    }
4891                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4892                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4893                                + " from background process " + proc);
4894                        return;
4895                    }
4896                }
4897                closeSystemDialogsLocked(reason);
4898            }
4899        } finally {
4900            Binder.restoreCallingIdentity(origId);
4901        }
4902    }
4903
4904    void closeSystemDialogsLocked(String reason) {
4905        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4906        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4907                | Intent.FLAG_RECEIVER_FOREGROUND);
4908        if (reason != null) {
4909            intent.putExtra("reason", reason);
4910        }
4911        mWindowManager.closeSystemDialogs(reason);
4912
4913        mStackSupervisor.closeSystemDialogsLocked();
4914
4915        broadcastIntentLocked(null, null, intent, null,
4916                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4917                Process.SYSTEM_UID, UserHandle.USER_ALL);
4918    }
4919
4920    @Override
4921    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4922        enforceNotIsolatedCaller("getProcessMemoryInfo");
4923        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4924        for (int i=pids.length-1; i>=0; i--) {
4925            ProcessRecord proc;
4926            int oomAdj;
4927            synchronized (this) {
4928                synchronized (mPidsSelfLocked) {
4929                    proc = mPidsSelfLocked.get(pids[i]);
4930                    oomAdj = proc != null ? proc.setAdj : 0;
4931                }
4932            }
4933            infos[i] = new Debug.MemoryInfo();
4934            Debug.getMemoryInfo(pids[i], infos[i]);
4935            if (proc != null) {
4936                synchronized (this) {
4937                    if (proc.thread != null && proc.setAdj == oomAdj) {
4938                        // Record this for posterity if the process has been stable.
4939                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4940                                infos[i].getTotalUss(), false, proc.pkgList);
4941                    }
4942                }
4943            }
4944        }
4945        return infos;
4946    }
4947
4948    @Override
4949    public long[] getProcessPss(int[] pids) {
4950        enforceNotIsolatedCaller("getProcessPss");
4951        long[] pss = new long[pids.length];
4952        for (int i=pids.length-1; i>=0; i--) {
4953            ProcessRecord proc;
4954            int oomAdj;
4955            synchronized (this) {
4956                synchronized (mPidsSelfLocked) {
4957                    proc = mPidsSelfLocked.get(pids[i]);
4958                    oomAdj = proc != null ? proc.setAdj : 0;
4959                }
4960            }
4961            long[] tmpUss = new long[1];
4962            pss[i] = Debug.getPss(pids[i], tmpUss);
4963            if (proc != null) {
4964                synchronized (this) {
4965                    if (proc.thread != null && proc.setAdj == oomAdj) {
4966                        // Record this for posterity if the process has been stable.
4967                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4968                    }
4969                }
4970            }
4971        }
4972        return pss;
4973    }
4974
4975    @Override
4976    public void killApplicationProcess(String processName, int uid) {
4977        if (processName == null) {
4978            return;
4979        }
4980
4981        int callerUid = Binder.getCallingUid();
4982        // Only the system server can kill an application
4983        if (callerUid == Process.SYSTEM_UID) {
4984            synchronized (this) {
4985                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4986                if (app != null && app.thread != null) {
4987                    try {
4988                        app.thread.scheduleSuicide();
4989                    } catch (RemoteException e) {
4990                        // If the other end already died, then our work here is done.
4991                    }
4992                } else {
4993                    Slog.w(TAG, "Process/uid not found attempting kill of "
4994                            + processName + " / " + uid);
4995                }
4996            }
4997        } else {
4998            throw new SecurityException(callerUid + " cannot kill app process: " +
4999                    processName);
5000        }
5001    }
5002
5003    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5004        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5005                false, true, false, false, UserHandle.getUserId(uid), reason);
5006        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5007                Uri.fromParts("package", packageName, null));
5008        if (!mProcessesReady) {
5009            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5010                    | Intent.FLAG_RECEIVER_FOREGROUND);
5011        }
5012        intent.putExtra(Intent.EXTRA_UID, uid);
5013        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5014        broadcastIntentLocked(null, null, intent,
5015                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5016                false, false,
5017                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5018    }
5019
5020    private void forceStopUserLocked(int userId, String reason) {
5021        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5022        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5023        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5024                | Intent.FLAG_RECEIVER_FOREGROUND);
5025        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
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.USER_ALL);
5030    }
5031
5032    private final boolean killPackageProcessesLocked(String packageName, int appId,
5033            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5034            boolean doit, boolean evenPersistent, String reason) {
5035        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5036
5037        // Remove all processes this package may have touched: all with the
5038        // same UID (except for the system or root user), and all whose name
5039        // matches the package name.
5040        final int NP = mProcessNames.getMap().size();
5041        for (int ip=0; ip<NP; ip++) {
5042            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5043            final int NA = apps.size();
5044            for (int ia=0; ia<NA; ia++) {
5045                ProcessRecord app = apps.valueAt(ia);
5046                if (app.persistent && !evenPersistent) {
5047                    // we don't kill persistent processes
5048                    continue;
5049                }
5050                if (app.removed) {
5051                    if (doit) {
5052                        procs.add(app);
5053                    }
5054                    continue;
5055                }
5056
5057                // Skip process if it doesn't meet our oom adj requirement.
5058                if (app.setAdj < minOomAdj) {
5059                    continue;
5060                }
5061
5062                // If no package is specified, we call all processes under the
5063                // give user id.
5064                if (packageName == null) {
5065                    if (app.userId != userId) {
5066                        continue;
5067                    }
5068                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5069                        continue;
5070                    }
5071                // Package has been specified, we want to hit all processes
5072                // that match it.  We need to qualify this by the processes
5073                // that are running under the specified app and user ID.
5074                } else {
5075                    final boolean isDep = app.pkgDeps != null
5076                            && app.pkgDeps.contains(packageName);
5077                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5078                        continue;
5079                    }
5080                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5081                        continue;
5082                    }
5083                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5084                        continue;
5085                    }
5086                }
5087
5088                // Process has passed all conditions, kill it!
5089                if (!doit) {
5090                    return true;
5091                }
5092                app.removed = true;
5093                procs.add(app);
5094            }
5095        }
5096
5097        int N = procs.size();
5098        for (int i=0; i<N; i++) {
5099            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5100        }
5101        updateOomAdjLocked();
5102        return N > 0;
5103    }
5104
5105    private final boolean forceStopPackageLocked(String name, int appId,
5106            boolean callerWillRestart, boolean purgeCache, boolean doit,
5107            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5108        int i;
5109        int N;
5110
5111        if (userId == UserHandle.USER_ALL && name == null) {
5112            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5113        }
5114
5115        if (appId < 0 && name != null) {
5116            try {
5117                appId = UserHandle.getAppId(
5118                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5119            } catch (RemoteException e) {
5120            }
5121        }
5122
5123        if (doit) {
5124            if (name != null) {
5125                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5126                        + " user=" + userId + ": " + reason);
5127            } else {
5128                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5129            }
5130
5131            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5132            for (int ip=pmap.size()-1; ip>=0; ip--) {
5133                SparseArray<Long> ba = pmap.valueAt(ip);
5134                for (i=ba.size()-1; i>=0; i--) {
5135                    boolean remove = false;
5136                    final int entUid = ba.keyAt(i);
5137                    if (name != null) {
5138                        if (userId == UserHandle.USER_ALL) {
5139                            if (UserHandle.getAppId(entUid) == appId) {
5140                                remove = true;
5141                            }
5142                        } else {
5143                            if (entUid == UserHandle.getUid(userId, appId)) {
5144                                remove = true;
5145                            }
5146                        }
5147                    } else if (UserHandle.getUserId(entUid) == userId) {
5148                        remove = true;
5149                    }
5150                    if (remove) {
5151                        ba.removeAt(i);
5152                    }
5153                }
5154                if (ba.size() == 0) {
5155                    pmap.removeAt(ip);
5156                }
5157            }
5158        }
5159
5160        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5161                -100, callerWillRestart, true, doit, evenPersistent,
5162                name == null ? ("stop user " + userId) : ("stop " + name));
5163
5164        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5165            if (!doit) {
5166                return true;
5167            }
5168            didSomething = true;
5169        }
5170
5171        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5172            if (!doit) {
5173                return true;
5174            }
5175            didSomething = true;
5176        }
5177
5178        if (name == null) {
5179            // Remove all sticky broadcasts from this user.
5180            mStickyBroadcasts.remove(userId);
5181        }
5182
5183        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5184        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5185                userId, providers)) {
5186            if (!doit) {
5187                return true;
5188            }
5189            didSomething = true;
5190        }
5191        N = providers.size();
5192        for (i=0; i<N; i++) {
5193            removeDyingProviderLocked(null, providers.get(i), true);
5194        }
5195
5196        // Remove transient permissions granted from/to this package/user
5197        removeUriPermissionsForPackageLocked(name, userId, false);
5198
5199        if (name == null || uninstalling) {
5200            // Remove pending intents.  For now we only do this when force
5201            // stopping users, because we have some problems when doing this
5202            // for packages -- app widgets are not currently cleaned up for
5203            // such packages, so they can be left with bad pending intents.
5204            if (mIntentSenderRecords.size() > 0) {
5205                Iterator<WeakReference<PendingIntentRecord>> it
5206                        = mIntentSenderRecords.values().iterator();
5207                while (it.hasNext()) {
5208                    WeakReference<PendingIntentRecord> wpir = it.next();
5209                    if (wpir == null) {
5210                        it.remove();
5211                        continue;
5212                    }
5213                    PendingIntentRecord pir = wpir.get();
5214                    if (pir == null) {
5215                        it.remove();
5216                        continue;
5217                    }
5218                    if (name == null) {
5219                        // Stopping user, remove all objects for the user.
5220                        if (pir.key.userId != userId) {
5221                            // Not the same user, skip it.
5222                            continue;
5223                        }
5224                    } else {
5225                        if (UserHandle.getAppId(pir.uid) != appId) {
5226                            // Different app id, skip it.
5227                            continue;
5228                        }
5229                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5230                            // Different user, skip it.
5231                            continue;
5232                        }
5233                        if (!pir.key.packageName.equals(name)) {
5234                            // Different package, skip it.
5235                            continue;
5236                        }
5237                    }
5238                    if (!doit) {
5239                        return true;
5240                    }
5241                    didSomething = true;
5242                    it.remove();
5243                    pir.canceled = true;
5244                    if (pir.key.activity != null) {
5245                        pir.key.activity.pendingResults.remove(pir.ref);
5246                    }
5247                }
5248            }
5249        }
5250
5251        if (doit) {
5252            if (purgeCache && name != null) {
5253                AttributeCache ac = AttributeCache.instance();
5254                if (ac != null) {
5255                    ac.removePackage(name);
5256                }
5257            }
5258            if (mBooted) {
5259                mStackSupervisor.resumeTopActivitiesLocked();
5260                mStackSupervisor.scheduleIdleLocked();
5261            }
5262        }
5263
5264        return didSomething;
5265    }
5266
5267    private final boolean removeProcessLocked(ProcessRecord app,
5268            boolean callerWillRestart, boolean allowRestart, String reason) {
5269        final String name = app.processName;
5270        final int uid = app.uid;
5271        if (DEBUG_PROCESSES) Slog.d(
5272            TAG, "Force removing proc " + app.toShortString() + " (" + name
5273            + "/" + uid + ")");
5274
5275        mProcessNames.remove(name, uid);
5276        mIsolatedProcesses.remove(app.uid);
5277        if (mHeavyWeightProcess == app) {
5278            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5279                    mHeavyWeightProcess.userId, 0));
5280            mHeavyWeightProcess = null;
5281        }
5282        boolean needRestart = false;
5283        if (app.pid > 0 && app.pid != MY_PID) {
5284            int pid = app.pid;
5285            synchronized (mPidsSelfLocked) {
5286                mPidsSelfLocked.remove(pid);
5287                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5288            }
5289            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5290            if (app.isolated) {
5291                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5292            }
5293            killUnneededProcessLocked(app, reason);
5294            Process.killProcessGroup(app.info.uid, app.pid);
5295            handleAppDiedLocked(app, true, allowRestart);
5296            removeLruProcessLocked(app);
5297
5298            if (app.persistent && !app.isolated) {
5299                if (!callerWillRestart) {
5300                    addAppLocked(app.info, false, null /* ABI override */);
5301                } else {
5302                    needRestart = true;
5303                }
5304            }
5305        } else {
5306            mRemovedProcesses.add(app);
5307        }
5308
5309        return needRestart;
5310    }
5311
5312    private final void processStartTimedOutLocked(ProcessRecord app) {
5313        final int pid = app.pid;
5314        boolean gone = false;
5315        synchronized (mPidsSelfLocked) {
5316            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5317            if (knownApp != null && knownApp.thread == null) {
5318                mPidsSelfLocked.remove(pid);
5319                gone = true;
5320            }
5321        }
5322
5323        if (gone) {
5324            Slog.w(TAG, "Process " + app + " failed to attach");
5325            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5326                    pid, app.uid, app.processName);
5327            mProcessNames.remove(app.processName, app.uid);
5328            mIsolatedProcesses.remove(app.uid);
5329            if (mHeavyWeightProcess == app) {
5330                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5331                        mHeavyWeightProcess.userId, 0));
5332                mHeavyWeightProcess = null;
5333            }
5334            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5335            if (app.isolated) {
5336                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5337            }
5338            // Take care of any launching providers waiting for this process.
5339            checkAppInLaunchingProvidersLocked(app, true);
5340            // Take care of any services that are waiting for the process.
5341            mServices.processStartTimedOutLocked(app);
5342            killUnneededProcessLocked(app, "start timeout");
5343            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5344                Slog.w(TAG, "Unattached app died before backup, skipping");
5345                try {
5346                    IBackupManager bm = IBackupManager.Stub.asInterface(
5347                            ServiceManager.getService(Context.BACKUP_SERVICE));
5348                    bm.agentDisconnected(app.info.packageName);
5349                } catch (RemoteException e) {
5350                    // Can't happen; the backup manager is local
5351                }
5352            }
5353            if (isPendingBroadcastProcessLocked(pid)) {
5354                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5355                skipPendingBroadcastLocked(pid);
5356            }
5357        } else {
5358            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5359        }
5360    }
5361
5362    private final boolean attachApplicationLocked(IApplicationThread thread,
5363            int pid) {
5364
5365        // Find the application record that is being attached...  either via
5366        // the pid if we are running in multiple processes, or just pull the
5367        // next app record if we are emulating process with anonymous threads.
5368        ProcessRecord app;
5369        if (pid != MY_PID && pid >= 0) {
5370            synchronized (mPidsSelfLocked) {
5371                app = mPidsSelfLocked.get(pid);
5372            }
5373        } else {
5374            app = null;
5375        }
5376
5377        if (app == null) {
5378            Slog.w(TAG, "No pending application record for pid " + pid
5379                    + " (IApplicationThread " + thread + "); dropping process");
5380            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5381            if (pid > 0 && pid != MY_PID) {
5382                Process.killProcessQuiet(pid);
5383                //TODO: Process.killProcessGroup(app.info.uid, pid);
5384            } else {
5385                try {
5386                    thread.scheduleExit();
5387                } catch (Exception e) {
5388                    // Ignore exceptions.
5389                }
5390            }
5391            return false;
5392        }
5393
5394        // If this application record is still attached to a previous
5395        // process, clean it up now.
5396        if (app.thread != null) {
5397            handleAppDiedLocked(app, true, true);
5398        }
5399
5400        // Tell the process all about itself.
5401
5402        if (localLOGV) Slog.v(
5403                TAG, "Binding process pid " + pid + " to record " + app);
5404
5405        final String processName = app.processName;
5406        try {
5407            AppDeathRecipient adr = new AppDeathRecipient(
5408                    app, pid, thread);
5409            thread.asBinder().linkToDeath(adr, 0);
5410            app.deathRecipient = adr;
5411        } catch (RemoteException e) {
5412            app.resetPackageList(mProcessStats);
5413            startProcessLocked(app, "link fail", processName);
5414            return false;
5415        }
5416
5417        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5418
5419        app.makeActive(thread, mProcessStats);
5420        app.curAdj = app.setAdj = -100;
5421        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5422        app.forcingToForeground = null;
5423        updateProcessForegroundLocked(app, false, false);
5424        app.hasShownUi = false;
5425        app.debugging = false;
5426        app.cached = false;
5427
5428        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5429
5430        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5431        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5432
5433        if (!normalMode) {
5434            Slog.i(TAG, "Launching preboot mode app: " + app);
5435        }
5436
5437        if (localLOGV) Slog.v(
5438            TAG, "New app record " + app
5439            + " thread=" + thread.asBinder() + " pid=" + pid);
5440        try {
5441            int testMode = IApplicationThread.DEBUG_OFF;
5442            if (mDebugApp != null && mDebugApp.equals(processName)) {
5443                testMode = mWaitForDebugger
5444                    ? IApplicationThread.DEBUG_WAIT
5445                    : IApplicationThread.DEBUG_ON;
5446                app.debugging = true;
5447                if (mDebugTransient) {
5448                    mDebugApp = mOrigDebugApp;
5449                    mWaitForDebugger = mOrigWaitForDebugger;
5450                }
5451            }
5452            String profileFile = app.instrumentationProfileFile;
5453            ParcelFileDescriptor profileFd = null;
5454            boolean profileAutoStop = false;
5455            if (mProfileApp != null && mProfileApp.equals(processName)) {
5456                mProfileProc = app;
5457                profileFile = mProfileFile;
5458                profileFd = mProfileFd;
5459                profileAutoStop = mAutoStopProfiler;
5460            }
5461            boolean enableOpenGlTrace = false;
5462            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5463                enableOpenGlTrace = true;
5464                mOpenGlTraceApp = null;
5465            }
5466
5467            // If the app is being launched for restore or full backup, set it up specially
5468            boolean isRestrictedBackupMode = false;
5469            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5470                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5471                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5472                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5473            }
5474
5475            ensurePackageDexOpt(app.instrumentationInfo != null
5476                    ? app.instrumentationInfo.packageName
5477                    : app.info.packageName);
5478            if (app.instrumentationClass != null) {
5479                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5480            }
5481            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5482                    + processName + " with config " + mConfiguration);
5483            ApplicationInfo appInfo = app.instrumentationInfo != null
5484                    ? app.instrumentationInfo : app.info;
5485            app.compat = compatibilityInfoForPackageLocked(appInfo);
5486            if (profileFd != null) {
5487                profileFd = profileFd.dup();
5488            }
5489            thread.bindApplication(processName, appInfo, providers,
5490                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5491                    app.instrumentationArguments, app.instrumentationWatcher,
5492                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5493                    isRestrictedBackupMode || !normalMode, app.persistent,
5494                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5495                    mCoreSettingsObserver.getCoreSettingsLocked());
5496            updateLruProcessLocked(app, false, null);
5497            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5498        } catch (Exception e) {
5499            // todo: Yikes!  What should we do?  For now we will try to
5500            // start another process, but that could easily get us in
5501            // an infinite loop of restarting processes...
5502            Slog.w(TAG, "Exception thrown during bind!", e);
5503
5504            app.resetPackageList(mProcessStats);
5505            app.unlinkDeathRecipient();
5506            startProcessLocked(app, "bind fail", processName);
5507            return false;
5508        }
5509
5510        // Remove this record from the list of starting applications.
5511        mPersistentStartingProcesses.remove(app);
5512        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5513                "Attach application locked removing on hold: " + app);
5514        mProcessesOnHold.remove(app);
5515
5516        boolean badApp = false;
5517        boolean didSomething = false;
5518
5519        // See if the top visible activity is waiting to run in this process...
5520        if (normalMode) {
5521            try {
5522                if (mStackSupervisor.attachApplicationLocked(app)) {
5523                    didSomething = true;
5524                }
5525            } catch (Exception e) {
5526                badApp = true;
5527            }
5528        }
5529
5530        // Find any services that should be running in this process...
5531        if (!badApp) {
5532            try {
5533                didSomething |= mServices.attachApplicationLocked(app, processName);
5534            } catch (Exception e) {
5535                badApp = true;
5536            }
5537        }
5538
5539        // Check if a next-broadcast receiver is in this process...
5540        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5541            try {
5542                didSomething |= sendPendingBroadcastsLocked(app);
5543            } catch (Exception e) {
5544                // If the app died trying to launch the receiver we declare it 'bad'
5545                badApp = true;
5546            }
5547        }
5548
5549        // Check whether the next backup agent is in this process...
5550        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5551            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5552            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5553            try {
5554                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5555                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5556                        mBackupTarget.backupMode);
5557            } catch (Exception e) {
5558                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5559                e.printStackTrace();
5560            }
5561        }
5562
5563        if (badApp) {
5564            // todo: Also need to kill application to deal with all
5565            // kinds of exceptions.
5566            handleAppDiedLocked(app, false, true);
5567            return false;
5568        }
5569
5570        if (!didSomething) {
5571            updateOomAdjLocked();
5572        }
5573
5574        return true;
5575    }
5576
5577    @Override
5578    public final void attachApplication(IApplicationThread thread) {
5579        synchronized (this) {
5580            int callingPid = Binder.getCallingPid();
5581            final long origId = Binder.clearCallingIdentity();
5582            attachApplicationLocked(thread, callingPid);
5583            Binder.restoreCallingIdentity(origId);
5584        }
5585    }
5586
5587    @Override
5588    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5589        final long origId = Binder.clearCallingIdentity();
5590        synchronized (this) {
5591            ActivityStack stack = ActivityRecord.getStackLocked(token);
5592            if (stack != null) {
5593                ActivityRecord r =
5594                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5595                if (stopProfiling) {
5596                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5597                        try {
5598                            mProfileFd.close();
5599                        } catch (IOException e) {
5600                        }
5601                        clearProfilerLocked();
5602                    }
5603                }
5604            }
5605        }
5606        Binder.restoreCallingIdentity(origId);
5607    }
5608
5609    void postEnableScreenAfterBootLocked() {
5610        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5611    }
5612
5613    void enableScreenAfterBoot() {
5614        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5615                SystemClock.uptimeMillis());
5616        mWindowManager.enableScreenAfterBoot();
5617
5618        synchronized (this) {
5619            updateEventDispatchingLocked();
5620        }
5621    }
5622
5623    @Override
5624    public void showBootMessage(final CharSequence msg, final boolean always) {
5625        enforceNotIsolatedCaller("showBootMessage");
5626        mWindowManager.showBootMessage(msg, always);
5627    }
5628
5629    @Override
5630    public void dismissKeyguardOnNextActivity() {
5631        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5632        final long token = Binder.clearCallingIdentity();
5633        try {
5634            synchronized (this) {
5635                if (DEBUG_LOCKSCREEN) logLockScreen("");
5636                if (mLockScreenShown) {
5637                    mLockScreenShown = false;
5638                    comeOutOfSleepIfNeededLocked();
5639                }
5640                mStackSupervisor.setDismissKeyguard(true);
5641            }
5642        } finally {
5643            Binder.restoreCallingIdentity(token);
5644        }
5645    }
5646
5647    final void finishBooting() {
5648        // Register receivers to handle package update events
5649        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5650
5651        synchronized (this) {
5652            // Ensure that any processes we had put on hold are now started
5653            // up.
5654            final int NP = mProcessesOnHold.size();
5655            if (NP > 0) {
5656                ArrayList<ProcessRecord> procs =
5657                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5658                for (int ip=0; ip<NP; ip++) {
5659                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5660                            + procs.get(ip));
5661                    startProcessLocked(procs.get(ip), "on-hold", null);
5662                }
5663            }
5664
5665            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5666                // Start looking for apps that are abusing wake locks.
5667                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5668                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5669                // Tell anyone interested that we are done booting!
5670                SystemProperties.set("sys.boot_completed", "1");
5671                SystemProperties.set("dev.bootcomplete", "1");
5672                for (int i=0; i<mStartedUsers.size(); i++) {
5673                    UserStartedState uss = mStartedUsers.valueAt(i);
5674                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5675                        uss.mState = UserStartedState.STATE_RUNNING;
5676                        final int userId = mStartedUsers.keyAt(i);
5677                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5678                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5679                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5680                        broadcastIntentLocked(null, null, intent, null,
5681                                new IIntentReceiver.Stub() {
5682                                    @Override
5683                                    public void performReceive(Intent intent, int resultCode,
5684                                            String data, Bundle extras, boolean ordered,
5685                                            boolean sticky, int sendingUser) {
5686                                        synchronized (ActivityManagerService.this) {
5687                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5688                                                    true, false);
5689                                        }
5690                                    }
5691                                },
5692                                0, null, null,
5693                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5694                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5695                                userId);
5696                    }
5697                }
5698                scheduleStartProfilesLocked();
5699            }
5700        }
5701    }
5702
5703    final void ensureBootCompleted() {
5704        boolean booting;
5705        boolean enableScreen;
5706        synchronized (this) {
5707            booting = mBooting;
5708            mBooting = false;
5709            enableScreen = !mBooted;
5710            mBooted = true;
5711        }
5712
5713        if (booting) {
5714            finishBooting();
5715        }
5716
5717        if (enableScreen) {
5718            enableScreenAfterBoot();
5719        }
5720    }
5721
5722    @Override
5723    public final void activityResumed(IBinder token) {
5724        final long origId = Binder.clearCallingIdentity();
5725        synchronized(this) {
5726            ActivityStack stack = ActivityRecord.getStackLocked(token);
5727            if (stack != null) {
5728                ActivityRecord.activityResumedLocked(token);
5729            }
5730        }
5731        Binder.restoreCallingIdentity(origId);
5732    }
5733
5734    @Override
5735    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5736        final long origId = Binder.clearCallingIdentity();
5737        synchronized(this) {
5738            ActivityStack stack = ActivityRecord.getStackLocked(token);
5739            if (stack != null) {
5740                stack.activityPausedLocked(token, false, persistentState);
5741            }
5742        }
5743        Binder.restoreCallingIdentity(origId);
5744    }
5745
5746    @Override
5747    public final void activityStopped(IBinder token, Bundle icicle,
5748            PersistableBundle persistentState, CharSequence description) {
5749        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5750
5751        // Refuse possible leaked file descriptors
5752        if (icicle != null && icicle.hasFileDescriptors()) {
5753            throw new IllegalArgumentException("File descriptors passed in Bundle");
5754        }
5755
5756        final long origId = Binder.clearCallingIdentity();
5757
5758        synchronized (this) {
5759            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5760            if (r != null) {
5761                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5762            }
5763        }
5764
5765        trimApplications();
5766
5767        Binder.restoreCallingIdentity(origId);
5768    }
5769
5770    @Override
5771    public final void activityDestroyed(IBinder token) {
5772        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5773        synchronized (this) {
5774            ActivityStack stack = ActivityRecord.getStackLocked(token);
5775            if (stack != null) {
5776                stack.activityDestroyedLocked(token);
5777            }
5778        }
5779    }
5780
5781    @Override
5782    public final void mediaResourcesReleased(IBinder token) {
5783        final long origId = Binder.clearCallingIdentity();
5784        try {
5785            synchronized (this) {
5786                ActivityStack stack = ActivityRecord.getStackLocked(token);
5787                if (stack != null) {
5788                    stack.mediaResourcesReleased(token);
5789                }
5790            }
5791        } finally {
5792            Binder.restoreCallingIdentity(origId);
5793        }
5794    }
5795
5796    @Override
5797    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5798        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5799    }
5800
5801    @Override
5802    public final void notifyEnterAnimationComplete(IBinder token) {
5803        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5804    }
5805
5806    @Override
5807    public String getCallingPackage(IBinder token) {
5808        synchronized (this) {
5809            ActivityRecord r = getCallingRecordLocked(token);
5810            return r != null ? r.info.packageName : null;
5811        }
5812    }
5813
5814    @Override
5815    public ComponentName getCallingActivity(IBinder token) {
5816        synchronized (this) {
5817            ActivityRecord r = getCallingRecordLocked(token);
5818            return r != null ? r.intent.getComponent() : null;
5819        }
5820    }
5821
5822    private ActivityRecord getCallingRecordLocked(IBinder token) {
5823        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5824        if (r == null) {
5825            return null;
5826        }
5827        return r.resultTo;
5828    }
5829
5830    @Override
5831    public ComponentName getActivityClassForToken(IBinder token) {
5832        synchronized(this) {
5833            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5834            if (r == null) {
5835                return null;
5836            }
5837            return r.intent.getComponent();
5838        }
5839    }
5840
5841    @Override
5842    public String getPackageForToken(IBinder token) {
5843        synchronized(this) {
5844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5845            if (r == null) {
5846                return null;
5847            }
5848            return r.packageName;
5849        }
5850    }
5851
5852    @Override
5853    public IIntentSender getIntentSender(int type,
5854            String packageName, IBinder token, String resultWho,
5855            int requestCode, Intent[] intents, String[] resolvedTypes,
5856            int flags, Bundle options, int userId) {
5857        enforceNotIsolatedCaller("getIntentSender");
5858        // Refuse possible leaked file descriptors
5859        if (intents != null) {
5860            if (intents.length < 1) {
5861                throw new IllegalArgumentException("Intents array length must be >= 1");
5862            }
5863            for (int i=0; i<intents.length; i++) {
5864                Intent intent = intents[i];
5865                if (intent != null) {
5866                    if (intent.hasFileDescriptors()) {
5867                        throw new IllegalArgumentException("File descriptors passed in Intent");
5868                    }
5869                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5870                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5871                        throw new IllegalArgumentException(
5872                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5873                    }
5874                    intents[i] = new Intent(intent);
5875                }
5876            }
5877            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5878                throw new IllegalArgumentException(
5879                        "Intent array length does not match resolvedTypes length");
5880            }
5881        }
5882        if (options != null) {
5883            if (options.hasFileDescriptors()) {
5884                throw new IllegalArgumentException("File descriptors passed in options");
5885            }
5886        }
5887
5888        synchronized(this) {
5889            int callingUid = Binder.getCallingUid();
5890            int origUserId = userId;
5891            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5892                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5893                    ALLOW_NON_FULL, "getIntentSender", null);
5894            if (origUserId == UserHandle.USER_CURRENT) {
5895                // We don't want to evaluate this until the pending intent is
5896                // actually executed.  However, we do want to always do the
5897                // security checking for it above.
5898                userId = UserHandle.USER_CURRENT;
5899            }
5900            try {
5901                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5902                    int uid = AppGlobals.getPackageManager()
5903                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5904                    if (!UserHandle.isSameApp(callingUid, uid)) {
5905                        String msg = "Permission Denial: getIntentSender() from pid="
5906                            + Binder.getCallingPid()
5907                            + ", uid=" + Binder.getCallingUid()
5908                            + ", (need uid=" + uid + ")"
5909                            + " is not allowed to send as package " + packageName;
5910                        Slog.w(TAG, msg);
5911                        throw new SecurityException(msg);
5912                    }
5913                }
5914
5915                return getIntentSenderLocked(type, packageName, callingUid, userId,
5916                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5917
5918            } catch (RemoteException e) {
5919                throw new SecurityException(e);
5920            }
5921        }
5922    }
5923
5924    IIntentSender getIntentSenderLocked(int type, String packageName,
5925            int callingUid, int userId, IBinder token, String resultWho,
5926            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5927            Bundle options) {
5928        if (DEBUG_MU)
5929            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5930        ActivityRecord activity = null;
5931        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5932            activity = ActivityRecord.isInStackLocked(token);
5933            if (activity == null) {
5934                return null;
5935            }
5936            if (activity.finishing) {
5937                return null;
5938            }
5939        }
5940
5941        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5942        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5943        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5944        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5945                |PendingIntent.FLAG_UPDATE_CURRENT);
5946
5947        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5948                type, packageName, activity, resultWho,
5949                requestCode, intents, resolvedTypes, flags, options, userId);
5950        WeakReference<PendingIntentRecord> ref;
5951        ref = mIntentSenderRecords.get(key);
5952        PendingIntentRecord rec = ref != null ? ref.get() : null;
5953        if (rec != null) {
5954            if (!cancelCurrent) {
5955                if (updateCurrent) {
5956                    if (rec.key.requestIntent != null) {
5957                        rec.key.requestIntent.replaceExtras(intents != null ?
5958                                intents[intents.length - 1] : null);
5959                    }
5960                    if (intents != null) {
5961                        intents[intents.length-1] = rec.key.requestIntent;
5962                        rec.key.allIntents = intents;
5963                        rec.key.allResolvedTypes = resolvedTypes;
5964                    } else {
5965                        rec.key.allIntents = null;
5966                        rec.key.allResolvedTypes = null;
5967                    }
5968                }
5969                return rec;
5970            }
5971            rec.canceled = true;
5972            mIntentSenderRecords.remove(key);
5973        }
5974        if (noCreate) {
5975            return rec;
5976        }
5977        rec = new PendingIntentRecord(this, key, callingUid);
5978        mIntentSenderRecords.put(key, rec.ref);
5979        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5980            if (activity.pendingResults == null) {
5981                activity.pendingResults
5982                        = new HashSet<WeakReference<PendingIntentRecord>>();
5983            }
5984            activity.pendingResults.add(rec.ref);
5985        }
5986        return rec;
5987    }
5988
5989    @Override
5990    public void cancelIntentSender(IIntentSender sender) {
5991        if (!(sender instanceof PendingIntentRecord)) {
5992            return;
5993        }
5994        synchronized(this) {
5995            PendingIntentRecord rec = (PendingIntentRecord)sender;
5996            try {
5997                int uid = AppGlobals.getPackageManager()
5998                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5999                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6000                    String msg = "Permission Denial: cancelIntentSender() from pid="
6001                        + Binder.getCallingPid()
6002                        + ", uid=" + Binder.getCallingUid()
6003                        + " is not allowed to cancel packges "
6004                        + rec.key.packageName;
6005                    Slog.w(TAG, msg);
6006                    throw new SecurityException(msg);
6007                }
6008            } catch (RemoteException e) {
6009                throw new SecurityException(e);
6010            }
6011            cancelIntentSenderLocked(rec, true);
6012        }
6013    }
6014
6015    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6016        rec.canceled = true;
6017        mIntentSenderRecords.remove(rec.key);
6018        if (cleanActivity && rec.key.activity != null) {
6019            rec.key.activity.pendingResults.remove(rec.ref);
6020        }
6021    }
6022
6023    @Override
6024    public String getPackageForIntentSender(IIntentSender pendingResult) {
6025        if (!(pendingResult instanceof PendingIntentRecord)) {
6026            return null;
6027        }
6028        try {
6029            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6030            return res.key.packageName;
6031        } catch (ClassCastException e) {
6032        }
6033        return null;
6034    }
6035
6036    @Override
6037    public int getUidForIntentSender(IIntentSender sender) {
6038        if (sender instanceof PendingIntentRecord) {
6039            try {
6040                PendingIntentRecord res = (PendingIntentRecord)sender;
6041                return res.uid;
6042            } catch (ClassCastException e) {
6043            }
6044        }
6045        return -1;
6046    }
6047
6048    @Override
6049    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6050        if (!(pendingResult instanceof PendingIntentRecord)) {
6051            return false;
6052        }
6053        try {
6054            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6055            if (res.key.allIntents == null) {
6056                return false;
6057            }
6058            for (int i=0; i<res.key.allIntents.length; i++) {
6059                Intent intent = res.key.allIntents[i];
6060                if (intent.getPackage() != null && intent.getComponent() != null) {
6061                    return false;
6062                }
6063            }
6064            return true;
6065        } catch (ClassCastException e) {
6066        }
6067        return false;
6068    }
6069
6070    @Override
6071    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6072        if (!(pendingResult instanceof PendingIntentRecord)) {
6073            return false;
6074        }
6075        try {
6076            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6077            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6078                return true;
6079            }
6080            return false;
6081        } catch (ClassCastException e) {
6082        }
6083        return false;
6084    }
6085
6086    @Override
6087    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6088        if (!(pendingResult instanceof PendingIntentRecord)) {
6089            return null;
6090        }
6091        try {
6092            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6093            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6094        } catch (ClassCastException e) {
6095        }
6096        return null;
6097    }
6098
6099    @Override
6100    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6101        if (!(pendingResult instanceof PendingIntentRecord)) {
6102            return null;
6103        }
6104        try {
6105            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6106            Intent intent = res.key.requestIntent;
6107            if (intent != null) {
6108                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6109                        || res.lastTagPrefix.equals(prefix))) {
6110                    return res.lastTag;
6111                }
6112                res.lastTagPrefix = prefix;
6113                StringBuilder sb = new StringBuilder(128);
6114                if (prefix != null) {
6115                    sb.append(prefix);
6116                }
6117                if (intent.getAction() != null) {
6118                    sb.append(intent.getAction());
6119                } else if (intent.getComponent() != null) {
6120                    intent.getComponent().appendShortString(sb);
6121                } else {
6122                    sb.append("?");
6123                }
6124                return res.lastTag = sb.toString();
6125            }
6126        } catch (ClassCastException e) {
6127        }
6128        return null;
6129    }
6130
6131    @Override
6132    public void setProcessLimit(int max) {
6133        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6134                "setProcessLimit()");
6135        synchronized (this) {
6136            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6137            mProcessLimitOverride = max;
6138        }
6139        trimApplications();
6140    }
6141
6142    @Override
6143    public int getProcessLimit() {
6144        synchronized (this) {
6145            return mProcessLimitOverride;
6146        }
6147    }
6148
6149    void foregroundTokenDied(ForegroundToken token) {
6150        synchronized (ActivityManagerService.this) {
6151            synchronized (mPidsSelfLocked) {
6152                ForegroundToken cur
6153                    = mForegroundProcesses.get(token.pid);
6154                if (cur != token) {
6155                    return;
6156                }
6157                mForegroundProcesses.remove(token.pid);
6158                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6159                if (pr == null) {
6160                    return;
6161                }
6162                pr.forcingToForeground = null;
6163                updateProcessForegroundLocked(pr, false, false);
6164            }
6165            updateOomAdjLocked();
6166        }
6167    }
6168
6169    @Override
6170    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6171        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6172                "setProcessForeground()");
6173        synchronized(this) {
6174            boolean changed = false;
6175
6176            synchronized (mPidsSelfLocked) {
6177                ProcessRecord pr = mPidsSelfLocked.get(pid);
6178                if (pr == null && isForeground) {
6179                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6180                    return;
6181                }
6182                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6183                if (oldToken != null) {
6184                    oldToken.token.unlinkToDeath(oldToken, 0);
6185                    mForegroundProcesses.remove(pid);
6186                    if (pr != null) {
6187                        pr.forcingToForeground = null;
6188                    }
6189                    changed = true;
6190                }
6191                if (isForeground && token != null) {
6192                    ForegroundToken newToken = new ForegroundToken() {
6193                        @Override
6194                        public void binderDied() {
6195                            foregroundTokenDied(this);
6196                        }
6197                    };
6198                    newToken.pid = pid;
6199                    newToken.token = token;
6200                    try {
6201                        token.linkToDeath(newToken, 0);
6202                        mForegroundProcesses.put(pid, newToken);
6203                        pr.forcingToForeground = token;
6204                        changed = true;
6205                    } catch (RemoteException e) {
6206                        // If the process died while doing this, we will later
6207                        // do the cleanup with the process death link.
6208                    }
6209                }
6210            }
6211
6212            if (changed) {
6213                updateOomAdjLocked();
6214            }
6215        }
6216    }
6217
6218    // =========================================================
6219    // PERMISSIONS
6220    // =========================================================
6221
6222    static class PermissionController extends IPermissionController.Stub {
6223        ActivityManagerService mActivityManagerService;
6224        PermissionController(ActivityManagerService activityManagerService) {
6225            mActivityManagerService = activityManagerService;
6226        }
6227
6228        @Override
6229        public boolean checkPermission(String permission, int pid, int uid) {
6230            return mActivityManagerService.checkPermission(permission, pid,
6231                    uid) == PackageManager.PERMISSION_GRANTED;
6232        }
6233    }
6234
6235    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6236        @Override
6237        public int checkComponentPermission(String permission, int pid, int uid,
6238                int owningUid, boolean exported) {
6239            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6240                    owningUid, exported);
6241        }
6242
6243        @Override
6244        public Object getAMSLock() {
6245            return ActivityManagerService.this;
6246        }
6247    }
6248
6249    /**
6250     * This can be called with or without the global lock held.
6251     */
6252    int checkComponentPermission(String permission, int pid, int uid,
6253            int owningUid, boolean exported) {
6254        // We might be performing an operation on behalf of an indirect binder
6255        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6256        // client identity accordingly before proceeding.
6257        Identity tlsIdentity = sCallerIdentity.get();
6258        if (tlsIdentity != null) {
6259            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6260                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6261            uid = tlsIdentity.uid;
6262            pid = tlsIdentity.pid;
6263        }
6264
6265        if (pid == MY_PID) {
6266            return PackageManager.PERMISSION_GRANTED;
6267        }
6268
6269        return ActivityManager.checkComponentPermission(permission, uid,
6270                owningUid, exported);
6271    }
6272
6273    /**
6274     * As the only public entry point for permissions checking, this method
6275     * can enforce the semantic that requesting a check on a null global
6276     * permission is automatically denied.  (Internally a null permission
6277     * string is used when calling {@link #checkComponentPermission} in cases
6278     * when only uid-based security is needed.)
6279     *
6280     * This can be called with or without the global lock held.
6281     */
6282    @Override
6283    public int checkPermission(String permission, int pid, int uid) {
6284        if (permission == null) {
6285            return PackageManager.PERMISSION_DENIED;
6286        }
6287        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6288    }
6289
6290    /**
6291     * Binder IPC calls go through the public entry point.
6292     * This can be called with or without the global lock held.
6293     */
6294    int checkCallingPermission(String permission) {
6295        return checkPermission(permission,
6296                Binder.getCallingPid(),
6297                UserHandle.getAppId(Binder.getCallingUid()));
6298    }
6299
6300    /**
6301     * This can be called with or without the global lock held.
6302     */
6303    void enforceCallingPermission(String permission, String func) {
6304        if (checkCallingPermission(permission)
6305                == PackageManager.PERMISSION_GRANTED) {
6306            return;
6307        }
6308
6309        String msg = "Permission Denial: " + func + " from pid="
6310                + Binder.getCallingPid()
6311                + ", uid=" + Binder.getCallingUid()
6312                + " requires " + permission;
6313        Slog.w(TAG, msg);
6314        throw new SecurityException(msg);
6315    }
6316
6317    /**
6318     * Determine if UID is holding permissions required to access {@link Uri} in
6319     * the given {@link ProviderInfo}. Final permission checking is always done
6320     * in {@link ContentProvider}.
6321     */
6322    private final boolean checkHoldingPermissionsLocked(
6323            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6324        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6325                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6326        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6327            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6328                    != PERMISSION_GRANTED) {
6329                return false;
6330            }
6331        }
6332        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6333    }
6334
6335    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6336            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6337        if (pi.applicationInfo.uid == uid) {
6338            return true;
6339        } else if (!pi.exported) {
6340            return false;
6341        }
6342
6343        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6344        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6345        try {
6346            // check if target holds top-level <provider> permissions
6347            if (!readMet && pi.readPermission != null && considerUidPermissions
6348                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6349                readMet = true;
6350            }
6351            if (!writeMet && pi.writePermission != null && considerUidPermissions
6352                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6353                writeMet = true;
6354            }
6355
6356            // track if unprotected read/write is allowed; any denied
6357            // <path-permission> below removes this ability
6358            boolean allowDefaultRead = pi.readPermission == null;
6359            boolean allowDefaultWrite = pi.writePermission == null;
6360
6361            // check if target holds any <path-permission> that match uri
6362            final PathPermission[] pps = pi.pathPermissions;
6363            if (pps != null) {
6364                final String path = grantUri.uri.getPath();
6365                int i = pps.length;
6366                while (i > 0 && (!readMet || !writeMet)) {
6367                    i--;
6368                    PathPermission pp = pps[i];
6369                    if (pp.match(path)) {
6370                        if (!readMet) {
6371                            final String pprperm = pp.getReadPermission();
6372                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6373                                    + pprperm + " for " + pp.getPath()
6374                                    + ": match=" + pp.match(path)
6375                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6376                            if (pprperm != null) {
6377                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6378                                        == PERMISSION_GRANTED) {
6379                                    readMet = true;
6380                                } else {
6381                                    allowDefaultRead = false;
6382                                }
6383                            }
6384                        }
6385                        if (!writeMet) {
6386                            final String ppwperm = pp.getWritePermission();
6387                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6388                                    + ppwperm + " for " + pp.getPath()
6389                                    + ": match=" + pp.match(path)
6390                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6391                            if (ppwperm != null) {
6392                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6393                                        == PERMISSION_GRANTED) {
6394                                    writeMet = true;
6395                                } else {
6396                                    allowDefaultWrite = false;
6397                                }
6398                            }
6399                        }
6400                    }
6401                }
6402            }
6403
6404            // grant unprotected <provider> read/write, if not blocked by
6405            // <path-permission> above
6406            if (allowDefaultRead) readMet = true;
6407            if (allowDefaultWrite) writeMet = true;
6408
6409        } catch (RemoteException e) {
6410            return false;
6411        }
6412
6413        return readMet && writeMet;
6414    }
6415
6416    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6417        ProviderInfo pi = null;
6418        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6419        if (cpr != null) {
6420            pi = cpr.info;
6421        } else {
6422            try {
6423                pi = AppGlobals.getPackageManager().resolveContentProvider(
6424                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6425            } catch (RemoteException ex) {
6426            }
6427        }
6428        return pi;
6429    }
6430
6431    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6432        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6433        if (targetUris != null) {
6434            return targetUris.get(grantUri);
6435        }
6436        return null;
6437    }
6438
6439    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6440            String targetPkg, int targetUid, GrantUri grantUri) {
6441        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6442        if (targetUris == null) {
6443            targetUris = Maps.newArrayMap();
6444            mGrantedUriPermissions.put(targetUid, targetUris);
6445        }
6446
6447        UriPermission perm = targetUris.get(grantUri);
6448        if (perm == null) {
6449            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6450            targetUris.put(grantUri, perm);
6451        }
6452
6453        return perm;
6454    }
6455
6456    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6457            final int modeFlags) {
6458        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6459        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6460                : UriPermission.STRENGTH_OWNED;
6461
6462        // Root gets to do everything.
6463        if (uid == 0) {
6464            return true;
6465        }
6466
6467        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6468        if (perms == null) return false;
6469
6470        // First look for exact match
6471        final UriPermission exactPerm = perms.get(grantUri);
6472        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6473            return true;
6474        }
6475
6476        // No exact match, look for prefixes
6477        final int N = perms.size();
6478        for (int i = 0; i < N; i++) {
6479            final UriPermission perm = perms.valueAt(i);
6480            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6481                    && perm.getStrength(modeFlags) >= minStrength) {
6482                return true;
6483            }
6484        }
6485
6486        return false;
6487    }
6488
6489    @Override
6490    public int checkUriPermission(Uri uri, int pid, int uid,
6491            final int modeFlags, int userId) {
6492        enforceNotIsolatedCaller("checkUriPermission");
6493
6494        // Another redirected-binder-call permissions check as in
6495        // {@link checkComponentPermission}.
6496        Identity tlsIdentity = sCallerIdentity.get();
6497        if (tlsIdentity != null) {
6498            uid = tlsIdentity.uid;
6499            pid = tlsIdentity.pid;
6500        }
6501
6502        // Our own process gets to do everything.
6503        if (pid == MY_PID) {
6504            return PackageManager.PERMISSION_GRANTED;
6505        }
6506        synchronized (this) {
6507            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6508                    ? PackageManager.PERMISSION_GRANTED
6509                    : PackageManager.PERMISSION_DENIED;
6510        }
6511    }
6512
6513    /**
6514     * Check if the targetPkg can be granted permission to access uri by
6515     * the callingUid using the given modeFlags.  Throws a security exception
6516     * if callingUid is not allowed to do this.  Returns the uid of the target
6517     * if the URI permission grant should be performed; returns -1 if it is not
6518     * needed (for example targetPkg already has permission to access the URI).
6519     * If you already know the uid of the target, you can supply it in
6520     * lastTargetUid else set that to -1.
6521     */
6522    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6523            final int modeFlags, int lastTargetUid) {
6524        if (!Intent.isAccessUriMode(modeFlags)) {
6525            return -1;
6526        }
6527
6528        if (targetPkg != null) {
6529            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6530                    "Checking grant " + targetPkg + " permission to " + grantUri);
6531        }
6532
6533        final IPackageManager pm = AppGlobals.getPackageManager();
6534
6535        // If this is not a content: uri, we can't do anything with it.
6536        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6537            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6538                    "Can't grant URI permission for non-content URI: " + grantUri);
6539            return -1;
6540        }
6541
6542        final String authority = grantUri.uri.getAuthority();
6543        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6544        if (pi == null) {
6545            Slog.w(TAG, "No content provider found for permission check: " +
6546                    grantUri.uri.toSafeString());
6547            return -1;
6548        }
6549
6550        int targetUid = lastTargetUid;
6551        if (targetUid < 0 && targetPkg != null) {
6552            try {
6553                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6554                if (targetUid < 0) {
6555                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6556                            "Can't grant URI permission no uid for: " + targetPkg);
6557                    return -1;
6558                }
6559            } catch (RemoteException ex) {
6560                return -1;
6561            }
6562        }
6563
6564        if (targetUid >= 0) {
6565            // First...  does the target actually need this permission?
6566            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6567                // No need to grant the target this permission.
6568                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6569                        "Target " + targetPkg + " already has full permission to " + grantUri);
6570                return -1;
6571            }
6572        } else {
6573            // First...  there is no target package, so can anyone access it?
6574            boolean allowed = pi.exported;
6575            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6576                if (pi.readPermission != null) {
6577                    allowed = false;
6578                }
6579            }
6580            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6581                if (pi.writePermission != null) {
6582                    allowed = false;
6583                }
6584            }
6585            if (allowed) {
6586                return -1;
6587            }
6588        }
6589
6590        /* There is a special cross user grant if:
6591         * - The target is on another user.
6592         * - Apps on the current user can access the uri without any uid permissions.
6593         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6594         * grant uri permissions.
6595         */
6596        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6597                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6598                modeFlags, false /*without considering the uid permissions*/);
6599
6600        // Second...  is the provider allowing granting of URI permissions?
6601        if (!specialCrossUserGrant) {
6602            if (!pi.grantUriPermissions) {
6603                throw new SecurityException("Provider " + pi.packageName
6604                        + "/" + pi.name
6605                        + " does not allow granting of Uri permissions (uri "
6606                        + grantUri + ")");
6607            }
6608            if (pi.uriPermissionPatterns != null) {
6609                final int N = pi.uriPermissionPatterns.length;
6610                boolean allowed = false;
6611                for (int i=0; i<N; i++) {
6612                    if (pi.uriPermissionPatterns[i] != null
6613                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6614                        allowed = true;
6615                        break;
6616                    }
6617                }
6618                if (!allowed) {
6619                    throw new SecurityException("Provider " + pi.packageName
6620                            + "/" + pi.name
6621                            + " does not allow granting of permission to path of Uri "
6622                            + grantUri);
6623                }
6624            }
6625        }
6626
6627        // Third...  does the caller itself have permission to access
6628        // this uri?
6629        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6630            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6631                // Require they hold a strong enough Uri permission
6632                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6633                    throw new SecurityException("Uid " + callingUid
6634                            + " does not have permission to uri " + grantUri);
6635                }
6636            }
6637        }
6638        return targetUid;
6639    }
6640
6641    @Override
6642    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6643            final int modeFlags, int userId) {
6644        enforceNotIsolatedCaller("checkGrantUriPermission");
6645        synchronized(this) {
6646            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6647                    new GrantUri(userId, uri, false), modeFlags, -1);
6648        }
6649    }
6650
6651    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6652            final int modeFlags, UriPermissionOwner owner) {
6653        if (!Intent.isAccessUriMode(modeFlags)) {
6654            return;
6655        }
6656
6657        // So here we are: the caller has the assumed permission
6658        // to the uri, and the target doesn't.  Let's now give this to
6659        // the target.
6660
6661        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6662                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6663
6664        final String authority = grantUri.uri.getAuthority();
6665        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6666        if (pi == null) {
6667            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6668            return;
6669        }
6670
6671        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6672            grantUri.prefix = true;
6673        }
6674        final UriPermission perm = findOrCreateUriPermissionLocked(
6675                pi.packageName, targetPkg, targetUid, grantUri);
6676        perm.grantModes(modeFlags, owner);
6677    }
6678
6679    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6680            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6681        if (targetPkg == null) {
6682            throw new NullPointerException("targetPkg");
6683        }
6684        int targetUid;
6685        final IPackageManager pm = AppGlobals.getPackageManager();
6686        try {
6687            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6688        } catch (RemoteException ex) {
6689            return;
6690        }
6691
6692        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6693                targetUid);
6694        if (targetUid < 0) {
6695            return;
6696        }
6697
6698        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6699                owner);
6700    }
6701
6702    static class NeededUriGrants extends ArrayList<GrantUri> {
6703        final String targetPkg;
6704        final int targetUid;
6705        final int flags;
6706
6707        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6708            this.targetPkg = targetPkg;
6709            this.targetUid = targetUid;
6710            this.flags = flags;
6711        }
6712    }
6713
6714    /**
6715     * Like checkGrantUriPermissionLocked, but takes an Intent.
6716     */
6717    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6718            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6719        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6720                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6721                + " clip=" + (intent != null ? intent.getClipData() : null)
6722                + " from " + intent + "; flags=0x"
6723                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6724
6725        if (targetPkg == null) {
6726            throw new NullPointerException("targetPkg");
6727        }
6728
6729        if (intent == null) {
6730            return null;
6731        }
6732        Uri data = intent.getData();
6733        ClipData clip = intent.getClipData();
6734        if (data == null && clip == null) {
6735            return null;
6736        }
6737        // Default userId for uris in the intent (if they don't specify it themselves)
6738        int contentUserHint = intent.getContentUserHint();
6739        if (contentUserHint == UserHandle.USER_CURRENT) {
6740            contentUserHint = UserHandle.getUserId(callingUid);
6741        }
6742        final IPackageManager pm = AppGlobals.getPackageManager();
6743        int targetUid;
6744        if (needed != null) {
6745            targetUid = needed.targetUid;
6746        } else {
6747            try {
6748                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6749            } catch (RemoteException ex) {
6750                return null;
6751            }
6752            if (targetUid < 0) {
6753                if (DEBUG_URI_PERMISSION) {
6754                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6755                            + " on user " + targetUserId);
6756                }
6757                return null;
6758            }
6759        }
6760        if (data != null) {
6761            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6762            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6763                    targetUid);
6764            if (targetUid > 0) {
6765                if (needed == null) {
6766                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6767                }
6768                needed.add(grantUri);
6769            }
6770        }
6771        if (clip != null) {
6772            for (int i=0; i<clip.getItemCount(); i++) {
6773                Uri uri = clip.getItemAt(i).getUri();
6774                if (uri != null) {
6775                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6776                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6777                            targetUid);
6778                    if (targetUid > 0) {
6779                        if (needed == null) {
6780                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6781                        }
6782                        needed.add(grantUri);
6783                    }
6784                } else {
6785                    Intent clipIntent = clip.getItemAt(i).getIntent();
6786                    if (clipIntent != null) {
6787                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6788                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6789                        if (newNeeded != null) {
6790                            needed = newNeeded;
6791                        }
6792                    }
6793                }
6794            }
6795        }
6796
6797        return needed;
6798    }
6799
6800    /**
6801     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6802     */
6803    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6804            UriPermissionOwner owner) {
6805        if (needed != null) {
6806            for (int i=0; i<needed.size(); i++) {
6807                GrantUri grantUri = needed.get(i);
6808                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6809                        grantUri, needed.flags, owner);
6810            }
6811        }
6812    }
6813
6814    void grantUriPermissionFromIntentLocked(int callingUid,
6815            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6816        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6817                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6818        if (needed == null) {
6819            return;
6820        }
6821
6822        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6823    }
6824
6825    @Override
6826    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6827            final int modeFlags, int userId) {
6828        enforceNotIsolatedCaller("grantUriPermission");
6829        GrantUri grantUri = new GrantUri(userId, uri, false);
6830        synchronized(this) {
6831            final ProcessRecord r = getRecordForAppLocked(caller);
6832            if (r == null) {
6833                throw new SecurityException("Unable to find app for caller "
6834                        + caller
6835                        + " when granting permission to uri " + grantUri);
6836            }
6837            if (targetPkg == null) {
6838                throw new IllegalArgumentException("null target");
6839            }
6840            if (grantUri == null) {
6841                throw new IllegalArgumentException("null uri");
6842            }
6843
6844            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6845                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6846                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6847                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6848
6849            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6850                    UserHandle.getUserId(r.uid));
6851        }
6852    }
6853
6854    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6855        if (perm.modeFlags == 0) {
6856            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6857                    perm.targetUid);
6858            if (perms != null) {
6859                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6860                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6861
6862                perms.remove(perm.uri);
6863                if (perms.isEmpty()) {
6864                    mGrantedUriPermissions.remove(perm.targetUid);
6865                }
6866            }
6867        }
6868    }
6869
6870    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6871        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6872
6873        final IPackageManager pm = AppGlobals.getPackageManager();
6874        final String authority = grantUri.uri.getAuthority();
6875        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6876        if (pi == null) {
6877            Slog.w(TAG, "No content provider found for permission revoke: "
6878                    + grantUri.toSafeString());
6879            return;
6880        }
6881
6882        // Does the caller have this permission on the URI?
6883        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6884            // Right now, if you are not the original owner of the permission,
6885            // you are not allowed to revoke it.
6886            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6887                throw new SecurityException("Uid " + callingUid
6888                        + " does not have permission to uri " + grantUri);
6889            //}
6890        }
6891
6892        boolean persistChanged = false;
6893
6894        // Go through all of the permissions and remove any that match.
6895        int N = mGrantedUriPermissions.size();
6896        for (int i = 0; i < N; i++) {
6897            final int targetUid = mGrantedUriPermissions.keyAt(i);
6898            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6899
6900            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6901                final UriPermission perm = it.next();
6902                if (perm.uri.sourceUserId == grantUri.sourceUserId
6903                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6904                    if (DEBUG_URI_PERMISSION)
6905                        Slog.v(TAG,
6906                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6907                    persistChanged |= perm.revokeModes(
6908                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6909                    if (perm.modeFlags == 0) {
6910                        it.remove();
6911                    }
6912                }
6913            }
6914
6915            if (perms.isEmpty()) {
6916                mGrantedUriPermissions.remove(targetUid);
6917                N--;
6918                i--;
6919            }
6920        }
6921
6922        if (persistChanged) {
6923            schedulePersistUriGrants();
6924        }
6925    }
6926
6927    @Override
6928    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6929            int userId) {
6930        enforceNotIsolatedCaller("revokeUriPermission");
6931        synchronized(this) {
6932            final ProcessRecord r = getRecordForAppLocked(caller);
6933            if (r == null) {
6934                throw new SecurityException("Unable to find app for caller "
6935                        + caller
6936                        + " when revoking permission to uri " + uri);
6937            }
6938            if (uri == null) {
6939                Slog.w(TAG, "revokeUriPermission: null uri");
6940                return;
6941            }
6942
6943            if (!Intent.isAccessUriMode(modeFlags)) {
6944                return;
6945            }
6946
6947            final IPackageManager pm = AppGlobals.getPackageManager();
6948            final String authority = uri.getAuthority();
6949            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6950            if (pi == null) {
6951                Slog.w(TAG, "No content provider found for permission revoke: "
6952                        + uri.toSafeString());
6953                return;
6954            }
6955
6956            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6957        }
6958    }
6959
6960    /**
6961     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6962     * given package.
6963     *
6964     * @param packageName Package name to match, or {@code null} to apply to all
6965     *            packages.
6966     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6967     *            to all users.
6968     * @param persistable If persistable grants should be removed.
6969     */
6970    private void removeUriPermissionsForPackageLocked(
6971            String packageName, int userHandle, boolean persistable) {
6972        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6973            throw new IllegalArgumentException("Must narrow by either package or user");
6974        }
6975
6976        boolean persistChanged = false;
6977
6978        int N = mGrantedUriPermissions.size();
6979        for (int i = 0; i < N; i++) {
6980            final int targetUid = mGrantedUriPermissions.keyAt(i);
6981            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6982
6983            // Only inspect grants matching user
6984            if (userHandle == UserHandle.USER_ALL
6985                    || userHandle == UserHandle.getUserId(targetUid)) {
6986                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6987                    final UriPermission perm = it.next();
6988
6989                    // Only inspect grants matching package
6990                    if (packageName == null || perm.sourcePkg.equals(packageName)
6991                            || perm.targetPkg.equals(packageName)) {
6992                        persistChanged |= perm.revokeModes(
6993                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6994
6995                        // Only remove when no modes remain; any persisted grants
6996                        // will keep this alive.
6997                        if (perm.modeFlags == 0) {
6998                            it.remove();
6999                        }
7000                    }
7001                }
7002
7003                if (perms.isEmpty()) {
7004                    mGrantedUriPermissions.remove(targetUid);
7005                    N--;
7006                    i--;
7007                }
7008            }
7009        }
7010
7011        if (persistChanged) {
7012            schedulePersistUriGrants();
7013        }
7014    }
7015
7016    @Override
7017    public IBinder newUriPermissionOwner(String name) {
7018        enforceNotIsolatedCaller("newUriPermissionOwner");
7019        synchronized(this) {
7020            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7021            return owner.getExternalTokenLocked();
7022        }
7023    }
7024
7025    @Override
7026    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7027            final int modeFlags, int sourceUserId, int targetUserId) {
7028        synchronized(this) {
7029            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7030            if (owner == null) {
7031                throw new IllegalArgumentException("Unknown owner: " + token);
7032            }
7033            if (fromUid != Binder.getCallingUid()) {
7034                if (Binder.getCallingUid() != Process.myUid()) {
7035                    // Only system code can grant URI permissions on behalf
7036                    // of other users.
7037                    throw new SecurityException("nice try");
7038                }
7039            }
7040            if (targetPkg == null) {
7041                throw new IllegalArgumentException("null target");
7042            }
7043            if (uri == null) {
7044                throw new IllegalArgumentException("null uri");
7045            }
7046
7047            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7048                    modeFlags, owner, targetUserId);
7049        }
7050    }
7051
7052    @Override
7053    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7054        synchronized(this) {
7055            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7056            if (owner == null) {
7057                throw new IllegalArgumentException("Unknown owner: " + token);
7058            }
7059
7060            if (uri == null) {
7061                owner.removeUriPermissionsLocked(mode);
7062            } else {
7063                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7064            }
7065        }
7066    }
7067
7068    private void schedulePersistUriGrants() {
7069        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7070            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7071                    10 * DateUtils.SECOND_IN_MILLIS);
7072        }
7073    }
7074
7075    private void writeGrantedUriPermissions() {
7076        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7077
7078        // Snapshot permissions so we can persist without lock
7079        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7080        synchronized (this) {
7081            final int size = mGrantedUriPermissions.size();
7082            for (int i = 0; i < size; i++) {
7083                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7084                for (UriPermission perm : perms.values()) {
7085                    if (perm.persistedModeFlags != 0) {
7086                        persist.add(perm.snapshot());
7087                    }
7088                }
7089            }
7090        }
7091
7092        FileOutputStream fos = null;
7093        try {
7094            fos = mGrantFile.startWrite();
7095
7096            XmlSerializer out = new FastXmlSerializer();
7097            out.setOutput(fos, "utf-8");
7098            out.startDocument(null, true);
7099            out.startTag(null, TAG_URI_GRANTS);
7100            for (UriPermission.Snapshot perm : persist) {
7101                out.startTag(null, TAG_URI_GRANT);
7102                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7103                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7104                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7105                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7106                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7107                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7108                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7109                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7110                out.endTag(null, TAG_URI_GRANT);
7111            }
7112            out.endTag(null, TAG_URI_GRANTS);
7113            out.endDocument();
7114
7115            mGrantFile.finishWrite(fos);
7116        } catch (IOException e) {
7117            if (fos != null) {
7118                mGrantFile.failWrite(fos);
7119            }
7120        }
7121    }
7122
7123    private void readGrantedUriPermissionsLocked() {
7124        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7125
7126        final long now = System.currentTimeMillis();
7127
7128        FileInputStream fis = null;
7129        try {
7130            fis = mGrantFile.openRead();
7131            final XmlPullParser in = Xml.newPullParser();
7132            in.setInput(fis, null);
7133
7134            int type;
7135            while ((type = in.next()) != END_DOCUMENT) {
7136                final String tag = in.getName();
7137                if (type == START_TAG) {
7138                    if (TAG_URI_GRANT.equals(tag)) {
7139                        final int sourceUserId;
7140                        final int targetUserId;
7141                        final int userHandle = readIntAttribute(in,
7142                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7143                        if (userHandle != UserHandle.USER_NULL) {
7144                            // For backwards compatibility.
7145                            sourceUserId = userHandle;
7146                            targetUserId = userHandle;
7147                        } else {
7148                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7149                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7150                        }
7151                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7152                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7153                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7154                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7155                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7156                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7157
7158                        // Sanity check that provider still belongs to source package
7159                        final ProviderInfo pi = getProviderInfoLocked(
7160                                uri.getAuthority(), sourceUserId);
7161                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7162                            int targetUid = -1;
7163                            try {
7164                                targetUid = AppGlobals.getPackageManager()
7165                                        .getPackageUid(targetPkg, targetUserId);
7166                            } catch (RemoteException e) {
7167                            }
7168                            if (targetUid != -1) {
7169                                final UriPermission perm = findOrCreateUriPermissionLocked(
7170                                        sourcePkg, targetPkg, targetUid,
7171                                        new GrantUri(sourceUserId, uri, prefix));
7172                                perm.initPersistedModes(modeFlags, createdTime);
7173                            }
7174                        } else {
7175                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7176                                    + " but instead found " + pi);
7177                        }
7178                    }
7179                }
7180            }
7181        } catch (FileNotFoundException e) {
7182            // Missing grants is okay
7183        } catch (IOException e) {
7184            Log.wtf(TAG, "Failed reading Uri grants", e);
7185        } catch (XmlPullParserException e) {
7186            Log.wtf(TAG, "Failed reading Uri grants", e);
7187        } finally {
7188            IoUtils.closeQuietly(fis);
7189        }
7190    }
7191
7192    @Override
7193    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7194        enforceNotIsolatedCaller("takePersistableUriPermission");
7195
7196        Preconditions.checkFlagsArgument(modeFlags,
7197                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7198
7199        synchronized (this) {
7200            final int callingUid = Binder.getCallingUid();
7201            boolean persistChanged = false;
7202            GrantUri grantUri = new GrantUri(userId, uri, false);
7203
7204            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7205                    new GrantUri(userId, uri, false));
7206            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7207                    new GrantUri(userId, uri, true));
7208
7209            final boolean exactValid = (exactPerm != null)
7210                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7211            final boolean prefixValid = (prefixPerm != null)
7212                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7213
7214            if (!(exactValid || prefixValid)) {
7215                throw new SecurityException("No persistable permission grants found for UID "
7216                        + callingUid + " and Uri " + grantUri.toSafeString());
7217            }
7218
7219            if (exactValid) {
7220                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7221            }
7222            if (prefixValid) {
7223                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7224            }
7225
7226            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7227
7228            if (persistChanged) {
7229                schedulePersistUriGrants();
7230            }
7231        }
7232    }
7233
7234    @Override
7235    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7236        enforceNotIsolatedCaller("releasePersistableUriPermission");
7237
7238        Preconditions.checkFlagsArgument(modeFlags,
7239                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7240
7241        synchronized (this) {
7242            final int callingUid = Binder.getCallingUid();
7243            boolean persistChanged = false;
7244
7245            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7246                    new GrantUri(userId, uri, false));
7247            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7248                    new GrantUri(userId, uri, true));
7249            if (exactPerm == null && prefixPerm == null) {
7250                throw new SecurityException("No permission grants found for UID " + callingUid
7251                        + " and Uri " + uri.toSafeString());
7252            }
7253
7254            if (exactPerm != null) {
7255                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7256                removeUriPermissionIfNeededLocked(exactPerm);
7257            }
7258            if (prefixPerm != null) {
7259                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7260                removeUriPermissionIfNeededLocked(prefixPerm);
7261            }
7262
7263            if (persistChanged) {
7264                schedulePersistUriGrants();
7265            }
7266        }
7267    }
7268
7269    /**
7270     * Prune any older {@link UriPermission} for the given UID until outstanding
7271     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7272     *
7273     * @return if any mutations occured that require persisting.
7274     */
7275    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7276        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7277        if (perms == null) return false;
7278        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7279
7280        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7281        for (UriPermission perm : perms.values()) {
7282            if (perm.persistedModeFlags != 0) {
7283                persisted.add(perm);
7284            }
7285        }
7286
7287        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7288        if (trimCount <= 0) return false;
7289
7290        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7291        for (int i = 0; i < trimCount; i++) {
7292            final UriPermission perm = persisted.get(i);
7293
7294            if (DEBUG_URI_PERMISSION) {
7295                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7296            }
7297
7298            perm.releasePersistableModes(~0);
7299            removeUriPermissionIfNeededLocked(perm);
7300        }
7301
7302        return true;
7303    }
7304
7305    @Override
7306    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7307            String packageName, boolean incoming) {
7308        enforceNotIsolatedCaller("getPersistedUriPermissions");
7309        Preconditions.checkNotNull(packageName, "packageName");
7310
7311        final int callingUid = Binder.getCallingUid();
7312        final IPackageManager pm = AppGlobals.getPackageManager();
7313        try {
7314            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7315            if (packageUid != callingUid) {
7316                throw new SecurityException(
7317                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7318            }
7319        } catch (RemoteException e) {
7320            throw new SecurityException("Failed to verify package name ownership");
7321        }
7322
7323        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7324        synchronized (this) {
7325            if (incoming) {
7326                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7327                        callingUid);
7328                if (perms == null) {
7329                    Slog.w(TAG, "No permission grants found for " + packageName);
7330                } else {
7331                    for (UriPermission perm : perms.values()) {
7332                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7333                            result.add(perm.buildPersistedPublicApiObject());
7334                        }
7335                    }
7336                }
7337            } else {
7338                final int size = mGrantedUriPermissions.size();
7339                for (int i = 0; i < size; i++) {
7340                    final ArrayMap<GrantUri, UriPermission> perms =
7341                            mGrantedUriPermissions.valueAt(i);
7342                    for (UriPermission perm : perms.values()) {
7343                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7344                            result.add(perm.buildPersistedPublicApiObject());
7345                        }
7346                    }
7347                }
7348            }
7349        }
7350        return new ParceledListSlice<android.content.UriPermission>(result);
7351    }
7352
7353    @Override
7354    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7355        synchronized (this) {
7356            ProcessRecord app =
7357                who != null ? getRecordForAppLocked(who) : null;
7358            if (app == null) return;
7359
7360            Message msg = Message.obtain();
7361            msg.what = WAIT_FOR_DEBUGGER_MSG;
7362            msg.obj = app;
7363            msg.arg1 = waiting ? 1 : 0;
7364            mHandler.sendMessage(msg);
7365        }
7366    }
7367
7368    @Override
7369    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7370        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7371        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7372        outInfo.availMem = Process.getFreeMemory();
7373        outInfo.totalMem = Process.getTotalMemory();
7374        outInfo.threshold = homeAppMem;
7375        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7376        outInfo.hiddenAppThreshold = cachedAppMem;
7377        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7378                ProcessList.SERVICE_ADJ);
7379        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7380                ProcessList.VISIBLE_APP_ADJ);
7381        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7382                ProcessList.FOREGROUND_APP_ADJ);
7383    }
7384
7385    // =========================================================
7386    // TASK MANAGEMENT
7387    // =========================================================
7388
7389    @Override
7390    public List<IAppTask> getAppTasks() {
7391        final PackageManager pm = mContext.getPackageManager();
7392        int callingUid = Binder.getCallingUid();
7393        long ident = Binder.clearCallingIdentity();
7394
7395        // Compose the list of packages for this id to test against
7396        HashSet<String> packages = new HashSet<String>();
7397        String[] uidPackages = pm.getPackagesForUid(callingUid);
7398        for (int i = 0; i < uidPackages.length; i++) {
7399            packages.add(uidPackages[i]);
7400        }
7401
7402        synchronized(this) {
7403            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7404            try {
7405                if (localLOGV) Slog.v(TAG, "getAppTasks");
7406
7407                final int N = mRecentTasks.size();
7408                for (int i = 0; i < N; i++) {
7409                    TaskRecord tr = mRecentTasks.get(i);
7410                    // Skip tasks that are not created by the caller
7411                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7412                        ActivityManager.RecentTaskInfo taskInfo =
7413                                createRecentTaskInfoFromTaskRecord(tr);
7414                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7415                        list.add(taskImpl);
7416                    }
7417                }
7418            } finally {
7419                Binder.restoreCallingIdentity(ident);
7420            }
7421            return list;
7422        }
7423    }
7424
7425    @Override
7426    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7427        final int callingUid = Binder.getCallingUid();
7428        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7429
7430        synchronized(this) {
7431            if (localLOGV) Slog.v(
7432                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7433
7434            final boolean allowed = checkCallingPermission(
7435                    android.Manifest.permission.GET_TASKS)
7436                    == PackageManager.PERMISSION_GRANTED;
7437            if (!allowed) {
7438                Slog.w(TAG, "getTasks: caller " + callingUid
7439                        + " does not hold GET_TASKS; limiting output");
7440            }
7441
7442            // TODO: Improve with MRU list from all ActivityStacks.
7443            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7444        }
7445
7446        return list;
7447    }
7448
7449    TaskRecord getMostRecentTask() {
7450        return mRecentTasks.get(0);
7451    }
7452
7453    /**
7454     * Creates a new RecentTaskInfo from a TaskRecord.
7455     */
7456    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7457        // Update the task description to reflect any changes in the task stack
7458        tr.updateTaskDescription();
7459
7460        // Compose the recent task info
7461        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7462        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7463        rti.persistentId = tr.taskId;
7464        rti.baseIntent = new Intent(tr.getBaseIntent());
7465        rti.origActivity = tr.origActivity;
7466        rti.description = tr.lastDescription;
7467        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7468        rti.userId = tr.userId;
7469        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7470        rti.firstActiveTime = tr.firstActiveTime;
7471        rti.lastActiveTime = tr.lastActiveTime;
7472        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7473        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7474        return rti;
7475    }
7476
7477    @Override
7478    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7479        final int callingUid = Binder.getCallingUid();
7480        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7481                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7482
7483        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7484        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7485        synchronized (this) {
7486            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7487                    == PackageManager.PERMISSION_GRANTED;
7488            if (!allowed) {
7489                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7490                        + " does not hold GET_TASKS; limiting output");
7491            }
7492            final boolean detailed = checkCallingPermission(
7493                    android.Manifest.permission.GET_DETAILED_TASKS)
7494                    == PackageManager.PERMISSION_GRANTED;
7495
7496            IPackageManager pm = AppGlobals.getPackageManager();
7497
7498            final int N = mRecentTasks.size();
7499            ArrayList<ActivityManager.RecentTaskInfo> res
7500                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7501                            maxNum < N ? maxNum : N);
7502
7503            final Set<Integer> includedUsers;
7504            if (includeProfiles) {
7505                includedUsers = getProfileIdsLocked(userId);
7506            } else {
7507                includedUsers = new HashSet<Integer>();
7508            }
7509            includedUsers.add(Integer.valueOf(userId));
7510
7511            // Regroup affiliated tasks together.
7512            for (int i = 0; i < N; ) {
7513                TaskRecord task = mRecentTasks.remove(i);
7514                if (mTmpRecents.contains(task)) {
7515                    continue;
7516                }
7517                int affiliatedTaskId = task.mAffiliatedTaskId;
7518                while (true) {
7519                    TaskRecord next = task.mNextAffiliate;
7520                    if (next == null) {
7521                        break;
7522                    }
7523                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7524                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7525                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7526                        task.setNextAffiliate(null);
7527                        if (next.mPrevAffiliate == task) {
7528                            next.setPrevAffiliate(null);
7529                        }
7530                        break;
7531                    }
7532                    if (next.mPrevAffiliate != task) {
7533                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7534                                next.mPrevAffiliate + " task=" + task);
7535                        next.setPrevAffiliate(null);
7536                        break;
7537                    }
7538                    if (!mRecentTasks.contains(next)) {
7539                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7540                        task.setNextAffiliate(null);
7541                        if (next.mPrevAffiliate == task) {
7542                            next.setPrevAffiliate(null);
7543                        }
7544                        break;
7545                    }
7546                    task = next;
7547                }
7548                // task is now the end of the list
7549                do {
7550                    mRecentTasks.remove(task);
7551                    mRecentTasks.add(i++, task);
7552                    mTmpRecents.add(task);
7553                } while ((task = task.mPrevAffiliate) != null);
7554            }
7555            mTmpRecents.clear();
7556            // mRecentTasks is now in sorted, affiliated order.
7557
7558            for (int i=0; i<N && maxNum > 0; i++) {
7559                TaskRecord tr = mRecentTasks.get(i);
7560                // Only add calling user or related users recent tasks
7561                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7562
7563                // Return the entry if desired by the caller.  We always return
7564                // the first entry, because callers always expect this to be the
7565                // foreground app.  We may filter others if the caller has
7566                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7567                // we should exclude the entry.
7568
7569                if (i == 0
7570                        || withExcluded
7571                        || (tr.intent == null)
7572                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7573                                == 0)) {
7574                    if (!allowed) {
7575                        // If the caller doesn't have the GET_TASKS permission, then only
7576                        // allow them to see a small subset of tasks -- their own and home.
7577                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7578                            continue;
7579                        }
7580                    }
7581                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7582                        // Don't include auto remove tasks that are finished or finishing.
7583                        continue;
7584                    }
7585
7586                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7587                    if (!detailed) {
7588                        rti.baseIntent.replaceExtras((Bundle)null);
7589                    }
7590
7591                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7592                        // Check whether this activity is currently available.
7593                        try {
7594                            if (rti.origActivity != null) {
7595                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7596                                        == null) {
7597                                    continue;
7598                                }
7599                            } else if (rti.baseIntent != null) {
7600                                if (pm.queryIntentActivities(rti.baseIntent,
7601                                        null, 0, userId) == null) {
7602                                    continue;
7603                                }
7604                            }
7605                        } catch (RemoteException e) {
7606                            // Will never happen.
7607                        }
7608                    }
7609
7610                    res.add(rti);
7611                    maxNum--;
7612                }
7613            }
7614            return res;
7615        }
7616    }
7617
7618    private TaskRecord recentTaskForIdLocked(int id) {
7619        final int N = mRecentTasks.size();
7620            for (int i=0; i<N; i++) {
7621                TaskRecord tr = mRecentTasks.get(i);
7622                if (tr.taskId == id) {
7623                    return tr;
7624                }
7625            }
7626            return null;
7627    }
7628
7629    @Override
7630    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7631        synchronized (this) {
7632            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7633                    "getTaskThumbnail()");
7634            TaskRecord tr = recentTaskForIdLocked(id);
7635            if (tr != null) {
7636                return tr.getTaskThumbnailLocked();
7637            }
7638        }
7639        return null;
7640    }
7641
7642    @Override
7643    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7644        synchronized (this) {
7645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7646            if (r != null) {
7647                r.taskDescription = td;
7648                r.task.updateTaskDescription();
7649            }
7650        }
7651    }
7652
7653    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7654        if (!pr.killedByAm) {
7655            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7656            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7657                    pr.processName, pr.setAdj, reason);
7658            pr.killedByAm = true;
7659            Process.killProcessQuiet(pr.pid);
7660            Process.killProcessGroup(pr.info.uid, pr.pid);
7661        }
7662    }
7663
7664    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7665        tr.disposeThumbnail();
7666        mRecentTasks.remove(tr);
7667        tr.closeRecentsChain();
7668        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7669        Intent baseIntent = new Intent(
7670                tr.intent != null ? tr.intent : tr.affinityIntent);
7671        ComponentName component = baseIntent.getComponent();
7672        if (component == null) {
7673            Slog.w(TAG, "Now component for base intent of task: " + tr);
7674            return;
7675        }
7676
7677        // Find any running services associated with this app.
7678        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7679
7680        if (killProcesses) {
7681            // Find any running processes associated with this app.
7682            final String pkg = component.getPackageName();
7683            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7684            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7685            for (int i=0; i<pmap.size(); i++) {
7686                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7687                for (int j=0; j<uids.size(); j++) {
7688                    ProcessRecord proc = uids.valueAt(j);
7689                    if (proc.userId != tr.userId) {
7690                        continue;
7691                    }
7692                    if (!proc.pkgList.containsKey(pkg)) {
7693                        continue;
7694                    }
7695                    procs.add(proc);
7696                }
7697            }
7698
7699            // Kill the running processes.
7700            for (int i=0; i<procs.size(); i++) {
7701                ProcessRecord pr = procs.get(i);
7702                if (pr == mHomeProcess) {
7703                    // Don't kill the home process along with tasks from the same package.
7704                    continue;
7705                }
7706                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7707                    killUnneededProcessLocked(pr, "remove task");
7708                } else {
7709                    pr.waitingToKill = "remove task";
7710                }
7711            }
7712        }
7713    }
7714
7715    /**
7716     * Removes the task with the specified task id.
7717     *
7718     * @param taskId Identifier of the task to be removed.
7719     * @param flags Additional operational flags.  May be 0 or
7720     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7721     * @return Returns true if the given task was found and removed.
7722     */
7723    private boolean removeTaskByIdLocked(int taskId, int flags) {
7724        TaskRecord tr = recentTaskForIdLocked(taskId);
7725        if (tr != null) {
7726            tr.removeTaskActivitiesLocked();
7727            cleanUpRemovedTaskLocked(tr, flags);
7728            if (tr.isPersistable) {
7729                notifyTaskPersisterLocked(null, true);
7730            }
7731            return true;
7732        }
7733        return false;
7734    }
7735
7736    @Override
7737    public boolean removeTask(int taskId, int flags) {
7738        synchronized (this) {
7739            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7740                    "removeTask()");
7741            long ident = Binder.clearCallingIdentity();
7742            try {
7743                return removeTaskByIdLocked(taskId, flags);
7744            } finally {
7745                Binder.restoreCallingIdentity(ident);
7746            }
7747        }
7748    }
7749
7750    /**
7751     * TODO: Add mController hook
7752     */
7753    @Override
7754    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7755        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7756                "moveTaskToFront()");
7757
7758        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7759        synchronized(this) {
7760            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7761                    Binder.getCallingUid(), "Task to front")) {
7762                ActivityOptions.abort(options);
7763                return;
7764            }
7765            final long origId = Binder.clearCallingIdentity();
7766            try {
7767                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7768                if (task == null) {
7769                    return;
7770                }
7771                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7772                    mStackSupervisor.showLockTaskToast();
7773                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7774                    return;
7775                }
7776                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7777                if (prev != null && prev.isRecentsActivity()) {
7778                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7779                }
7780                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7781            } finally {
7782                Binder.restoreCallingIdentity(origId);
7783            }
7784            ActivityOptions.abort(options);
7785        }
7786    }
7787
7788    @Override
7789    public void moveTaskToBack(int taskId) {
7790        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7791                "moveTaskToBack()");
7792
7793        synchronized(this) {
7794            TaskRecord tr = recentTaskForIdLocked(taskId);
7795            if (tr != null) {
7796                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7797                ActivityStack stack = tr.stack;
7798                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7799                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7800                            Binder.getCallingUid(), "Task to back")) {
7801                        return;
7802                    }
7803                }
7804                final long origId = Binder.clearCallingIdentity();
7805                try {
7806                    stack.moveTaskToBackLocked(taskId, null);
7807                } finally {
7808                    Binder.restoreCallingIdentity(origId);
7809                }
7810            }
7811        }
7812    }
7813
7814    /**
7815     * Moves an activity, and all of the other activities within the same task, to the bottom
7816     * of the history stack.  The activity's order within the task is unchanged.
7817     *
7818     * @param token A reference to the activity we wish to move
7819     * @param nonRoot If false then this only works if the activity is the root
7820     *                of a task; if true it will work for any activity in a task.
7821     * @return Returns true if the move completed, false if not.
7822     */
7823    @Override
7824    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7825        enforceNotIsolatedCaller("moveActivityTaskToBack");
7826        synchronized(this) {
7827            final long origId = Binder.clearCallingIdentity();
7828            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7829            if (taskId >= 0) {
7830                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7831            }
7832            Binder.restoreCallingIdentity(origId);
7833        }
7834        return false;
7835    }
7836
7837    @Override
7838    public void moveTaskBackwards(int task) {
7839        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7840                "moveTaskBackwards()");
7841
7842        synchronized(this) {
7843            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7844                    Binder.getCallingUid(), "Task backwards")) {
7845                return;
7846            }
7847            final long origId = Binder.clearCallingIdentity();
7848            moveTaskBackwardsLocked(task);
7849            Binder.restoreCallingIdentity(origId);
7850        }
7851    }
7852
7853    private final void moveTaskBackwardsLocked(int task) {
7854        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7855    }
7856
7857    @Override
7858    public IBinder getHomeActivityToken() throws RemoteException {
7859        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7860                "getHomeActivityToken()");
7861        synchronized (this) {
7862            return mStackSupervisor.getHomeActivityToken();
7863        }
7864    }
7865
7866    @Override
7867    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7868            IActivityContainerCallback callback) throws RemoteException {
7869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7870                "createActivityContainer()");
7871        synchronized (this) {
7872            if (parentActivityToken == null) {
7873                throw new IllegalArgumentException("parent token must not be null");
7874            }
7875            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7876            if (r == null) {
7877                return null;
7878            }
7879            if (callback == null) {
7880                throw new IllegalArgumentException("callback must not be null");
7881            }
7882            return mStackSupervisor.createActivityContainer(r, callback);
7883        }
7884    }
7885
7886    @Override
7887    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7889                "deleteActivityContainer()");
7890        synchronized (this) {
7891            mStackSupervisor.deleteActivityContainer(container);
7892        }
7893    }
7894
7895    @Override
7896    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7897            throws RemoteException {
7898        synchronized (this) {
7899            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7900            if (stack != null) {
7901                return stack.mActivityContainer;
7902            }
7903            return null;
7904        }
7905    }
7906
7907    @Override
7908    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7909        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7910                "moveTaskToStack()");
7911        if (stackId == HOME_STACK_ID) {
7912            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7913                    new RuntimeException("here").fillInStackTrace());
7914        }
7915        synchronized (this) {
7916            long ident = Binder.clearCallingIdentity();
7917            try {
7918                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7919                        + stackId + " toTop=" + toTop);
7920                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7921            } finally {
7922                Binder.restoreCallingIdentity(ident);
7923            }
7924        }
7925    }
7926
7927    @Override
7928    public void resizeStack(int stackBoxId, Rect bounds) {
7929        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7930                "resizeStackBox()");
7931        long ident = Binder.clearCallingIdentity();
7932        try {
7933            mWindowManager.resizeStack(stackBoxId, bounds);
7934        } finally {
7935            Binder.restoreCallingIdentity(ident);
7936        }
7937    }
7938
7939    @Override
7940    public List<StackInfo> getAllStackInfos() {
7941        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7942                "getAllStackInfos()");
7943        long ident = Binder.clearCallingIdentity();
7944        try {
7945            synchronized (this) {
7946                return mStackSupervisor.getAllStackInfosLocked();
7947            }
7948        } finally {
7949            Binder.restoreCallingIdentity(ident);
7950        }
7951    }
7952
7953    @Override
7954    public StackInfo getStackInfo(int stackId) {
7955        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7956                "getStackInfo()");
7957        long ident = Binder.clearCallingIdentity();
7958        try {
7959            synchronized (this) {
7960                return mStackSupervisor.getStackInfoLocked(stackId);
7961            }
7962        } finally {
7963            Binder.restoreCallingIdentity(ident);
7964        }
7965    }
7966
7967    @Override
7968    public boolean isInHomeStack(int taskId) {
7969        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7970                "getStackInfo()");
7971        long ident = Binder.clearCallingIdentity();
7972        try {
7973            synchronized (this) {
7974                TaskRecord tr = recentTaskForIdLocked(taskId);
7975                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7976            }
7977        } finally {
7978            Binder.restoreCallingIdentity(ident);
7979        }
7980    }
7981
7982    @Override
7983    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7984        synchronized(this) {
7985            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7986        }
7987    }
7988
7989    private boolean isLockTaskAuthorized(String pkg) {
7990        final DevicePolicyManager dpm = (DevicePolicyManager)
7991                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7992        try {
7993            int uid = mContext.getPackageManager().getPackageUid(pkg,
7994                    Binder.getCallingUserHandle().getIdentifier());
7995            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7996        } catch (NameNotFoundException e) {
7997            return false;
7998        }
7999    }
8000
8001    void startLockTaskMode(TaskRecord task) {
8002        final String pkg;
8003        synchronized (this) {
8004            pkg = task.intent.getComponent().getPackageName();
8005        }
8006        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8007        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8008            final TaskRecord taskRecord = task;
8009            mHandler.post(new Runnable() {
8010                @Override
8011                public void run() {
8012                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8013                }
8014            });
8015            return;
8016        }
8017        long ident = Binder.clearCallingIdentity();
8018        try {
8019            synchronized (this) {
8020                // Since we lost lock on task, make sure it is still there.
8021                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8022                if (task != null) {
8023                    if (!isSystemInitiated
8024                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8025                        throw new IllegalArgumentException("Invalid task, not in foreground");
8026                    }
8027                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8028                }
8029            }
8030        } finally {
8031            Binder.restoreCallingIdentity(ident);
8032        }
8033    }
8034
8035    @Override
8036    public void startLockTaskMode(int taskId) {
8037        final TaskRecord task;
8038        long ident = Binder.clearCallingIdentity();
8039        try {
8040            synchronized (this) {
8041                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8042            }
8043        } finally {
8044            Binder.restoreCallingIdentity(ident);
8045        }
8046        if (task != null) {
8047            startLockTaskMode(task);
8048        }
8049    }
8050
8051    @Override
8052    public void startLockTaskMode(IBinder token) {
8053        final TaskRecord task;
8054        long ident = Binder.clearCallingIdentity();
8055        try {
8056            synchronized (this) {
8057                final ActivityRecord r = ActivityRecord.forToken(token);
8058                if (r == null) {
8059                    return;
8060                }
8061                task = r.task;
8062            }
8063        } finally {
8064            Binder.restoreCallingIdentity(ident);
8065        }
8066        if (task != null) {
8067            startLockTaskMode(task);
8068        }
8069    }
8070
8071    @Override
8072    public void startLockTaskModeOnCurrent() throws RemoteException {
8073        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8074        ActivityRecord r = null;
8075        synchronized (this) {
8076            r = mStackSupervisor.topRunningActivityLocked();
8077        }
8078        startLockTaskMode(r.task);
8079    }
8080
8081    @Override
8082    public void stopLockTaskMode() {
8083        // Verify that the user matches the package of the intent for the TaskRecord
8084        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8085        // and stopLockTaskMode.
8086        final int callingUid = Binder.getCallingUid();
8087        if (callingUid != Process.SYSTEM_UID) {
8088            try {
8089                String pkg =
8090                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8091                int uid = mContext.getPackageManager().getPackageUid(pkg,
8092                        Binder.getCallingUserHandle().getIdentifier());
8093                if (uid != callingUid) {
8094                    throw new SecurityException("Invalid uid, expected " + uid);
8095                }
8096            } catch (NameNotFoundException e) {
8097                Log.d(TAG, "stopLockTaskMode " + e);
8098                return;
8099            }
8100        }
8101        long ident = Binder.clearCallingIdentity();
8102        try {
8103            Log.d(TAG, "stopLockTaskMode");
8104            // Stop lock task
8105            synchronized (this) {
8106                mStackSupervisor.setLockTaskModeLocked(null, false);
8107            }
8108        } finally {
8109            Binder.restoreCallingIdentity(ident);
8110        }
8111    }
8112
8113    @Override
8114    public void stopLockTaskModeOnCurrent() throws RemoteException {
8115        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8116        long ident = Binder.clearCallingIdentity();
8117        try {
8118            stopLockTaskMode();
8119        } finally {
8120            Binder.restoreCallingIdentity(ident);
8121        }
8122    }
8123
8124    @Override
8125    public boolean isInLockTaskMode() {
8126        synchronized (this) {
8127            return mStackSupervisor.isInLockTaskMode();
8128        }
8129    }
8130
8131    // =========================================================
8132    // CONTENT PROVIDERS
8133    // =========================================================
8134
8135    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8136        List<ProviderInfo> providers = null;
8137        try {
8138            providers = AppGlobals.getPackageManager().
8139                queryContentProviders(app.processName, app.uid,
8140                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8141        } catch (RemoteException ex) {
8142        }
8143        if (DEBUG_MU)
8144            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8145        int userId = app.userId;
8146        if (providers != null) {
8147            int N = providers.size();
8148            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8149            for (int i=0; i<N; i++) {
8150                ProviderInfo cpi =
8151                    (ProviderInfo)providers.get(i);
8152                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8153                        cpi.name, cpi.flags);
8154                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8155                    // This is a singleton provider, but a user besides the
8156                    // default user is asking to initialize a process it runs
8157                    // in...  well, no, it doesn't actually run in this process,
8158                    // it runs in the process of the default user.  Get rid of it.
8159                    providers.remove(i);
8160                    N--;
8161                    i--;
8162                    continue;
8163                }
8164
8165                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8166                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8167                if (cpr == null) {
8168                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8169                    mProviderMap.putProviderByClass(comp, cpr);
8170                }
8171                if (DEBUG_MU)
8172                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8173                app.pubProviders.put(cpi.name, cpr);
8174                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8175                    // Don't add this if it is a platform component that is marked
8176                    // to run in multiple processes, because this is actually
8177                    // part of the framework so doesn't make sense to track as a
8178                    // separate apk in the process.
8179                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8180                            mProcessStats);
8181                }
8182                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8183            }
8184        }
8185        return providers;
8186    }
8187
8188    /**
8189     * Check if {@link ProcessRecord} has a possible chance at accessing the
8190     * given {@link ProviderInfo}. Final permission checking is always done
8191     * in {@link ContentProvider}.
8192     */
8193    private final String checkContentProviderPermissionLocked(
8194            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8195        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8196        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8197        boolean checkedGrants = false;
8198        if (checkUser) {
8199            // Looking for cross-user grants before enforcing the typical cross-users permissions
8200            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8201            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8202                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8203                    return null;
8204                }
8205                checkedGrants = true;
8206            }
8207            userId = handleIncomingUser(callingPid, callingUid, userId,
8208                    false, ALLOW_NON_FULL,
8209                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8210            if (userId != tmpTargetUserId) {
8211                // When we actually went to determine the final targer user ID, this ended
8212                // up different than our initial check for the authority.  This is because
8213                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8214                // SELF.  So we need to re-check the grants again.
8215                checkedGrants = false;
8216            }
8217        }
8218        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8219                cpi.applicationInfo.uid, cpi.exported)
8220                == PackageManager.PERMISSION_GRANTED) {
8221            return null;
8222        }
8223        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8224                cpi.applicationInfo.uid, cpi.exported)
8225                == PackageManager.PERMISSION_GRANTED) {
8226            return null;
8227        }
8228
8229        PathPermission[] pps = cpi.pathPermissions;
8230        if (pps != null) {
8231            int i = pps.length;
8232            while (i > 0) {
8233                i--;
8234                PathPermission pp = pps[i];
8235                String pprperm = pp.getReadPermission();
8236                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8237                        cpi.applicationInfo.uid, cpi.exported)
8238                        == PackageManager.PERMISSION_GRANTED) {
8239                    return null;
8240                }
8241                String ppwperm = pp.getWritePermission();
8242                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8243                        cpi.applicationInfo.uid, cpi.exported)
8244                        == PackageManager.PERMISSION_GRANTED) {
8245                    return null;
8246                }
8247            }
8248        }
8249        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8250            return null;
8251        }
8252
8253        String msg;
8254        if (!cpi.exported) {
8255            msg = "Permission Denial: opening provider " + cpi.name
8256                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8257                    + ", uid=" + callingUid + ") that is not exported from uid "
8258                    + cpi.applicationInfo.uid;
8259        } else {
8260            msg = "Permission Denial: opening provider " + cpi.name
8261                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8262                    + ", uid=" + callingUid + ") requires "
8263                    + cpi.readPermission + " or " + cpi.writePermission;
8264        }
8265        Slog.w(TAG, msg);
8266        return msg;
8267    }
8268
8269    /**
8270     * Returns if the ContentProvider has granted a uri to callingUid
8271     */
8272    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8273        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8274        if (perms != null) {
8275            for (int i=perms.size()-1; i>=0; i--) {
8276                GrantUri grantUri = perms.keyAt(i);
8277                if (grantUri.sourceUserId == userId || !checkUser) {
8278                    if (matchesProvider(grantUri.uri, cpi)) {
8279                        return true;
8280                    }
8281                }
8282            }
8283        }
8284        return false;
8285    }
8286
8287    /**
8288     * Returns true if the uri authority is one of the authorities specified in the provider.
8289     */
8290    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8291        String uriAuth = uri.getAuthority();
8292        String cpiAuth = cpi.authority;
8293        if (cpiAuth.indexOf(';') == -1) {
8294            return cpiAuth.equals(uriAuth);
8295        }
8296        String[] cpiAuths = cpiAuth.split(";");
8297        int length = cpiAuths.length;
8298        for (int i = 0; i < length; i++) {
8299            if (cpiAuths[i].equals(uriAuth)) return true;
8300        }
8301        return false;
8302    }
8303
8304    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8305            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8306        if (r != null) {
8307            for (int i=0; i<r.conProviders.size(); i++) {
8308                ContentProviderConnection conn = r.conProviders.get(i);
8309                if (conn.provider == cpr) {
8310                    if (DEBUG_PROVIDER) Slog.v(TAG,
8311                            "Adding provider requested by "
8312                            + r.processName + " from process "
8313                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8314                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8315                    if (stable) {
8316                        conn.stableCount++;
8317                        conn.numStableIncs++;
8318                    } else {
8319                        conn.unstableCount++;
8320                        conn.numUnstableIncs++;
8321                    }
8322                    return conn;
8323                }
8324            }
8325            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8326            if (stable) {
8327                conn.stableCount = 1;
8328                conn.numStableIncs = 1;
8329            } else {
8330                conn.unstableCount = 1;
8331                conn.numUnstableIncs = 1;
8332            }
8333            cpr.connections.add(conn);
8334            r.conProviders.add(conn);
8335            return conn;
8336        }
8337        cpr.addExternalProcessHandleLocked(externalProcessToken);
8338        return null;
8339    }
8340
8341    boolean decProviderCountLocked(ContentProviderConnection conn,
8342            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8343        if (conn != null) {
8344            cpr = conn.provider;
8345            if (DEBUG_PROVIDER) Slog.v(TAG,
8346                    "Removing provider requested by "
8347                    + conn.client.processName + " from process "
8348                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8349                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8350            if (stable) {
8351                conn.stableCount--;
8352            } else {
8353                conn.unstableCount--;
8354            }
8355            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8356                cpr.connections.remove(conn);
8357                conn.client.conProviders.remove(conn);
8358                return true;
8359            }
8360            return false;
8361        }
8362        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8363        return false;
8364    }
8365
8366    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8367            String name, IBinder token, boolean stable, int userId) {
8368        ContentProviderRecord cpr;
8369        ContentProviderConnection conn = null;
8370        ProviderInfo cpi = null;
8371
8372        synchronized(this) {
8373            ProcessRecord r = null;
8374            if (caller != null) {
8375                r = getRecordForAppLocked(caller);
8376                if (r == null) {
8377                    throw new SecurityException(
8378                            "Unable to find app for caller " + caller
8379                          + " (pid=" + Binder.getCallingPid()
8380                          + ") when getting content provider " + name);
8381                }
8382            }
8383
8384            boolean checkCrossUser = true;
8385
8386            // First check if this content provider has been published...
8387            cpr = mProviderMap.getProviderByName(name, userId);
8388            // If that didn't work, check if it exists for user 0 and then
8389            // verify that it's a singleton provider before using it.
8390            if (cpr == null && userId != UserHandle.USER_OWNER) {
8391                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8392                if (cpr != null) {
8393                    cpi = cpr.info;
8394                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8395                            cpi.name, cpi.flags)
8396                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8397                        userId = UserHandle.USER_OWNER;
8398                        checkCrossUser = false;
8399                    } else {
8400                        cpr = null;
8401                        cpi = null;
8402                    }
8403                }
8404            }
8405
8406            boolean providerRunning = cpr != null;
8407            if (providerRunning) {
8408                cpi = cpr.info;
8409                String msg;
8410                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8411                        != null) {
8412                    throw new SecurityException(msg);
8413                }
8414
8415                if (r != null && cpr.canRunHere(r)) {
8416                    // This provider has been published or is in the process
8417                    // of being published...  but it is also allowed to run
8418                    // in the caller's process, so don't make a connection
8419                    // and just let the caller instantiate its own instance.
8420                    ContentProviderHolder holder = cpr.newHolder(null);
8421                    // don't give caller the provider object, it needs
8422                    // to make its own.
8423                    holder.provider = null;
8424                    return holder;
8425                }
8426
8427                final long origId = Binder.clearCallingIdentity();
8428
8429                // In this case the provider instance already exists, so we can
8430                // return it right away.
8431                conn = incProviderCountLocked(r, cpr, token, stable);
8432                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8433                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8434                        // If this is a perceptible app accessing the provider,
8435                        // make sure to count it as being accessed and thus
8436                        // back up on the LRU list.  This is good because
8437                        // content providers are often expensive to start.
8438                        updateLruProcessLocked(cpr.proc, false, null);
8439                    }
8440                }
8441
8442                if (cpr.proc != null) {
8443                    if (false) {
8444                        if (cpr.name.flattenToShortString().equals(
8445                                "com.android.providers.calendar/.CalendarProvider2")) {
8446                            Slog.v(TAG, "****************** KILLING "
8447                                + cpr.name.flattenToShortString());
8448                            Process.killProcess(cpr.proc.pid);
8449                        }
8450                    }
8451                    boolean success = updateOomAdjLocked(cpr.proc);
8452                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8453                    // NOTE: there is still a race here where a signal could be
8454                    // pending on the process even though we managed to update its
8455                    // adj level.  Not sure what to do about this, but at least
8456                    // the race is now smaller.
8457                    if (!success) {
8458                        // Uh oh...  it looks like the provider's process
8459                        // has been killed on us.  We need to wait for a new
8460                        // process to be started, and make sure its death
8461                        // doesn't kill our process.
8462                        Slog.i(TAG,
8463                                "Existing provider " + cpr.name.flattenToShortString()
8464                                + " is crashing; detaching " + r);
8465                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8466                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8467                        if (!lastRef) {
8468                            // This wasn't the last ref our process had on
8469                            // the provider...  we have now been killed, bail.
8470                            return null;
8471                        }
8472                        providerRunning = false;
8473                        conn = null;
8474                    }
8475                }
8476
8477                Binder.restoreCallingIdentity(origId);
8478            }
8479
8480            boolean singleton;
8481            if (!providerRunning) {
8482                try {
8483                    cpi = AppGlobals.getPackageManager().
8484                        resolveContentProvider(name,
8485                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8486                } catch (RemoteException ex) {
8487                }
8488                if (cpi == null) {
8489                    return null;
8490                }
8491                // If the provider is a singleton AND
8492                // (it's a call within the same user || the provider is a
8493                // privileged app)
8494                // Then allow connecting to the singleton provider
8495                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8496                        cpi.name, cpi.flags)
8497                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8498                if (singleton) {
8499                    userId = UserHandle.USER_OWNER;
8500                }
8501                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8502
8503                String msg;
8504                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8505                        != null) {
8506                    throw new SecurityException(msg);
8507                }
8508
8509                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8510                        && !cpi.processName.equals("system")) {
8511                    // If this content provider does not run in the system
8512                    // process, and the system is not yet ready to run other
8513                    // processes, then fail fast instead of hanging.
8514                    throw new IllegalArgumentException(
8515                            "Attempt to launch content provider before system ready");
8516                }
8517
8518                // Make sure that the user who owns this provider is started.  If not,
8519                // we don't want to allow it to run.
8520                if (mStartedUsers.get(userId) == null) {
8521                    Slog.w(TAG, "Unable to launch app "
8522                            + cpi.applicationInfo.packageName + "/"
8523                            + cpi.applicationInfo.uid + " for provider "
8524                            + name + ": user " + userId + " is stopped");
8525                    return null;
8526                }
8527
8528                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8529                cpr = mProviderMap.getProviderByClass(comp, userId);
8530                final boolean firstClass = cpr == null;
8531                if (firstClass) {
8532                    try {
8533                        ApplicationInfo ai =
8534                            AppGlobals.getPackageManager().
8535                                getApplicationInfo(
8536                                        cpi.applicationInfo.packageName,
8537                                        STOCK_PM_FLAGS, userId);
8538                        if (ai == null) {
8539                            Slog.w(TAG, "No package info for content provider "
8540                                    + cpi.name);
8541                            return null;
8542                        }
8543                        ai = getAppInfoForUser(ai, userId);
8544                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8545                    } catch (RemoteException ex) {
8546                        // pm is in same process, this will never happen.
8547                    }
8548                }
8549
8550                if (r != null && cpr.canRunHere(r)) {
8551                    // If this is a multiprocess provider, then just return its
8552                    // info and allow the caller to instantiate it.  Only do
8553                    // this if the provider is the same user as the caller's
8554                    // process, or can run as root (so can be in any process).
8555                    return cpr.newHolder(null);
8556                }
8557
8558                if (DEBUG_PROVIDER) {
8559                    RuntimeException e = new RuntimeException("here");
8560                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8561                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8562                }
8563
8564                // This is single process, and our app is now connecting to it.
8565                // See if we are already in the process of launching this
8566                // provider.
8567                final int N = mLaunchingProviders.size();
8568                int i;
8569                for (i=0; i<N; i++) {
8570                    if (mLaunchingProviders.get(i) == cpr) {
8571                        break;
8572                    }
8573                }
8574
8575                // If the provider is not already being launched, then get it
8576                // started.
8577                if (i >= N) {
8578                    final long origId = Binder.clearCallingIdentity();
8579
8580                    try {
8581                        // Content provider is now in use, its package can't be stopped.
8582                        try {
8583                            AppGlobals.getPackageManager().setPackageStoppedState(
8584                                    cpr.appInfo.packageName, false, userId);
8585                        } catch (RemoteException e) {
8586                        } catch (IllegalArgumentException e) {
8587                            Slog.w(TAG, "Failed trying to unstop package "
8588                                    + cpr.appInfo.packageName + ": " + e);
8589                        }
8590
8591                        // Use existing process if already started
8592                        ProcessRecord proc = getProcessRecordLocked(
8593                                cpi.processName, cpr.appInfo.uid, false);
8594                        if (proc != null && proc.thread != null) {
8595                            if (DEBUG_PROVIDER) {
8596                                Slog.d(TAG, "Installing in existing process " + proc);
8597                            }
8598                            proc.pubProviders.put(cpi.name, cpr);
8599                            try {
8600                                proc.thread.scheduleInstallProvider(cpi);
8601                            } catch (RemoteException e) {
8602                            }
8603                        } else {
8604                            proc = startProcessLocked(cpi.processName,
8605                                    cpr.appInfo, false, 0, "content provider",
8606                                    new ComponentName(cpi.applicationInfo.packageName,
8607                                            cpi.name), false, false, false);
8608                            if (proc == null) {
8609                                Slog.w(TAG, "Unable to launch app "
8610                                        + cpi.applicationInfo.packageName + "/"
8611                                        + cpi.applicationInfo.uid + " for provider "
8612                                        + name + ": process is bad");
8613                                return null;
8614                            }
8615                        }
8616                        cpr.launchingApp = proc;
8617                        mLaunchingProviders.add(cpr);
8618                    } finally {
8619                        Binder.restoreCallingIdentity(origId);
8620                    }
8621                }
8622
8623                // Make sure the provider is published (the same provider class
8624                // may be published under multiple names).
8625                if (firstClass) {
8626                    mProviderMap.putProviderByClass(comp, cpr);
8627                }
8628
8629                mProviderMap.putProviderByName(name, cpr);
8630                conn = incProviderCountLocked(r, cpr, token, stable);
8631                if (conn != null) {
8632                    conn.waiting = true;
8633                }
8634            }
8635        }
8636
8637        // Wait for the provider to be published...
8638        synchronized (cpr) {
8639            while (cpr.provider == null) {
8640                if (cpr.launchingApp == null) {
8641                    Slog.w(TAG, "Unable to launch app "
8642                            + cpi.applicationInfo.packageName + "/"
8643                            + cpi.applicationInfo.uid + " for provider "
8644                            + name + ": launching app became null");
8645                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8646                            UserHandle.getUserId(cpi.applicationInfo.uid),
8647                            cpi.applicationInfo.packageName,
8648                            cpi.applicationInfo.uid, name);
8649                    return null;
8650                }
8651                try {
8652                    if (DEBUG_MU) {
8653                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8654                                + cpr.launchingApp);
8655                    }
8656                    if (conn != null) {
8657                        conn.waiting = true;
8658                    }
8659                    cpr.wait();
8660                } catch (InterruptedException ex) {
8661                } finally {
8662                    if (conn != null) {
8663                        conn.waiting = false;
8664                    }
8665                }
8666            }
8667        }
8668        return cpr != null ? cpr.newHolder(conn) : null;
8669    }
8670
8671    @Override
8672    public final ContentProviderHolder getContentProvider(
8673            IApplicationThread caller, String name, int userId, boolean stable) {
8674        enforceNotIsolatedCaller("getContentProvider");
8675        if (caller == null) {
8676            String msg = "null IApplicationThread when getting content provider "
8677                    + name;
8678            Slog.w(TAG, msg);
8679            throw new SecurityException(msg);
8680        }
8681        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8682        // with cross-user grant.
8683        return getContentProviderImpl(caller, name, null, stable, userId);
8684    }
8685
8686    public ContentProviderHolder getContentProviderExternal(
8687            String name, int userId, IBinder token) {
8688        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8689            "Do not have permission in call getContentProviderExternal()");
8690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8691                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8692        return getContentProviderExternalUnchecked(name, token, userId);
8693    }
8694
8695    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8696            IBinder token, int userId) {
8697        return getContentProviderImpl(null, name, token, true, userId);
8698    }
8699
8700    /**
8701     * Drop a content provider from a ProcessRecord's bookkeeping
8702     */
8703    public void removeContentProvider(IBinder connection, boolean stable) {
8704        enforceNotIsolatedCaller("removeContentProvider");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            synchronized (this) {
8708                ContentProviderConnection conn;
8709                try {
8710                    conn = (ContentProviderConnection)connection;
8711                } catch (ClassCastException e) {
8712                    String msg ="removeContentProvider: " + connection
8713                            + " not a ContentProviderConnection";
8714                    Slog.w(TAG, msg);
8715                    throw new IllegalArgumentException(msg);
8716                }
8717                if (conn == null) {
8718                    throw new NullPointerException("connection is null");
8719                }
8720                if (decProviderCountLocked(conn, null, null, stable)) {
8721                    updateOomAdjLocked();
8722                }
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    public void removeContentProviderExternal(String name, IBinder token) {
8730        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8731            "Do not have permission in call removeContentProviderExternal()");
8732        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8733    }
8734
8735    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8736        synchronized (this) {
8737            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8738            if(cpr == null) {
8739                //remove from mProvidersByClass
8740                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8741                return;
8742            }
8743
8744            //update content provider record entry info
8745            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8746            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8747            if (localCpr.hasExternalProcessHandles()) {
8748                if (localCpr.removeExternalProcessHandleLocked(token)) {
8749                    updateOomAdjLocked();
8750                } else {
8751                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8752                            + " with no external reference for token: "
8753                            + token + ".");
8754                }
8755            } else {
8756                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8757                        + " with no external references.");
8758            }
8759        }
8760    }
8761
8762    public final void publishContentProviders(IApplicationThread caller,
8763            List<ContentProviderHolder> providers) {
8764        if (providers == null) {
8765            return;
8766        }
8767
8768        enforceNotIsolatedCaller("publishContentProviders");
8769        synchronized (this) {
8770            final ProcessRecord r = getRecordForAppLocked(caller);
8771            if (DEBUG_MU)
8772                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8773            if (r == null) {
8774                throw new SecurityException(
8775                        "Unable to find app for caller " + caller
8776                      + " (pid=" + Binder.getCallingPid()
8777                      + ") when publishing content providers");
8778            }
8779
8780            final long origId = Binder.clearCallingIdentity();
8781
8782            final int N = providers.size();
8783            for (int i=0; i<N; i++) {
8784                ContentProviderHolder src = providers.get(i);
8785                if (src == null || src.info == null || src.provider == null) {
8786                    continue;
8787                }
8788                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8789                if (DEBUG_MU)
8790                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8791                if (dst != null) {
8792                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8793                    mProviderMap.putProviderByClass(comp, dst);
8794                    String names[] = dst.info.authority.split(";");
8795                    for (int j = 0; j < names.length; j++) {
8796                        mProviderMap.putProviderByName(names[j], dst);
8797                    }
8798
8799                    int NL = mLaunchingProviders.size();
8800                    int j;
8801                    for (j=0; j<NL; j++) {
8802                        if (mLaunchingProviders.get(j) == dst) {
8803                            mLaunchingProviders.remove(j);
8804                            j--;
8805                            NL--;
8806                        }
8807                    }
8808                    synchronized (dst) {
8809                        dst.provider = src.provider;
8810                        dst.proc = r;
8811                        dst.notifyAll();
8812                    }
8813                    updateOomAdjLocked(r);
8814                }
8815            }
8816
8817            Binder.restoreCallingIdentity(origId);
8818        }
8819    }
8820
8821    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8822        ContentProviderConnection conn;
8823        try {
8824            conn = (ContentProviderConnection)connection;
8825        } catch (ClassCastException e) {
8826            String msg ="refContentProvider: " + connection
8827                    + " not a ContentProviderConnection";
8828            Slog.w(TAG, msg);
8829            throw new IllegalArgumentException(msg);
8830        }
8831        if (conn == null) {
8832            throw new NullPointerException("connection is null");
8833        }
8834
8835        synchronized (this) {
8836            if (stable > 0) {
8837                conn.numStableIncs += stable;
8838            }
8839            stable = conn.stableCount + stable;
8840            if (stable < 0) {
8841                throw new IllegalStateException("stableCount < 0: " + stable);
8842            }
8843
8844            if (unstable > 0) {
8845                conn.numUnstableIncs += unstable;
8846            }
8847            unstable = conn.unstableCount + unstable;
8848            if (unstable < 0) {
8849                throw new IllegalStateException("unstableCount < 0: " + unstable);
8850            }
8851
8852            if ((stable+unstable) <= 0) {
8853                throw new IllegalStateException("ref counts can't go to zero here: stable="
8854                        + stable + " unstable=" + unstable);
8855            }
8856            conn.stableCount = stable;
8857            conn.unstableCount = unstable;
8858            return !conn.dead;
8859        }
8860    }
8861
8862    public void unstableProviderDied(IBinder connection) {
8863        ContentProviderConnection conn;
8864        try {
8865            conn = (ContentProviderConnection)connection;
8866        } catch (ClassCastException e) {
8867            String msg ="refContentProvider: " + connection
8868                    + " not a ContentProviderConnection";
8869            Slog.w(TAG, msg);
8870            throw new IllegalArgumentException(msg);
8871        }
8872        if (conn == null) {
8873            throw new NullPointerException("connection is null");
8874        }
8875
8876        // Safely retrieve the content provider associated with the connection.
8877        IContentProvider provider;
8878        synchronized (this) {
8879            provider = conn.provider.provider;
8880        }
8881
8882        if (provider == null) {
8883            // Um, yeah, we're way ahead of you.
8884            return;
8885        }
8886
8887        // Make sure the caller is being honest with us.
8888        if (provider.asBinder().pingBinder()) {
8889            // Er, no, still looks good to us.
8890            synchronized (this) {
8891                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8892                        + " says " + conn + " died, but we don't agree");
8893                return;
8894            }
8895        }
8896
8897        // Well look at that!  It's dead!
8898        synchronized (this) {
8899            if (conn.provider.provider != provider) {
8900                // But something changed...  good enough.
8901                return;
8902            }
8903
8904            ProcessRecord proc = conn.provider.proc;
8905            if (proc == null || proc.thread == null) {
8906                // Seems like the process is already cleaned up.
8907                return;
8908            }
8909
8910            // As far as we're concerned, this is just like receiving a
8911            // death notification...  just a bit prematurely.
8912            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8913                    + ") early provider death");
8914            final long ident = Binder.clearCallingIdentity();
8915            try {
8916                appDiedLocked(proc, proc.pid, proc.thread);
8917            } finally {
8918                Binder.restoreCallingIdentity(ident);
8919            }
8920        }
8921    }
8922
8923    @Override
8924    public void appNotRespondingViaProvider(IBinder connection) {
8925        enforceCallingPermission(
8926                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8927
8928        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8929        if (conn == null) {
8930            Slog.w(TAG, "ContentProviderConnection is null");
8931            return;
8932        }
8933
8934        final ProcessRecord host = conn.provider.proc;
8935        if (host == null) {
8936            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8937            return;
8938        }
8939
8940        final long token = Binder.clearCallingIdentity();
8941        try {
8942            appNotResponding(host, null, null, false, "ContentProvider not responding");
8943        } finally {
8944            Binder.restoreCallingIdentity(token);
8945        }
8946    }
8947
8948    public final void installSystemProviders() {
8949        List<ProviderInfo> providers;
8950        synchronized (this) {
8951            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8952            providers = generateApplicationProvidersLocked(app);
8953            if (providers != null) {
8954                for (int i=providers.size()-1; i>=0; i--) {
8955                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8956                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8957                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8958                                + ": not system .apk");
8959                        providers.remove(i);
8960                    }
8961                }
8962            }
8963        }
8964        if (providers != null) {
8965            mSystemThread.installSystemProviders(providers);
8966        }
8967
8968        mCoreSettingsObserver = new CoreSettingsObserver(this);
8969
8970        //mUsageStatsService.monitorPackages();
8971    }
8972
8973    /**
8974     * Allows apps to retrieve the MIME type of a URI.
8975     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
8976     * users, then it does not need permission to access the ContentProvider.
8977     * Either, it needs cross-user uri grants.
8978     *
8979     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8980     *
8981     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8982     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8983     */
8984    public String getProviderMimeType(Uri uri, int userId) {
8985        enforceNotIsolatedCaller("getProviderMimeType");
8986        final String name = uri.getAuthority();
8987        int callingUid = Binder.getCallingUid();
8988        int callingPid = Binder.getCallingPid();
8989        long ident = 0;
8990        boolean clearedIdentity = false;
8991        userId = unsafeConvertIncomingUser(userId);
8992        if (UserHandle.getUserId(callingUid) != userId) {
8993            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
8994                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
8995                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
8996                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
8997                clearedIdentity = true;
8998                ident = Binder.clearCallingIdentity();
8999            }
9000        }
9001        ContentProviderHolder holder = null;
9002        try {
9003            holder = getContentProviderExternalUnchecked(name, null, userId);
9004            if (holder != null) {
9005                return holder.provider.getType(uri);
9006            }
9007        } catch (RemoteException e) {
9008            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9009            return null;
9010        } finally {
9011            // We need to clear the identity to call removeContentProviderExternalUnchecked
9012            if (!clearedIdentity) {
9013                ident = Binder.clearCallingIdentity();
9014            }
9015            try {
9016                if (holder != null) {
9017                    removeContentProviderExternalUnchecked(name, null, userId);
9018                }
9019            } finally {
9020                Binder.restoreCallingIdentity(ident);
9021            }
9022        }
9023
9024        return null;
9025    }
9026
9027    // =========================================================
9028    // GLOBAL MANAGEMENT
9029    // =========================================================
9030
9031    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9032            boolean isolated, int isolatedUid) {
9033        String proc = customProcess != null ? customProcess : info.processName;
9034        BatteryStatsImpl.Uid.Proc ps = null;
9035        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9036        int uid = info.uid;
9037        if (isolated) {
9038            if (isolatedUid == 0) {
9039                int userId = UserHandle.getUserId(uid);
9040                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9041                while (true) {
9042                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9043                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9044                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9045                    }
9046                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9047                    mNextIsolatedProcessUid++;
9048                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9049                        // No process for this uid, use it.
9050                        break;
9051                    }
9052                    stepsLeft--;
9053                    if (stepsLeft <= 0) {
9054                        return null;
9055                    }
9056                }
9057            } else {
9058                // Special case for startIsolatedProcess (internal only), where
9059                // the uid of the isolated process is specified by the caller.
9060                uid = isolatedUid;
9061            }
9062        }
9063        return new ProcessRecord(stats, info, proc, uid);
9064    }
9065
9066    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9067            String abiOverride) {
9068        ProcessRecord app;
9069        if (!isolated) {
9070            app = getProcessRecordLocked(info.processName, info.uid, true);
9071        } else {
9072            app = null;
9073        }
9074
9075        if (app == null) {
9076            app = newProcessRecordLocked(info, null, isolated, 0);
9077            mProcessNames.put(info.processName, app.uid, app);
9078            if (isolated) {
9079                mIsolatedProcesses.put(app.uid, app);
9080            }
9081            updateLruProcessLocked(app, false, null);
9082            updateOomAdjLocked();
9083        }
9084
9085        // This package really, really can not be stopped.
9086        try {
9087            AppGlobals.getPackageManager().setPackageStoppedState(
9088                    info.packageName, false, UserHandle.getUserId(app.uid));
9089        } catch (RemoteException e) {
9090        } catch (IllegalArgumentException e) {
9091            Slog.w(TAG, "Failed trying to unstop package "
9092                    + info.packageName + ": " + e);
9093        }
9094
9095        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9096                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9097            app.persistent = true;
9098            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9099        }
9100        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9101            mPersistentStartingProcesses.add(app);
9102            startProcessLocked(app, "added application", app.processName, abiOverride,
9103                    null /* entryPoint */, null /* entryPointArgs */);
9104        }
9105
9106        return app;
9107    }
9108
9109    public void unhandledBack() {
9110        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9111                "unhandledBack()");
9112
9113        synchronized(this) {
9114            final long origId = Binder.clearCallingIdentity();
9115            try {
9116                getFocusedStack().unhandledBackLocked();
9117            } finally {
9118                Binder.restoreCallingIdentity(origId);
9119            }
9120        }
9121    }
9122
9123    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9124        enforceNotIsolatedCaller("openContentUri");
9125        final int userId = UserHandle.getCallingUserId();
9126        String name = uri.getAuthority();
9127        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9128        ParcelFileDescriptor pfd = null;
9129        if (cph != null) {
9130            // We record the binder invoker's uid in thread-local storage before
9131            // going to the content provider to open the file.  Later, in the code
9132            // that handles all permissions checks, we look for this uid and use
9133            // that rather than the Activity Manager's own uid.  The effect is that
9134            // we do the check against the caller's permissions even though it looks
9135            // to the content provider like the Activity Manager itself is making
9136            // the request.
9137            sCallerIdentity.set(new Identity(
9138                    Binder.getCallingPid(), Binder.getCallingUid()));
9139            try {
9140                pfd = cph.provider.openFile(null, uri, "r", null);
9141            } catch (FileNotFoundException e) {
9142                // do nothing; pfd will be returned null
9143            } finally {
9144                // Ensure that whatever happens, we clean up the identity state
9145                sCallerIdentity.remove();
9146            }
9147
9148            // We've got the fd now, so we're done with the provider.
9149            removeContentProviderExternalUnchecked(name, null, userId);
9150        } else {
9151            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9152        }
9153        return pfd;
9154    }
9155
9156    // Actually is sleeping or shutting down or whatever else in the future
9157    // is an inactive state.
9158    public boolean isSleepingOrShuttingDown() {
9159        return mSleeping || mShuttingDown;
9160    }
9161
9162    public boolean isSleeping() {
9163        return mSleeping;
9164    }
9165
9166    void goingToSleep() {
9167        synchronized(this) {
9168            mWentToSleep = true;
9169            updateEventDispatchingLocked();
9170            goToSleepIfNeededLocked();
9171        }
9172    }
9173
9174    void finishRunningVoiceLocked() {
9175        if (mRunningVoice) {
9176            mRunningVoice = false;
9177            goToSleepIfNeededLocked();
9178        }
9179    }
9180
9181    void goToSleepIfNeededLocked() {
9182        if (mWentToSleep && !mRunningVoice) {
9183            if (!mSleeping) {
9184                mSleeping = true;
9185                mStackSupervisor.goingToSleepLocked();
9186
9187                // Initialize the wake times of all processes.
9188                checkExcessivePowerUsageLocked(false);
9189                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9190                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9191                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9192            }
9193        }
9194    }
9195
9196    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9197        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9198            // Never persist the home stack.
9199            return;
9200        }
9201        mTaskPersister.wakeup(task, flush);
9202    }
9203
9204    @Override
9205    public boolean shutdown(int timeout) {
9206        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9207                != PackageManager.PERMISSION_GRANTED) {
9208            throw new SecurityException("Requires permission "
9209                    + android.Manifest.permission.SHUTDOWN);
9210        }
9211
9212        boolean timedout = false;
9213
9214        synchronized(this) {
9215            mShuttingDown = true;
9216            updateEventDispatchingLocked();
9217            timedout = mStackSupervisor.shutdownLocked(timeout);
9218        }
9219
9220        mAppOpsService.shutdown();
9221        if (mUsageStatsService != null) {
9222            mUsageStatsService.prepareShutdown();
9223        }
9224        mBatteryStatsService.shutdown();
9225        synchronized (this) {
9226            mProcessStats.shutdownLocked();
9227        }
9228        notifyTaskPersisterLocked(null, true);
9229
9230        return timedout;
9231    }
9232
9233    public final void activitySlept(IBinder token) {
9234        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9235
9236        final long origId = Binder.clearCallingIdentity();
9237
9238        synchronized (this) {
9239            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9240            if (r != null) {
9241                mStackSupervisor.activitySleptLocked(r);
9242            }
9243        }
9244
9245        Binder.restoreCallingIdentity(origId);
9246    }
9247
9248    void logLockScreen(String msg) {
9249        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9250                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9251                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9252                mStackSupervisor.mDismissKeyguardOnNextActivity);
9253    }
9254
9255    private void comeOutOfSleepIfNeededLocked() {
9256        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9257            if (mSleeping) {
9258                mSleeping = false;
9259                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9260            }
9261        }
9262    }
9263
9264    void wakingUp() {
9265        synchronized(this) {
9266            mWentToSleep = false;
9267            updateEventDispatchingLocked();
9268            comeOutOfSleepIfNeededLocked();
9269        }
9270    }
9271
9272    void startRunningVoiceLocked() {
9273        if (!mRunningVoice) {
9274            mRunningVoice = true;
9275            comeOutOfSleepIfNeededLocked();
9276        }
9277    }
9278
9279    private void updateEventDispatchingLocked() {
9280        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9281    }
9282
9283    public void setLockScreenShown(boolean shown) {
9284        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9285                != PackageManager.PERMISSION_GRANTED) {
9286            throw new SecurityException("Requires permission "
9287                    + android.Manifest.permission.DEVICE_POWER);
9288        }
9289
9290        synchronized(this) {
9291            long ident = Binder.clearCallingIdentity();
9292            try {
9293                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9294                mLockScreenShown = shown;
9295                comeOutOfSleepIfNeededLocked();
9296            } finally {
9297                Binder.restoreCallingIdentity(ident);
9298            }
9299        }
9300    }
9301
9302    @Override
9303    public void stopAppSwitches() {
9304        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9305                != PackageManager.PERMISSION_GRANTED) {
9306            throw new SecurityException("Requires permission "
9307                    + android.Manifest.permission.STOP_APP_SWITCHES);
9308        }
9309
9310        synchronized(this) {
9311            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9312                    + APP_SWITCH_DELAY_TIME;
9313            mDidAppSwitch = false;
9314            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9315            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9316            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9317        }
9318    }
9319
9320    public void resumeAppSwitches() {
9321        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9322                != PackageManager.PERMISSION_GRANTED) {
9323            throw new SecurityException("Requires permission "
9324                    + android.Manifest.permission.STOP_APP_SWITCHES);
9325        }
9326
9327        synchronized(this) {
9328            // Note that we don't execute any pending app switches... we will
9329            // let those wait until either the timeout, or the next start
9330            // activity request.
9331            mAppSwitchesAllowedTime = 0;
9332        }
9333    }
9334
9335    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9336            String name) {
9337        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9338            return true;
9339        }
9340
9341        final int perm = checkComponentPermission(
9342                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9343                callingUid, -1, true);
9344        if (perm == PackageManager.PERMISSION_GRANTED) {
9345            return true;
9346        }
9347
9348        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9349        return false;
9350    }
9351
9352    public void setDebugApp(String packageName, boolean waitForDebugger,
9353            boolean persistent) {
9354        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9355                "setDebugApp()");
9356
9357        long ident = Binder.clearCallingIdentity();
9358        try {
9359            // Note that this is not really thread safe if there are multiple
9360            // callers into it at the same time, but that's not a situation we
9361            // care about.
9362            if (persistent) {
9363                final ContentResolver resolver = mContext.getContentResolver();
9364                Settings.Global.putString(
9365                    resolver, Settings.Global.DEBUG_APP,
9366                    packageName);
9367                Settings.Global.putInt(
9368                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9369                    waitForDebugger ? 1 : 0);
9370            }
9371
9372            synchronized (this) {
9373                if (!persistent) {
9374                    mOrigDebugApp = mDebugApp;
9375                    mOrigWaitForDebugger = mWaitForDebugger;
9376                }
9377                mDebugApp = packageName;
9378                mWaitForDebugger = waitForDebugger;
9379                mDebugTransient = !persistent;
9380                if (packageName != null) {
9381                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9382                            false, UserHandle.USER_ALL, "set debug app");
9383                }
9384            }
9385        } finally {
9386            Binder.restoreCallingIdentity(ident);
9387        }
9388    }
9389
9390    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9391        synchronized (this) {
9392            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9393            if (!isDebuggable) {
9394                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9395                    throw new SecurityException("Process not debuggable: " + app.packageName);
9396                }
9397            }
9398
9399            mOpenGlTraceApp = processName;
9400        }
9401    }
9402
9403    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9404            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9405        synchronized (this) {
9406            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9407            if (!isDebuggable) {
9408                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9409                    throw new SecurityException("Process not debuggable: " + app.packageName);
9410                }
9411            }
9412            mProfileApp = processName;
9413            mProfileFile = profileFile;
9414            if (mProfileFd != null) {
9415                try {
9416                    mProfileFd.close();
9417                } catch (IOException e) {
9418                }
9419                mProfileFd = null;
9420            }
9421            mProfileFd = profileFd;
9422            mProfileType = 0;
9423            mAutoStopProfiler = autoStopProfiler;
9424        }
9425    }
9426
9427    @Override
9428    public void setAlwaysFinish(boolean enabled) {
9429        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9430                "setAlwaysFinish()");
9431
9432        Settings.Global.putInt(
9433                mContext.getContentResolver(),
9434                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9435
9436        synchronized (this) {
9437            mAlwaysFinishActivities = enabled;
9438        }
9439    }
9440
9441    @Override
9442    public void setActivityController(IActivityController controller) {
9443        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9444                "setActivityController()");
9445        synchronized (this) {
9446            mController = controller;
9447            Watchdog.getInstance().setActivityController(controller);
9448        }
9449    }
9450
9451    @Override
9452    public void setUserIsMonkey(boolean userIsMonkey) {
9453        synchronized (this) {
9454            synchronized (mPidsSelfLocked) {
9455                final int callingPid = Binder.getCallingPid();
9456                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9457                if (precessRecord == null) {
9458                    throw new SecurityException("Unknown process: " + callingPid);
9459                }
9460                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9461                    throw new SecurityException("Only an instrumentation process "
9462                            + "with a UiAutomation can call setUserIsMonkey");
9463                }
9464            }
9465            mUserIsMonkey = userIsMonkey;
9466        }
9467    }
9468
9469    @Override
9470    public boolean isUserAMonkey() {
9471        synchronized (this) {
9472            // If there is a controller also implies the user is a monkey.
9473            return (mUserIsMonkey || mController != null);
9474        }
9475    }
9476
9477    public void requestBugReport() {
9478        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9479        SystemProperties.set("ctl.start", "bugreport");
9480    }
9481
9482    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9483        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9484    }
9485
9486    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9487        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9488            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9489        }
9490        return KEY_DISPATCHING_TIMEOUT;
9491    }
9492
9493    @Override
9494    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9495        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9496                != PackageManager.PERMISSION_GRANTED) {
9497            throw new SecurityException("Requires permission "
9498                    + android.Manifest.permission.FILTER_EVENTS);
9499        }
9500        ProcessRecord proc;
9501        long timeout;
9502        synchronized (this) {
9503            synchronized (mPidsSelfLocked) {
9504                proc = mPidsSelfLocked.get(pid);
9505            }
9506            timeout = getInputDispatchingTimeoutLocked(proc);
9507        }
9508
9509        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9510            return -1;
9511        }
9512
9513        return timeout;
9514    }
9515
9516    /**
9517     * Handle input dispatching timeouts.
9518     * Returns whether input dispatching should be aborted or not.
9519     */
9520    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9521            final ActivityRecord activity, final ActivityRecord parent,
9522            final boolean aboveSystem, String reason) {
9523        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9524                != PackageManager.PERMISSION_GRANTED) {
9525            throw new SecurityException("Requires permission "
9526                    + android.Manifest.permission.FILTER_EVENTS);
9527        }
9528
9529        final String annotation;
9530        if (reason == null) {
9531            annotation = "Input dispatching timed out";
9532        } else {
9533            annotation = "Input dispatching timed out (" + reason + ")";
9534        }
9535
9536        if (proc != null) {
9537            synchronized (this) {
9538                if (proc.debugging) {
9539                    return false;
9540                }
9541
9542                if (mDidDexOpt) {
9543                    // Give more time since we were dexopting.
9544                    mDidDexOpt = false;
9545                    return false;
9546                }
9547
9548                if (proc.instrumentationClass != null) {
9549                    Bundle info = new Bundle();
9550                    info.putString("shortMsg", "keyDispatchingTimedOut");
9551                    info.putString("longMsg", annotation);
9552                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9553                    return true;
9554                }
9555            }
9556            mHandler.post(new Runnable() {
9557                @Override
9558                public void run() {
9559                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9560                }
9561            });
9562        }
9563
9564        return true;
9565    }
9566
9567    public Bundle getAssistContextExtras(int requestType) {
9568        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9569                "getAssistContextExtras()");
9570        PendingAssistExtras pae;
9571        Bundle extras = new Bundle();
9572        synchronized (this) {
9573            ActivityRecord activity = getFocusedStack().mResumedActivity;
9574            if (activity == null) {
9575                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9576                return null;
9577            }
9578            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9579            if (activity.app == null || activity.app.thread == null) {
9580                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9581                return extras;
9582            }
9583            if (activity.app.pid == Binder.getCallingPid()) {
9584                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9585                return extras;
9586            }
9587            pae = new PendingAssistExtras(activity);
9588            try {
9589                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9590                        requestType);
9591                mPendingAssistExtras.add(pae);
9592                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9593            } catch (RemoteException e) {
9594                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9595                return extras;
9596            }
9597        }
9598        synchronized (pae) {
9599            while (!pae.haveResult) {
9600                try {
9601                    pae.wait();
9602                } catch (InterruptedException e) {
9603                }
9604            }
9605            if (pae.result != null) {
9606                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9607            }
9608        }
9609        synchronized (this) {
9610            mPendingAssistExtras.remove(pae);
9611            mHandler.removeCallbacks(pae);
9612        }
9613        return extras;
9614    }
9615
9616    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9617        PendingAssistExtras pae = (PendingAssistExtras)token;
9618        synchronized (pae) {
9619            pae.result = extras;
9620            pae.haveResult = true;
9621            pae.notifyAll();
9622        }
9623    }
9624
9625    public void registerProcessObserver(IProcessObserver observer) {
9626        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9627                "registerProcessObserver()");
9628        synchronized (this) {
9629            mProcessObservers.register(observer);
9630        }
9631    }
9632
9633    @Override
9634    public void unregisterProcessObserver(IProcessObserver observer) {
9635        synchronized (this) {
9636            mProcessObservers.unregister(observer);
9637        }
9638    }
9639
9640    @Override
9641    public boolean convertFromTranslucent(IBinder token) {
9642        final long origId = Binder.clearCallingIdentity();
9643        try {
9644            synchronized (this) {
9645                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9646                if (r == null) {
9647                    return false;
9648                }
9649                if (r.changeWindowTranslucency(true)) {
9650                    mWindowManager.setAppFullscreen(token, true);
9651                    r.task.stack.releaseMediaResources();
9652                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9653                    return true;
9654                }
9655                return false;
9656            }
9657        } finally {
9658            Binder.restoreCallingIdentity(origId);
9659        }
9660    }
9661
9662    @Override
9663    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9664        final long origId = Binder.clearCallingIdentity();
9665        try {
9666            synchronized (this) {
9667                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9668                if (r == null) {
9669                    return false;
9670                }
9671                int index = r.task.mActivities.lastIndexOf(r);
9672                if (index > 0) {
9673                    ActivityRecord under = r.task.mActivities.get(index - 1);
9674                    under.returningOptions = options;
9675                }
9676                if (r.changeWindowTranslucency(false)) {
9677                    r.task.stack.convertToTranslucent(r);
9678                    mWindowManager.setAppFullscreen(token, false);
9679                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9680                    return true;
9681                } else {
9682                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9683                    return false;
9684                }
9685            }
9686        } finally {
9687            Binder.restoreCallingIdentity(origId);
9688        }
9689    }
9690
9691    @Override
9692    public boolean setMediaPlaying(IBinder token, boolean playing) {
9693        final long origId = Binder.clearCallingIdentity();
9694        try {
9695            synchronized (this) {
9696                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9697                if (r != null) {
9698                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9699                }
9700            }
9701            return false;
9702        } finally {
9703            Binder.restoreCallingIdentity(origId);
9704        }
9705    }
9706
9707    @Override
9708    public boolean isBackgroundMediaPlaying(IBinder token) {
9709        final long origId = Binder.clearCallingIdentity();
9710        try {
9711            synchronized (this) {
9712                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9713                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9714                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9715                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9716                return playing;
9717            }
9718        } finally {
9719            Binder.restoreCallingIdentity(origId);
9720        }
9721    }
9722
9723    @Override
9724    public ActivityOptions getActivityOptions(IBinder token) {
9725        final long origId = Binder.clearCallingIdentity();
9726        try {
9727            synchronized (this) {
9728                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9729                if (r != null) {
9730                    final ActivityOptions activityOptions = r.pendingOptions;
9731                    r.pendingOptions = null;
9732                    return activityOptions;
9733                }
9734                return null;
9735            }
9736        } finally {
9737            Binder.restoreCallingIdentity(origId);
9738        }
9739    }
9740
9741    @Override
9742    public void setImmersive(IBinder token, boolean immersive) {
9743        synchronized(this) {
9744            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9745            if (r == null) {
9746                throw new IllegalArgumentException();
9747            }
9748            r.immersive = immersive;
9749
9750            // update associated state if we're frontmost
9751            if (r == mFocusedActivity) {
9752                if (DEBUG_IMMERSIVE) {
9753                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9754                }
9755                applyUpdateLockStateLocked(r);
9756            }
9757        }
9758    }
9759
9760    @Override
9761    public boolean isImmersive(IBinder token) {
9762        synchronized (this) {
9763            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9764            if (r == null) {
9765                throw new IllegalArgumentException();
9766            }
9767            return r.immersive;
9768        }
9769    }
9770
9771    public boolean isTopActivityImmersive() {
9772        enforceNotIsolatedCaller("startActivity");
9773        synchronized (this) {
9774            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9775            return (r != null) ? r.immersive : false;
9776        }
9777    }
9778
9779    @Override
9780    public boolean isTopOfTask(IBinder token) {
9781        synchronized (this) {
9782            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9783            if (r == null) {
9784                throw new IllegalArgumentException();
9785            }
9786            return r.task.getTopActivity() == r;
9787        }
9788    }
9789
9790    public final void enterSafeMode() {
9791        synchronized(this) {
9792            // It only makes sense to do this before the system is ready
9793            // and started launching other packages.
9794            if (!mSystemReady) {
9795                try {
9796                    AppGlobals.getPackageManager().enterSafeMode();
9797                } catch (RemoteException e) {
9798                }
9799            }
9800
9801            mSafeMode = true;
9802        }
9803    }
9804
9805    public final void showSafeModeOverlay() {
9806        View v = LayoutInflater.from(mContext).inflate(
9807                com.android.internal.R.layout.safe_mode, null);
9808        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9809        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9810        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9811        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9812        lp.gravity = Gravity.BOTTOM | Gravity.START;
9813        lp.format = v.getBackground().getOpacity();
9814        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9815                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9816        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9817        ((WindowManager)mContext.getSystemService(
9818                Context.WINDOW_SERVICE)).addView(v, lp);
9819    }
9820
9821    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9822        if (!(sender instanceof PendingIntentRecord)) {
9823            return;
9824        }
9825        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9826        synchronized (stats) {
9827            if (mBatteryStatsService.isOnBattery()) {
9828                mBatteryStatsService.enforceCallingPermission();
9829                PendingIntentRecord rec = (PendingIntentRecord)sender;
9830                int MY_UID = Binder.getCallingUid();
9831                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9832                BatteryStatsImpl.Uid.Pkg pkg =
9833                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9834                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9835                pkg.incWakeupsLocked();
9836            }
9837        }
9838    }
9839
9840    public boolean killPids(int[] pids, String pReason, boolean secure) {
9841        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9842            throw new SecurityException("killPids only available to the system");
9843        }
9844        String reason = (pReason == null) ? "Unknown" : pReason;
9845        // XXX Note: don't acquire main activity lock here, because the window
9846        // manager calls in with its locks held.
9847
9848        boolean killed = false;
9849        synchronized (mPidsSelfLocked) {
9850            int[] types = new int[pids.length];
9851            int worstType = 0;
9852            for (int i=0; i<pids.length; i++) {
9853                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9854                if (proc != null) {
9855                    int type = proc.setAdj;
9856                    types[i] = type;
9857                    if (type > worstType) {
9858                        worstType = type;
9859                    }
9860                }
9861            }
9862
9863            // If the worst oom_adj is somewhere in the cached proc LRU range,
9864            // then constrain it so we will kill all cached procs.
9865            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9866                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9867                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9868            }
9869
9870            // If this is not a secure call, don't let it kill processes that
9871            // are important.
9872            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9873                worstType = ProcessList.SERVICE_ADJ;
9874            }
9875
9876            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9877            for (int i=0; i<pids.length; i++) {
9878                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9879                if (proc == null) {
9880                    continue;
9881                }
9882                int adj = proc.setAdj;
9883                if (adj >= worstType && !proc.killedByAm) {
9884                    killUnneededProcessLocked(proc, reason);
9885                    killed = true;
9886                }
9887            }
9888        }
9889        return killed;
9890    }
9891
9892    @Override
9893    public void killUid(int uid, String reason) {
9894        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9895            throw new SecurityException("killUid only available to the system");
9896        }
9897        synchronized (this) {
9898            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9899                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9900                    reason != null ? reason : "kill uid");
9901        }
9902    }
9903
9904    @Override
9905    public boolean killProcessesBelowForeground(String reason) {
9906        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9907            throw new SecurityException("killProcessesBelowForeground() only available to system");
9908        }
9909
9910        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9911    }
9912
9913    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9914        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9915            throw new SecurityException("killProcessesBelowAdj() only available to system");
9916        }
9917
9918        boolean killed = false;
9919        synchronized (mPidsSelfLocked) {
9920            final int size = mPidsSelfLocked.size();
9921            for (int i = 0; i < size; i++) {
9922                final int pid = mPidsSelfLocked.keyAt(i);
9923                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9924                if (proc == null) continue;
9925
9926                final int adj = proc.setAdj;
9927                if (adj > belowAdj && !proc.killedByAm) {
9928                    killUnneededProcessLocked(proc, reason);
9929                    killed = true;
9930                }
9931            }
9932        }
9933        return killed;
9934    }
9935
9936    @Override
9937    public void hang(final IBinder who, boolean allowRestart) {
9938        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9939                != PackageManager.PERMISSION_GRANTED) {
9940            throw new SecurityException("Requires permission "
9941                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9942        }
9943
9944        final IBinder.DeathRecipient death = new DeathRecipient() {
9945            @Override
9946            public void binderDied() {
9947                synchronized (this) {
9948                    notifyAll();
9949                }
9950            }
9951        };
9952
9953        try {
9954            who.linkToDeath(death, 0);
9955        } catch (RemoteException e) {
9956            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9957            return;
9958        }
9959
9960        synchronized (this) {
9961            Watchdog.getInstance().setAllowRestart(allowRestart);
9962            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9963            synchronized (death) {
9964                while (who.isBinderAlive()) {
9965                    try {
9966                        death.wait();
9967                    } catch (InterruptedException e) {
9968                    }
9969                }
9970            }
9971            Watchdog.getInstance().setAllowRestart(true);
9972        }
9973    }
9974
9975    @Override
9976    public void restart() {
9977        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9978                != PackageManager.PERMISSION_GRANTED) {
9979            throw new SecurityException("Requires permission "
9980                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9981        }
9982
9983        Log.i(TAG, "Sending shutdown broadcast...");
9984
9985        BroadcastReceiver br = new BroadcastReceiver() {
9986            @Override public void onReceive(Context context, Intent intent) {
9987                // Now the broadcast is done, finish up the low-level shutdown.
9988                Log.i(TAG, "Shutting down activity manager...");
9989                shutdown(10000);
9990                Log.i(TAG, "Shutdown complete, restarting!");
9991                Process.killProcess(Process.myPid());
9992                System.exit(10);
9993            }
9994        };
9995
9996        // First send the high-level shut down broadcast.
9997        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9998        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9999        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10000        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10001        mContext.sendOrderedBroadcastAsUser(intent,
10002                UserHandle.ALL, null, br, mHandler, 0, null, null);
10003        */
10004        br.onReceive(mContext, intent);
10005    }
10006
10007    private long getLowRamTimeSinceIdle(long now) {
10008        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10009    }
10010
10011    @Override
10012    public void performIdleMaintenance() {
10013        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10014                != PackageManager.PERMISSION_GRANTED) {
10015            throw new SecurityException("Requires permission "
10016                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10017        }
10018
10019        synchronized (this) {
10020            final long now = SystemClock.uptimeMillis();
10021            final long timeSinceLastIdle = now - mLastIdleTime;
10022            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10023            mLastIdleTime = now;
10024            mLowRamTimeSinceLastIdle = 0;
10025            if (mLowRamStartTime != 0) {
10026                mLowRamStartTime = now;
10027            }
10028
10029            StringBuilder sb = new StringBuilder(128);
10030            sb.append("Idle maintenance over ");
10031            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10032            sb.append(" low RAM for ");
10033            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10034            Slog.i(TAG, sb.toString());
10035
10036            // If at least 1/3 of our time since the last idle period has been spent
10037            // with RAM low, then we want to kill processes.
10038            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10039
10040            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10041                ProcessRecord proc = mLruProcesses.get(i);
10042                if (proc.notCachedSinceIdle) {
10043                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10044                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10045                        if (doKilling && proc.initialIdlePss != 0
10046                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10047                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10048                                    + " from " + proc.initialIdlePss + ")");
10049                        }
10050                    }
10051                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10052                    proc.notCachedSinceIdle = true;
10053                    proc.initialIdlePss = 0;
10054                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10055                            isSleeping(), now);
10056                }
10057            }
10058
10059            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10060            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10061        }
10062    }
10063
10064    private void retrieveSettings() {
10065        final ContentResolver resolver = mContext.getContentResolver();
10066        String debugApp = Settings.Global.getString(
10067            resolver, Settings.Global.DEBUG_APP);
10068        boolean waitForDebugger = Settings.Global.getInt(
10069            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10070        boolean alwaysFinishActivities = Settings.Global.getInt(
10071            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10072        boolean forceRtl = Settings.Global.getInt(
10073                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10074        // Transfer any global setting for forcing RTL layout, into a System Property
10075        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10076
10077        Configuration configuration = new Configuration();
10078        Settings.System.getConfiguration(resolver, configuration);
10079        if (forceRtl) {
10080            // This will take care of setting the correct layout direction flags
10081            configuration.setLayoutDirection(configuration.locale);
10082        }
10083
10084        synchronized (this) {
10085            mDebugApp = mOrigDebugApp = debugApp;
10086            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10087            mAlwaysFinishActivities = alwaysFinishActivities;
10088            // This happens before any activities are started, so we can
10089            // change mConfiguration in-place.
10090            updateConfigurationLocked(configuration, null, false, true);
10091            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10092        }
10093    }
10094
10095    public boolean testIsSystemReady() {
10096        // no need to synchronize(this) just to read & return the value
10097        return mSystemReady;
10098    }
10099
10100    private static File getCalledPreBootReceiversFile() {
10101        File dataDir = Environment.getDataDirectory();
10102        File systemDir = new File(dataDir, "system");
10103        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10104        return fname;
10105    }
10106
10107    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10108        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10109        File file = getCalledPreBootReceiversFile();
10110        FileInputStream fis = null;
10111        try {
10112            fis = new FileInputStream(file);
10113            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10114            int fvers = dis.readInt();
10115            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10116                String vers = dis.readUTF();
10117                String codename = dis.readUTF();
10118                String build = dis.readUTF();
10119                if (android.os.Build.VERSION.RELEASE.equals(vers)
10120                        && android.os.Build.VERSION.CODENAME.equals(codename)
10121                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10122                    int num = dis.readInt();
10123                    while (num > 0) {
10124                        num--;
10125                        String pkg = dis.readUTF();
10126                        String cls = dis.readUTF();
10127                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10128                    }
10129                }
10130            }
10131        } catch (FileNotFoundException e) {
10132        } catch (IOException e) {
10133            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10134        } finally {
10135            if (fis != null) {
10136                try {
10137                    fis.close();
10138                } catch (IOException e) {
10139                }
10140            }
10141        }
10142        return lastDoneReceivers;
10143    }
10144
10145    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10146        File file = getCalledPreBootReceiversFile();
10147        FileOutputStream fos = null;
10148        DataOutputStream dos = null;
10149        try {
10150            fos = new FileOutputStream(file);
10151            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10152            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10153            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10154            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10155            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10156            dos.writeInt(list.size());
10157            for (int i=0; i<list.size(); i++) {
10158                dos.writeUTF(list.get(i).getPackageName());
10159                dos.writeUTF(list.get(i).getClassName());
10160            }
10161        } catch (IOException e) {
10162            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10163            file.delete();
10164        } finally {
10165            FileUtils.sync(fos);
10166            if (dos != null) {
10167                try {
10168                    dos.close();
10169                } catch (IOException e) {
10170                    // TODO Auto-generated catch block
10171                    e.printStackTrace();
10172                }
10173            }
10174        }
10175    }
10176
10177    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10178            ArrayList<ComponentName> doneReceivers, int userId) {
10179        boolean waitingUpdate = false;
10180        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10181        List<ResolveInfo> ris = null;
10182        try {
10183            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10184                    intent, null, 0, userId);
10185        } catch (RemoteException e) {
10186        }
10187        if (ris != null) {
10188            for (int i=ris.size()-1; i>=0; i--) {
10189                if ((ris.get(i).activityInfo.applicationInfo.flags
10190                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10191                    ris.remove(i);
10192                }
10193            }
10194            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10195
10196            // For User 0, load the version number. When delivering to a new user, deliver
10197            // to all receivers.
10198            if (userId == UserHandle.USER_OWNER) {
10199                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10200                for (int i=0; i<ris.size(); i++) {
10201                    ActivityInfo ai = ris.get(i).activityInfo;
10202                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10203                    if (lastDoneReceivers.contains(comp)) {
10204                        // We already did the pre boot receiver for this app with the current
10205                        // platform version, so don't do it again...
10206                        ris.remove(i);
10207                        i--;
10208                        // ...however, do keep it as one that has been done, so we don't
10209                        // forget about it when rewriting the file of last done receivers.
10210                        doneReceivers.add(comp);
10211                    }
10212                }
10213            }
10214
10215            // If primary user, send broadcast to all available users, else just to userId
10216            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10217                    : new int[] { userId };
10218            for (int i = 0; i < ris.size(); i++) {
10219                ActivityInfo ai = ris.get(i).activityInfo;
10220                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10221                doneReceivers.add(comp);
10222                intent.setComponent(comp);
10223                for (int j=0; j<users.length; j++) {
10224                    IIntentReceiver finisher = null;
10225                    // On last receiver and user, set up a completion callback
10226                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10227                        finisher = new IIntentReceiver.Stub() {
10228                            public void performReceive(Intent intent, int resultCode,
10229                                    String data, Bundle extras, boolean ordered,
10230                                    boolean sticky, int sendingUser) {
10231                                // The raw IIntentReceiver interface is called
10232                                // with the AM lock held, so redispatch to
10233                                // execute our code without the lock.
10234                                mHandler.post(onFinishCallback);
10235                            }
10236                        };
10237                    }
10238                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10239                            + " for user " + users[j]);
10240                    broadcastIntentLocked(null, null, intent, null, finisher,
10241                            0, null, null, null, AppOpsManager.OP_NONE,
10242                            true, false, MY_PID, Process.SYSTEM_UID,
10243                            users[j]);
10244                    if (finisher != null) {
10245                        waitingUpdate = true;
10246                    }
10247                }
10248            }
10249        }
10250
10251        return waitingUpdate;
10252    }
10253
10254    public void systemReady(final Runnable goingCallback) {
10255        synchronized(this) {
10256            if (mSystemReady) {
10257                // If we're done calling all the receivers, run the next "boot phase" passed in
10258                // by the SystemServer
10259                if (goingCallback != null) {
10260                    goingCallback.run();
10261                }
10262                return;
10263            }
10264
10265            // Make sure we have the current profile info, since it is needed for
10266            // security checks.
10267            updateCurrentProfileIdsLocked();
10268
10269            if (mRecentTasks == null) {
10270                mRecentTasks = mTaskPersister.restoreTasksLocked();
10271                if (!mRecentTasks.isEmpty()) {
10272                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10273                }
10274                mTaskPersister.startPersisting();
10275            }
10276
10277            // Check to see if there are any update receivers to run.
10278            if (!mDidUpdate) {
10279                if (mWaitingUpdate) {
10280                    return;
10281                }
10282                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10283                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10284                    public void run() {
10285                        synchronized (ActivityManagerService.this) {
10286                            mDidUpdate = true;
10287                        }
10288                        writeLastDonePreBootReceivers(doneReceivers);
10289                        showBootMessage(mContext.getText(
10290                                R.string.android_upgrading_complete),
10291                                false);
10292                        systemReady(goingCallback);
10293                    }
10294                }, doneReceivers, UserHandle.USER_OWNER);
10295
10296                if (mWaitingUpdate) {
10297                    return;
10298                }
10299                mDidUpdate = true;
10300            }
10301
10302            mAppOpsService.systemReady();
10303            mSystemReady = true;
10304        }
10305
10306        ArrayList<ProcessRecord> procsToKill = null;
10307        synchronized(mPidsSelfLocked) {
10308            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10309                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10310                if (!isAllowedWhileBooting(proc.info)){
10311                    if (procsToKill == null) {
10312                        procsToKill = new ArrayList<ProcessRecord>();
10313                    }
10314                    procsToKill.add(proc);
10315                }
10316            }
10317        }
10318
10319        synchronized(this) {
10320            if (procsToKill != null) {
10321                for (int i=procsToKill.size()-1; i>=0; i--) {
10322                    ProcessRecord proc = procsToKill.get(i);
10323                    Slog.i(TAG, "Removing system update proc: " + proc);
10324                    removeProcessLocked(proc, true, false, "system update done");
10325                }
10326            }
10327
10328            // Now that we have cleaned up any update processes, we
10329            // are ready to start launching real processes and know that
10330            // we won't trample on them any more.
10331            mProcessesReady = true;
10332        }
10333
10334        Slog.i(TAG, "System now ready");
10335        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10336            SystemClock.uptimeMillis());
10337
10338        synchronized(this) {
10339            // Make sure we have no pre-ready processes sitting around.
10340
10341            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10342                ResolveInfo ri = mContext.getPackageManager()
10343                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10344                                STOCK_PM_FLAGS);
10345                CharSequence errorMsg = null;
10346                if (ri != null) {
10347                    ActivityInfo ai = ri.activityInfo;
10348                    ApplicationInfo app = ai.applicationInfo;
10349                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10350                        mTopAction = Intent.ACTION_FACTORY_TEST;
10351                        mTopData = null;
10352                        mTopComponent = new ComponentName(app.packageName,
10353                                ai.name);
10354                    } else {
10355                        errorMsg = mContext.getResources().getText(
10356                                com.android.internal.R.string.factorytest_not_system);
10357                    }
10358                } else {
10359                    errorMsg = mContext.getResources().getText(
10360                            com.android.internal.R.string.factorytest_no_action);
10361                }
10362                if (errorMsg != null) {
10363                    mTopAction = null;
10364                    mTopData = null;
10365                    mTopComponent = null;
10366                    Message msg = Message.obtain();
10367                    msg.what = SHOW_FACTORY_ERROR_MSG;
10368                    msg.getData().putCharSequence("msg", errorMsg);
10369                    mHandler.sendMessage(msg);
10370                }
10371            }
10372        }
10373
10374        retrieveSettings();
10375
10376        synchronized (this) {
10377            readGrantedUriPermissionsLocked();
10378        }
10379
10380        if (goingCallback != null) goingCallback.run();
10381
10382        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10383                Integer.toString(mCurrentUserId), mCurrentUserId);
10384        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10385                Integer.toString(mCurrentUserId), mCurrentUserId);
10386        mSystemServiceManager.startUser(mCurrentUserId);
10387
10388        synchronized (this) {
10389            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10390                try {
10391                    List apps = AppGlobals.getPackageManager().
10392                        getPersistentApplications(STOCK_PM_FLAGS);
10393                    if (apps != null) {
10394                        int N = apps.size();
10395                        int i;
10396                        for (i=0; i<N; i++) {
10397                            ApplicationInfo info
10398                                = (ApplicationInfo)apps.get(i);
10399                            if (info != null &&
10400                                    !info.packageName.equals("android")) {
10401                                addAppLocked(info, false, null /* ABI override */);
10402                            }
10403                        }
10404                    }
10405                } catch (RemoteException ex) {
10406                    // pm is in same process, this will never happen.
10407                }
10408            }
10409
10410            // Start up initial activity.
10411            mBooting = true;
10412
10413            try {
10414                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10415                    Message msg = Message.obtain();
10416                    msg.what = SHOW_UID_ERROR_MSG;
10417                    mHandler.sendMessage(msg);
10418                }
10419            } catch (RemoteException e) {
10420            }
10421
10422            long ident = Binder.clearCallingIdentity();
10423            try {
10424                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10425                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10426                        | Intent.FLAG_RECEIVER_FOREGROUND);
10427                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10428                broadcastIntentLocked(null, null, intent,
10429                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10430                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10431                intent = new Intent(Intent.ACTION_USER_STARTING);
10432                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10433                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10434                broadcastIntentLocked(null, null, intent,
10435                        null, new IIntentReceiver.Stub() {
10436                            @Override
10437                            public void performReceive(Intent intent, int resultCode, String data,
10438                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10439                                    throws RemoteException {
10440                            }
10441                        }, 0, null, null,
10442                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10443                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10444            } catch (Throwable t) {
10445                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10446            } finally {
10447                Binder.restoreCallingIdentity(ident);
10448            }
10449            mStackSupervisor.resumeTopActivitiesLocked();
10450            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10451        }
10452    }
10453
10454    private boolean makeAppCrashingLocked(ProcessRecord app,
10455            String shortMsg, String longMsg, String stackTrace) {
10456        app.crashing = true;
10457        app.crashingReport = generateProcessError(app,
10458                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10459        startAppProblemLocked(app);
10460        app.stopFreezingAllLocked();
10461        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10462    }
10463
10464    private void makeAppNotRespondingLocked(ProcessRecord app,
10465            String activity, String shortMsg, String longMsg) {
10466        app.notResponding = true;
10467        app.notRespondingReport = generateProcessError(app,
10468                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10469                activity, shortMsg, longMsg, null);
10470        startAppProblemLocked(app);
10471        app.stopFreezingAllLocked();
10472    }
10473
10474    /**
10475     * Generate a process error record, suitable for attachment to a ProcessRecord.
10476     *
10477     * @param app The ProcessRecord in which the error occurred.
10478     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10479     *                      ActivityManager.AppErrorStateInfo
10480     * @param activity The activity associated with the crash, if known.
10481     * @param shortMsg Short message describing the crash.
10482     * @param longMsg Long message describing the crash.
10483     * @param stackTrace Full crash stack trace, may be null.
10484     *
10485     * @return Returns a fully-formed AppErrorStateInfo record.
10486     */
10487    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10488            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10489        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10490
10491        report.condition = condition;
10492        report.processName = app.processName;
10493        report.pid = app.pid;
10494        report.uid = app.info.uid;
10495        report.tag = activity;
10496        report.shortMsg = shortMsg;
10497        report.longMsg = longMsg;
10498        report.stackTrace = stackTrace;
10499
10500        return report;
10501    }
10502
10503    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10504        synchronized (this) {
10505            app.crashing = false;
10506            app.crashingReport = null;
10507            app.notResponding = false;
10508            app.notRespondingReport = null;
10509            if (app.anrDialog == fromDialog) {
10510                app.anrDialog = null;
10511            }
10512            if (app.waitDialog == fromDialog) {
10513                app.waitDialog = null;
10514            }
10515            if (app.pid > 0 && app.pid != MY_PID) {
10516                handleAppCrashLocked(app, null, null, null);
10517                killUnneededProcessLocked(app, "user request after error");
10518            }
10519        }
10520    }
10521
10522    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10523            String stackTrace) {
10524        long now = SystemClock.uptimeMillis();
10525
10526        Long crashTime;
10527        if (!app.isolated) {
10528            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10529        } else {
10530            crashTime = null;
10531        }
10532        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10533            // This process loses!
10534            Slog.w(TAG, "Process " + app.info.processName
10535                    + " has crashed too many times: killing!");
10536            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10537                    app.userId, app.info.processName, app.uid);
10538            mStackSupervisor.handleAppCrashLocked(app);
10539            if (!app.persistent) {
10540                // We don't want to start this process again until the user
10541                // explicitly does so...  but for persistent process, we really
10542                // need to keep it running.  If a persistent process is actually
10543                // repeatedly crashing, then badness for everyone.
10544                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10545                        app.info.processName);
10546                if (!app.isolated) {
10547                    // XXX We don't have a way to mark isolated processes
10548                    // as bad, since they don't have a peristent identity.
10549                    mBadProcesses.put(app.info.processName, app.uid,
10550                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10551                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10552                }
10553                app.bad = true;
10554                app.removed = true;
10555                // Don't let services in this process be restarted and potentially
10556                // annoy the user repeatedly.  Unless it is persistent, since those
10557                // processes run critical code.
10558                removeProcessLocked(app, false, false, "crash");
10559                mStackSupervisor.resumeTopActivitiesLocked();
10560                return false;
10561            }
10562            mStackSupervisor.resumeTopActivitiesLocked();
10563        } else {
10564            mStackSupervisor.finishTopRunningActivityLocked(app);
10565        }
10566
10567        // Bump up the crash count of any services currently running in the proc.
10568        for (int i=app.services.size()-1; i>=0; i--) {
10569            // Any services running in the application need to be placed
10570            // back in the pending list.
10571            ServiceRecord sr = app.services.valueAt(i);
10572            sr.crashCount++;
10573        }
10574
10575        // If the crashing process is what we consider to be the "home process" and it has been
10576        // replaced by a third-party app, clear the package preferred activities from packages
10577        // with a home activity running in the process to prevent a repeatedly crashing app
10578        // from blocking the user to manually clear the list.
10579        final ArrayList<ActivityRecord> activities = app.activities;
10580        if (app == mHomeProcess && activities.size() > 0
10581                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10582            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10583                final ActivityRecord r = activities.get(activityNdx);
10584                if (r.isHomeActivity()) {
10585                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10586                    try {
10587                        ActivityThread.getPackageManager()
10588                                .clearPackagePreferredActivities(r.packageName);
10589                    } catch (RemoteException c) {
10590                        // pm is in same process, this will never happen.
10591                    }
10592                }
10593            }
10594        }
10595
10596        if (!app.isolated) {
10597            // XXX Can't keep track of crash times for isolated processes,
10598            // because they don't have a perisistent identity.
10599            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10600        }
10601
10602        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10603        return true;
10604    }
10605
10606    void startAppProblemLocked(ProcessRecord app) {
10607        // If this app is not running under the current user, then we
10608        // can't give it a report button because that would require
10609        // launching the report UI under a different user.
10610        app.errorReportReceiver = null;
10611
10612        for (int userId : mCurrentProfileIds) {
10613            if (app.userId == userId) {
10614                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10615                        mContext, app.info.packageName, app.info.flags);
10616            }
10617        }
10618        skipCurrentReceiverLocked(app);
10619    }
10620
10621    void skipCurrentReceiverLocked(ProcessRecord app) {
10622        for (BroadcastQueue queue : mBroadcastQueues) {
10623            queue.skipCurrentReceiverLocked(app);
10624        }
10625    }
10626
10627    /**
10628     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10629     * The application process will exit immediately after this call returns.
10630     * @param app object of the crashing app, null for the system server
10631     * @param crashInfo describing the exception
10632     */
10633    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10634        ProcessRecord r = findAppProcess(app, "Crash");
10635        final String processName = app == null ? "system_server"
10636                : (r == null ? "unknown" : r.processName);
10637
10638        handleApplicationCrashInner("crash", r, processName, crashInfo);
10639    }
10640
10641    /* Native crash reporting uses this inner version because it needs to be somewhat
10642     * decoupled from the AM-managed cleanup lifecycle
10643     */
10644    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10645            ApplicationErrorReport.CrashInfo crashInfo) {
10646        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10647                UserHandle.getUserId(Binder.getCallingUid()), processName,
10648                r == null ? -1 : r.info.flags,
10649                crashInfo.exceptionClassName,
10650                crashInfo.exceptionMessage,
10651                crashInfo.throwFileName,
10652                crashInfo.throwLineNumber);
10653
10654        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10655
10656        crashApplication(r, crashInfo);
10657    }
10658
10659    public void handleApplicationStrictModeViolation(
10660            IBinder app,
10661            int violationMask,
10662            StrictMode.ViolationInfo info) {
10663        ProcessRecord r = findAppProcess(app, "StrictMode");
10664        if (r == null) {
10665            return;
10666        }
10667
10668        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10669            Integer stackFingerprint = info.hashCode();
10670            boolean logIt = true;
10671            synchronized (mAlreadyLoggedViolatedStacks) {
10672                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10673                    logIt = false;
10674                    // TODO: sub-sample into EventLog for these, with
10675                    // the info.durationMillis?  Then we'd get
10676                    // the relative pain numbers, without logging all
10677                    // the stack traces repeatedly.  We'd want to do
10678                    // likewise in the client code, which also does
10679                    // dup suppression, before the Binder call.
10680                } else {
10681                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10682                        mAlreadyLoggedViolatedStacks.clear();
10683                    }
10684                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10685                }
10686            }
10687            if (logIt) {
10688                logStrictModeViolationToDropBox(r, info);
10689            }
10690        }
10691
10692        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10693            AppErrorResult result = new AppErrorResult();
10694            synchronized (this) {
10695                final long origId = Binder.clearCallingIdentity();
10696
10697                Message msg = Message.obtain();
10698                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10699                HashMap<String, Object> data = new HashMap<String, Object>();
10700                data.put("result", result);
10701                data.put("app", r);
10702                data.put("violationMask", violationMask);
10703                data.put("info", info);
10704                msg.obj = data;
10705                mHandler.sendMessage(msg);
10706
10707                Binder.restoreCallingIdentity(origId);
10708            }
10709            int res = result.get();
10710            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10711        }
10712    }
10713
10714    // Depending on the policy in effect, there could be a bunch of
10715    // these in quick succession so we try to batch these together to
10716    // minimize disk writes, number of dropbox entries, and maximize
10717    // compression, by having more fewer, larger records.
10718    private void logStrictModeViolationToDropBox(
10719            ProcessRecord process,
10720            StrictMode.ViolationInfo info) {
10721        if (info == null) {
10722            return;
10723        }
10724        final boolean isSystemApp = process == null ||
10725                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10726                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10727        final String processName = process == null ? "unknown" : process.processName;
10728        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10729        final DropBoxManager dbox = (DropBoxManager)
10730                mContext.getSystemService(Context.DROPBOX_SERVICE);
10731
10732        // Exit early if the dropbox isn't configured to accept this report type.
10733        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10734
10735        boolean bufferWasEmpty;
10736        boolean needsFlush;
10737        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10738        synchronized (sb) {
10739            bufferWasEmpty = sb.length() == 0;
10740            appendDropBoxProcessHeaders(process, processName, sb);
10741            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10742            sb.append("System-App: ").append(isSystemApp).append("\n");
10743            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10744            if (info.violationNumThisLoop != 0) {
10745                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10746            }
10747            if (info.numAnimationsRunning != 0) {
10748                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10749            }
10750            if (info.broadcastIntentAction != null) {
10751                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10752            }
10753            if (info.durationMillis != -1) {
10754                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10755            }
10756            if (info.numInstances != -1) {
10757                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10758            }
10759            if (info.tags != null) {
10760                for (String tag : info.tags) {
10761                    sb.append("Span-Tag: ").append(tag).append("\n");
10762                }
10763            }
10764            sb.append("\n");
10765            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10766                sb.append(info.crashInfo.stackTrace);
10767            }
10768            sb.append("\n");
10769
10770            // Only buffer up to ~64k.  Various logging bits truncate
10771            // things at 128k.
10772            needsFlush = (sb.length() > 64 * 1024);
10773        }
10774
10775        // Flush immediately if the buffer's grown too large, or this
10776        // is a non-system app.  Non-system apps are isolated with a
10777        // different tag & policy and not batched.
10778        //
10779        // Batching is useful during internal testing with
10780        // StrictMode settings turned up high.  Without batching,
10781        // thousands of separate files could be created on boot.
10782        if (!isSystemApp || needsFlush) {
10783            new Thread("Error dump: " + dropboxTag) {
10784                @Override
10785                public void run() {
10786                    String report;
10787                    synchronized (sb) {
10788                        report = sb.toString();
10789                        sb.delete(0, sb.length());
10790                        sb.trimToSize();
10791                    }
10792                    if (report.length() != 0) {
10793                        dbox.addText(dropboxTag, report);
10794                    }
10795                }
10796            }.start();
10797            return;
10798        }
10799
10800        // System app batching:
10801        if (!bufferWasEmpty) {
10802            // An existing dropbox-writing thread is outstanding, so
10803            // we don't need to start it up.  The existing thread will
10804            // catch the buffer appends we just did.
10805            return;
10806        }
10807
10808        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10809        // (After this point, we shouldn't access AMS internal data structures.)
10810        new Thread("Error dump: " + dropboxTag) {
10811            @Override
10812            public void run() {
10813                // 5 second sleep to let stacks arrive and be batched together
10814                try {
10815                    Thread.sleep(5000);  // 5 seconds
10816                } catch (InterruptedException e) {}
10817
10818                String errorReport;
10819                synchronized (mStrictModeBuffer) {
10820                    errorReport = mStrictModeBuffer.toString();
10821                    if (errorReport.length() == 0) {
10822                        return;
10823                    }
10824                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10825                    mStrictModeBuffer.trimToSize();
10826                }
10827                dbox.addText(dropboxTag, errorReport);
10828            }
10829        }.start();
10830    }
10831
10832    /**
10833     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10834     * @param app object of the crashing app, null for the system server
10835     * @param tag reported by the caller
10836     * @param crashInfo describing the context of the error
10837     * @return true if the process should exit immediately (WTF is fatal)
10838     */
10839    public boolean handleApplicationWtf(IBinder app, String tag,
10840            ApplicationErrorReport.CrashInfo crashInfo) {
10841        ProcessRecord r = findAppProcess(app, "WTF");
10842        final String processName = app == null ? "system_server"
10843                : (r == null ? "unknown" : r.processName);
10844
10845        EventLog.writeEvent(EventLogTags.AM_WTF,
10846                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10847                processName,
10848                r == null ? -1 : r.info.flags,
10849                tag, crashInfo.exceptionMessage);
10850
10851        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10852
10853        if (r != null && r.pid != Process.myPid() &&
10854                Settings.Global.getInt(mContext.getContentResolver(),
10855                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10856            crashApplication(r, crashInfo);
10857            return true;
10858        } else {
10859            return false;
10860        }
10861    }
10862
10863    /**
10864     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10865     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10866     */
10867    private ProcessRecord findAppProcess(IBinder app, String reason) {
10868        if (app == null) {
10869            return null;
10870        }
10871
10872        synchronized (this) {
10873            final int NP = mProcessNames.getMap().size();
10874            for (int ip=0; ip<NP; ip++) {
10875                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10876                final int NA = apps.size();
10877                for (int ia=0; ia<NA; ia++) {
10878                    ProcessRecord p = apps.valueAt(ia);
10879                    if (p.thread != null && p.thread.asBinder() == app) {
10880                        return p;
10881                    }
10882                }
10883            }
10884
10885            Slog.w(TAG, "Can't find mystery application for " + reason
10886                    + " from pid=" + Binder.getCallingPid()
10887                    + " uid=" + Binder.getCallingUid() + ": " + app);
10888            return null;
10889        }
10890    }
10891
10892    /**
10893     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10894     * to append various headers to the dropbox log text.
10895     */
10896    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10897            StringBuilder sb) {
10898        // Watchdog thread ends up invoking this function (with
10899        // a null ProcessRecord) to add the stack file to dropbox.
10900        // Do not acquire a lock on this (am) in such cases, as it
10901        // could cause a potential deadlock, if and when watchdog
10902        // is invoked due to unavailability of lock on am and it
10903        // would prevent watchdog from killing system_server.
10904        if (process == null) {
10905            sb.append("Process: ").append(processName).append("\n");
10906            return;
10907        }
10908        // Note: ProcessRecord 'process' is guarded by the service
10909        // instance.  (notably process.pkgList, which could otherwise change
10910        // concurrently during execution of this method)
10911        synchronized (this) {
10912            sb.append("Process: ").append(processName).append("\n");
10913            int flags = process.info.flags;
10914            IPackageManager pm = AppGlobals.getPackageManager();
10915            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10916            for (int ip=0; ip<process.pkgList.size(); ip++) {
10917                String pkg = process.pkgList.keyAt(ip);
10918                sb.append("Package: ").append(pkg);
10919                try {
10920                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10921                    if (pi != null) {
10922                        sb.append(" v").append(pi.versionCode);
10923                        if (pi.versionName != null) {
10924                            sb.append(" (").append(pi.versionName).append(")");
10925                        }
10926                    }
10927                } catch (RemoteException e) {
10928                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10929                }
10930                sb.append("\n");
10931            }
10932        }
10933    }
10934
10935    private static String processClass(ProcessRecord process) {
10936        if (process == null || process.pid == MY_PID) {
10937            return "system_server";
10938        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10939            return "system_app";
10940        } else {
10941            return "data_app";
10942        }
10943    }
10944
10945    /**
10946     * Write a description of an error (crash, WTF, ANR) to the drop box.
10947     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10948     * @param process which caused the error, null means the system server
10949     * @param activity which triggered the error, null if unknown
10950     * @param parent activity related to the error, null if unknown
10951     * @param subject line related to the error, null if absent
10952     * @param report in long form describing the error, null if absent
10953     * @param logFile to include in the report, null if none
10954     * @param crashInfo giving an application stack trace, null if absent
10955     */
10956    public void addErrorToDropBox(String eventType,
10957            ProcessRecord process, String processName, ActivityRecord activity,
10958            ActivityRecord parent, String subject,
10959            final String report, final File logFile,
10960            final ApplicationErrorReport.CrashInfo crashInfo) {
10961        // NOTE -- this must never acquire the ActivityManagerService lock,
10962        // otherwise the watchdog may be prevented from resetting the system.
10963
10964        final String dropboxTag = processClass(process) + "_" + eventType;
10965        final DropBoxManager dbox = (DropBoxManager)
10966                mContext.getSystemService(Context.DROPBOX_SERVICE);
10967
10968        // Exit early if the dropbox isn't configured to accept this report type.
10969        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10970
10971        final StringBuilder sb = new StringBuilder(1024);
10972        appendDropBoxProcessHeaders(process, processName, sb);
10973        if (activity != null) {
10974            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10975        }
10976        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10977            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10978        }
10979        if (parent != null && parent != activity) {
10980            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10981        }
10982        if (subject != null) {
10983            sb.append("Subject: ").append(subject).append("\n");
10984        }
10985        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10986        if (Debug.isDebuggerConnected()) {
10987            sb.append("Debugger: Connected\n");
10988        }
10989        sb.append("\n");
10990
10991        // Do the rest in a worker thread to avoid blocking the caller on I/O
10992        // (After this point, we shouldn't access AMS internal data structures.)
10993        Thread worker = new Thread("Error dump: " + dropboxTag) {
10994            @Override
10995            public void run() {
10996                if (report != null) {
10997                    sb.append(report);
10998                }
10999                if (logFile != null) {
11000                    try {
11001                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11002                                    "\n\n[[TRUNCATED]]"));
11003                    } catch (IOException e) {
11004                        Slog.e(TAG, "Error reading " + logFile, e);
11005                    }
11006                }
11007                if (crashInfo != null && crashInfo.stackTrace != null) {
11008                    sb.append(crashInfo.stackTrace);
11009                }
11010
11011                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11012                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11013                if (lines > 0) {
11014                    sb.append("\n");
11015
11016                    // Merge several logcat streams, and take the last N lines
11017                    InputStreamReader input = null;
11018                    try {
11019                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11020                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11021                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11022
11023                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11024                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11025                        input = new InputStreamReader(logcat.getInputStream());
11026
11027                        int num;
11028                        char[] buf = new char[8192];
11029                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11030                    } catch (IOException e) {
11031                        Slog.e(TAG, "Error running logcat", e);
11032                    } finally {
11033                        if (input != null) try { input.close(); } catch (IOException e) {}
11034                    }
11035                }
11036
11037                dbox.addText(dropboxTag, sb.toString());
11038            }
11039        };
11040
11041        if (process == null) {
11042            // If process is null, we are being called from some internal code
11043            // and may be about to die -- run this synchronously.
11044            worker.run();
11045        } else {
11046            worker.start();
11047        }
11048    }
11049
11050    /**
11051     * Bring up the "unexpected error" dialog box for a crashing app.
11052     * Deal with edge cases (intercepts from instrumented applications,
11053     * ActivityController, error intent receivers, that sort of thing).
11054     * @param r the application crashing
11055     * @param crashInfo describing the failure
11056     */
11057    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11058        long timeMillis = System.currentTimeMillis();
11059        String shortMsg = crashInfo.exceptionClassName;
11060        String longMsg = crashInfo.exceptionMessage;
11061        String stackTrace = crashInfo.stackTrace;
11062        if (shortMsg != null && longMsg != null) {
11063            longMsg = shortMsg + ": " + longMsg;
11064        } else if (shortMsg != null) {
11065            longMsg = shortMsg;
11066        }
11067
11068        AppErrorResult result = new AppErrorResult();
11069        synchronized (this) {
11070            if (mController != null) {
11071                try {
11072                    String name = r != null ? r.processName : null;
11073                    int pid = r != null ? r.pid : Binder.getCallingPid();
11074                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11075                    if (!mController.appCrashed(name, pid,
11076                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11077                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11078                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11079                            Slog.w(TAG, "Skip killing native crashed app " + name
11080                                    + "(" + pid + ") during testing");
11081                        } else {
11082                            Slog.w(TAG, "Force-killing crashed app " + name
11083                                    + " at watcher's request");
11084                            Process.killProcess(pid);
11085                            if (r != null) {
11086                                Process.killProcessGroup(uid, pid);
11087                            }
11088                        }
11089                        return;
11090                    }
11091                } catch (RemoteException e) {
11092                    mController = null;
11093                    Watchdog.getInstance().setActivityController(null);
11094                }
11095            }
11096
11097            final long origId = Binder.clearCallingIdentity();
11098
11099            // If this process is running instrumentation, finish it.
11100            if (r != null && r.instrumentationClass != null) {
11101                Slog.w(TAG, "Error in app " + r.processName
11102                      + " running instrumentation " + r.instrumentationClass + ":");
11103                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11104                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11105                Bundle info = new Bundle();
11106                info.putString("shortMsg", shortMsg);
11107                info.putString("longMsg", longMsg);
11108                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11109                Binder.restoreCallingIdentity(origId);
11110                return;
11111            }
11112
11113            // If we can't identify the process or it's already exceeded its crash quota,
11114            // quit right away without showing a crash dialog.
11115            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11116                Binder.restoreCallingIdentity(origId);
11117                return;
11118            }
11119
11120            Message msg = Message.obtain();
11121            msg.what = SHOW_ERROR_MSG;
11122            HashMap data = new HashMap();
11123            data.put("result", result);
11124            data.put("app", r);
11125            msg.obj = data;
11126            mHandler.sendMessage(msg);
11127
11128            Binder.restoreCallingIdentity(origId);
11129        }
11130
11131        int res = result.get();
11132
11133        Intent appErrorIntent = null;
11134        synchronized (this) {
11135            if (r != null && !r.isolated) {
11136                // XXX Can't keep track of crash time for isolated processes,
11137                // since they don't have a persistent identity.
11138                mProcessCrashTimes.put(r.info.processName, r.uid,
11139                        SystemClock.uptimeMillis());
11140            }
11141            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11142                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11143            }
11144        }
11145
11146        if (appErrorIntent != null) {
11147            try {
11148                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11149            } catch (ActivityNotFoundException e) {
11150                Slog.w(TAG, "bug report receiver dissappeared", e);
11151            }
11152        }
11153    }
11154
11155    Intent createAppErrorIntentLocked(ProcessRecord r,
11156            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11157        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11158        if (report == null) {
11159            return null;
11160        }
11161        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11162        result.setComponent(r.errorReportReceiver);
11163        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11164        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11165        return result;
11166    }
11167
11168    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11169            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11170        if (r.errorReportReceiver == null) {
11171            return null;
11172        }
11173
11174        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11175            return null;
11176        }
11177
11178        ApplicationErrorReport report = new ApplicationErrorReport();
11179        report.packageName = r.info.packageName;
11180        report.installerPackageName = r.errorReportReceiver.getPackageName();
11181        report.processName = r.processName;
11182        report.time = timeMillis;
11183        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11184
11185        if (r.crashing || r.forceCrashReport) {
11186            report.type = ApplicationErrorReport.TYPE_CRASH;
11187            report.crashInfo = crashInfo;
11188        } else if (r.notResponding) {
11189            report.type = ApplicationErrorReport.TYPE_ANR;
11190            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11191
11192            report.anrInfo.activity = r.notRespondingReport.tag;
11193            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11194            report.anrInfo.info = r.notRespondingReport.longMsg;
11195        }
11196
11197        return report;
11198    }
11199
11200    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11201        enforceNotIsolatedCaller("getProcessesInErrorState");
11202        // assume our apps are happy - lazy create the list
11203        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11204
11205        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11206                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11207        int userId = UserHandle.getUserId(Binder.getCallingUid());
11208
11209        synchronized (this) {
11210
11211            // iterate across all processes
11212            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11213                ProcessRecord app = mLruProcesses.get(i);
11214                if (!allUsers && app.userId != userId) {
11215                    continue;
11216                }
11217                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11218                    // This one's in trouble, so we'll generate a report for it
11219                    // crashes are higher priority (in case there's a crash *and* an anr)
11220                    ActivityManager.ProcessErrorStateInfo report = null;
11221                    if (app.crashing) {
11222                        report = app.crashingReport;
11223                    } else if (app.notResponding) {
11224                        report = app.notRespondingReport;
11225                    }
11226
11227                    if (report != null) {
11228                        if (errList == null) {
11229                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11230                        }
11231                        errList.add(report);
11232                    } else {
11233                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11234                                " crashing = " + app.crashing +
11235                                " notResponding = " + app.notResponding);
11236                    }
11237                }
11238            }
11239        }
11240
11241        return errList;
11242    }
11243
11244    static int procStateToImportance(int procState, int memAdj,
11245            ActivityManager.RunningAppProcessInfo currApp) {
11246        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11247        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11248            currApp.lru = memAdj;
11249        } else {
11250            currApp.lru = 0;
11251        }
11252        return imp;
11253    }
11254
11255    private void fillInProcMemInfo(ProcessRecord app,
11256            ActivityManager.RunningAppProcessInfo outInfo) {
11257        outInfo.pid = app.pid;
11258        outInfo.uid = app.info.uid;
11259        if (mHeavyWeightProcess == app) {
11260            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11261        }
11262        if (app.persistent) {
11263            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11264        }
11265        if (app.activities.size() > 0) {
11266            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11267        }
11268        outInfo.lastTrimLevel = app.trimMemoryLevel;
11269        int adj = app.curAdj;
11270        int procState = app.curProcState;
11271        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11272        outInfo.importanceReasonCode = app.adjTypeCode;
11273        outInfo.processState = app.curProcState;
11274    }
11275
11276    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11277        enforceNotIsolatedCaller("getRunningAppProcesses");
11278        // Lazy instantiation of list
11279        List<ActivityManager.RunningAppProcessInfo> runList = null;
11280        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11281                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11282        int userId = UserHandle.getUserId(Binder.getCallingUid());
11283        synchronized (this) {
11284            // Iterate across all processes
11285            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11286                ProcessRecord app = mLruProcesses.get(i);
11287                if (!allUsers && app.userId != userId) {
11288                    continue;
11289                }
11290                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11291                    // Generate process state info for running application
11292                    ActivityManager.RunningAppProcessInfo currApp =
11293                        new ActivityManager.RunningAppProcessInfo(app.processName,
11294                                app.pid, app.getPackageList());
11295                    fillInProcMemInfo(app, currApp);
11296                    if (app.adjSource instanceof ProcessRecord) {
11297                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11298                        currApp.importanceReasonImportance =
11299                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11300                                        app.adjSourceProcState);
11301                    } else if (app.adjSource instanceof ActivityRecord) {
11302                        ActivityRecord r = (ActivityRecord)app.adjSource;
11303                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11304                    }
11305                    if (app.adjTarget instanceof ComponentName) {
11306                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11307                    }
11308                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11309                    //        + " lru=" + currApp.lru);
11310                    if (runList == null) {
11311                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11312                    }
11313                    runList.add(currApp);
11314                }
11315            }
11316        }
11317        return runList;
11318    }
11319
11320    public List<ApplicationInfo> getRunningExternalApplications() {
11321        enforceNotIsolatedCaller("getRunningExternalApplications");
11322        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11323        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11324        if (runningApps != null && runningApps.size() > 0) {
11325            Set<String> extList = new HashSet<String>();
11326            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11327                if (app.pkgList != null) {
11328                    for (String pkg : app.pkgList) {
11329                        extList.add(pkg);
11330                    }
11331                }
11332            }
11333            IPackageManager pm = AppGlobals.getPackageManager();
11334            for (String pkg : extList) {
11335                try {
11336                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11337                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11338                        retList.add(info);
11339                    }
11340                } catch (RemoteException e) {
11341                }
11342            }
11343        }
11344        return retList;
11345    }
11346
11347    @Override
11348    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11349        enforceNotIsolatedCaller("getMyMemoryState");
11350        synchronized (this) {
11351            ProcessRecord proc;
11352            synchronized (mPidsSelfLocked) {
11353                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11354            }
11355            fillInProcMemInfo(proc, outInfo);
11356        }
11357    }
11358
11359    @Override
11360    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11361        if (checkCallingPermission(android.Manifest.permission.DUMP)
11362                != PackageManager.PERMISSION_GRANTED) {
11363            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11364                    + Binder.getCallingPid()
11365                    + ", uid=" + Binder.getCallingUid()
11366                    + " without permission "
11367                    + android.Manifest.permission.DUMP);
11368            return;
11369        }
11370
11371        boolean dumpAll = false;
11372        boolean dumpClient = false;
11373        String dumpPackage = null;
11374
11375        int opti = 0;
11376        while (opti < args.length) {
11377            String opt = args[opti];
11378            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11379                break;
11380            }
11381            opti++;
11382            if ("-a".equals(opt)) {
11383                dumpAll = true;
11384            } else if ("-c".equals(opt)) {
11385                dumpClient = true;
11386            } else if ("-h".equals(opt)) {
11387                pw.println("Activity manager dump options:");
11388                pw.println("  [-a] [-c] [-h] [cmd] ...");
11389                pw.println("  cmd may be one of:");
11390                pw.println("    a[ctivities]: activity stack state");
11391                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11392                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11393                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11394                pw.println("    o[om]: out of memory management");
11395                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11396                pw.println("    provider [COMP_SPEC]: provider client-side state");
11397                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11398                pw.println("    service [COMP_SPEC]: service client-side state");
11399                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11400                pw.println("    all: dump all activities");
11401                pw.println("    top: dump the top activity");
11402                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11403                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11404                pw.println("    a partial substring in a component name, a");
11405                pw.println("    hex object identifier.");
11406                pw.println("  -a: include all available server state.");
11407                pw.println("  -c: include client state.");
11408                return;
11409            } else {
11410                pw.println("Unknown argument: " + opt + "; use -h for help");
11411            }
11412        }
11413
11414        long origId = Binder.clearCallingIdentity();
11415        boolean more = false;
11416        // Is the caller requesting to dump a particular piece of data?
11417        if (opti < args.length) {
11418            String cmd = args[opti];
11419            opti++;
11420            if ("activities".equals(cmd) || "a".equals(cmd)) {
11421                synchronized (this) {
11422                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11423                }
11424            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11425                String[] newArgs;
11426                String name;
11427                if (opti >= args.length) {
11428                    name = null;
11429                    newArgs = EMPTY_STRING_ARRAY;
11430                } else {
11431                    name = args[opti];
11432                    opti++;
11433                    newArgs = new String[args.length - opti];
11434                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11435                            args.length - opti);
11436                }
11437                synchronized (this) {
11438                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11439                }
11440            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11441                String[] newArgs;
11442                String name;
11443                if (opti >= args.length) {
11444                    name = null;
11445                    newArgs = EMPTY_STRING_ARRAY;
11446                } else {
11447                    name = args[opti];
11448                    opti++;
11449                    newArgs = new String[args.length - opti];
11450                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11451                            args.length - opti);
11452                }
11453                synchronized (this) {
11454                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11455                }
11456            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11457                String[] newArgs;
11458                String name;
11459                if (opti >= args.length) {
11460                    name = null;
11461                    newArgs = EMPTY_STRING_ARRAY;
11462                } else {
11463                    name = args[opti];
11464                    opti++;
11465                    newArgs = new String[args.length - opti];
11466                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11467                            args.length - opti);
11468                }
11469                synchronized (this) {
11470                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11471                }
11472            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11473                synchronized (this) {
11474                    dumpOomLocked(fd, pw, args, opti, true);
11475                }
11476            } else if ("provider".equals(cmd)) {
11477                String[] newArgs;
11478                String name;
11479                if (opti >= args.length) {
11480                    name = null;
11481                    newArgs = EMPTY_STRING_ARRAY;
11482                } else {
11483                    name = args[opti];
11484                    opti++;
11485                    newArgs = new String[args.length - opti];
11486                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11487                }
11488                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11489                    pw.println("No providers match: " + name);
11490                    pw.println("Use -h for help.");
11491                }
11492            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11493                synchronized (this) {
11494                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11495                }
11496            } else if ("service".equals(cmd)) {
11497                String[] newArgs;
11498                String name;
11499                if (opti >= args.length) {
11500                    name = null;
11501                    newArgs = EMPTY_STRING_ARRAY;
11502                } else {
11503                    name = args[opti];
11504                    opti++;
11505                    newArgs = new String[args.length - opti];
11506                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11507                            args.length - opti);
11508                }
11509                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11510                    pw.println("No services match: " + name);
11511                    pw.println("Use -h for help.");
11512                }
11513            } else if ("package".equals(cmd)) {
11514                String[] newArgs;
11515                if (opti >= args.length) {
11516                    pw.println("package: no package name specified");
11517                    pw.println("Use -h for help.");
11518                } else {
11519                    dumpPackage = args[opti];
11520                    opti++;
11521                    newArgs = new String[args.length - opti];
11522                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11523                            args.length - opti);
11524                    args = newArgs;
11525                    opti = 0;
11526                    more = true;
11527                }
11528            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11529                synchronized (this) {
11530                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11531                }
11532            } else {
11533                // Dumping a single activity?
11534                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11535                    pw.println("Bad activity command, or no activities match: " + cmd);
11536                    pw.println("Use -h for help.");
11537                }
11538            }
11539            if (!more) {
11540                Binder.restoreCallingIdentity(origId);
11541                return;
11542            }
11543        }
11544
11545        // No piece of data specified, dump everything.
11546        synchronized (this) {
11547            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11548            pw.println();
11549            if (dumpAll) {
11550                pw.println("-------------------------------------------------------------------------------");
11551            }
11552            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11553            pw.println();
11554            if (dumpAll) {
11555                pw.println("-------------------------------------------------------------------------------");
11556            }
11557            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11558            pw.println();
11559            if (dumpAll) {
11560                pw.println("-------------------------------------------------------------------------------");
11561            }
11562            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11563            pw.println();
11564            if (dumpAll) {
11565                pw.println("-------------------------------------------------------------------------------");
11566            }
11567            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11568            pw.println();
11569            if (dumpAll) {
11570                pw.println("-------------------------------------------------------------------------------");
11571            }
11572            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11573        }
11574        Binder.restoreCallingIdentity(origId);
11575    }
11576
11577    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11578            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11579        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11580
11581        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11582                dumpPackage);
11583        boolean needSep = printedAnything;
11584
11585        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11586                dumpPackage, needSep, "  mFocusedActivity: ");
11587        if (printed) {
11588            printedAnything = true;
11589            needSep = false;
11590        }
11591
11592        if (dumpPackage == null) {
11593            if (needSep) {
11594                pw.println();
11595            }
11596            needSep = true;
11597            printedAnything = true;
11598            mStackSupervisor.dump(pw, "  ");
11599        }
11600
11601        if (mRecentTasks.size() > 0) {
11602            boolean printedHeader = false;
11603
11604            final int N = mRecentTasks.size();
11605            for (int i=0; i<N; i++) {
11606                TaskRecord tr = mRecentTasks.get(i);
11607                if (dumpPackage != null) {
11608                    if (tr.realActivity == null ||
11609                            !dumpPackage.equals(tr.realActivity)) {
11610                        continue;
11611                    }
11612                }
11613                if (!printedHeader) {
11614                    if (needSep) {
11615                        pw.println();
11616                    }
11617                    pw.println("  Recent tasks:");
11618                    printedHeader = true;
11619                    printedAnything = true;
11620                }
11621                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11622                        pw.println(tr);
11623                if (dumpAll) {
11624                    mRecentTasks.get(i).dump(pw, "    ");
11625                }
11626            }
11627        }
11628
11629        if (!printedAnything) {
11630            pw.println("  (nothing)");
11631        }
11632    }
11633
11634    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11635            int opti, boolean dumpAll, String dumpPackage) {
11636        boolean needSep = false;
11637        boolean printedAnything = false;
11638        int numPers = 0;
11639
11640        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11641
11642        if (dumpAll) {
11643            final int NP = mProcessNames.getMap().size();
11644            for (int ip=0; ip<NP; ip++) {
11645                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11646                final int NA = procs.size();
11647                for (int ia=0; ia<NA; ia++) {
11648                    ProcessRecord r = procs.valueAt(ia);
11649                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11650                        continue;
11651                    }
11652                    if (!needSep) {
11653                        pw.println("  All known processes:");
11654                        needSep = true;
11655                        printedAnything = true;
11656                    }
11657                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11658                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11659                        pw.print(" "); pw.println(r);
11660                    r.dump(pw, "    ");
11661                    if (r.persistent) {
11662                        numPers++;
11663                    }
11664                }
11665            }
11666        }
11667
11668        if (mIsolatedProcesses.size() > 0) {
11669            boolean printed = false;
11670            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11671                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11672                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11673                    continue;
11674                }
11675                if (!printed) {
11676                    if (needSep) {
11677                        pw.println();
11678                    }
11679                    pw.println("  Isolated process list (sorted by uid):");
11680                    printedAnything = true;
11681                    printed = true;
11682                    needSep = true;
11683                }
11684                pw.println(String.format("%sIsolated #%2d: %s",
11685                        "    ", i, r.toString()));
11686            }
11687        }
11688
11689        if (mLruProcesses.size() > 0) {
11690            if (needSep) {
11691                pw.println();
11692            }
11693            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11694                    pw.print(" total, non-act at ");
11695                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11696                    pw.print(", non-svc at ");
11697                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11698                    pw.println("):");
11699            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11700            needSep = true;
11701            printedAnything = true;
11702        }
11703
11704        if (dumpAll || dumpPackage != null) {
11705            synchronized (mPidsSelfLocked) {
11706                boolean printed = false;
11707                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11708                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11709                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11710                        continue;
11711                    }
11712                    if (!printed) {
11713                        if (needSep) pw.println();
11714                        needSep = true;
11715                        pw.println("  PID mappings:");
11716                        printed = true;
11717                        printedAnything = true;
11718                    }
11719                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11720                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11721                }
11722            }
11723        }
11724
11725        if (mForegroundProcesses.size() > 0) {
11726            synchronized (mPidsSelfLocked) {
11727                boolean printed = false;
11728                for (int i=0; i<mForegroundProcesses.size(); i++) {
11729                    ProcessRecord r = mPidsSelfLocked.get(
11730                            mForegroundProcesses.valueAt(i).pid);
11731                    if (dumpPackage != null && (r == null
11732                            || !r.pkgList.containsKey(dumpPackage))) {
11733                        continue;
11734                    }
11735                    if (!printed) {
11736                        if (needSep) pw.println();
11737                        needSep = true;
11738                        pw.println("  Foreground Processes:");
11739                        printed = true;
11740                        printedAnything = true;
11741                    }
11742                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11743                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11744                }
11745            }
11746        }
11747
11748        if (mPersistentStartingProcesses.size() > 0) {
11749            if (needSep) pw.println();
11750            needSep = true;
11751            printedAnything = true;
11752            pw.println("  Persisent processes that are starting:");
11753            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11754                    "Starting Norm", "Restarting PERS", dumpPackage);
11755        }
11756
11757        if (mRemovedProcesses.size() > 0) {
11758            if (needSep) pw.println();
11759            needSep = true;
11760            printedAnything = true;
11761            pw.println("  Processes that are being removed:");
11762            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11763                    "Removed Norm", "Removed PERS", dumpPackage);
11764        }
11765
11766        if (mProcessesOnHold.size() > 0) {
11767            if (needSep) pw.println();
11768            needSep = true;
11769            printedAnything = true;
11770            pw.println("  Processes that are on old until the system is ready:");
11771            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11772                    "OnHold Norm", "OnHold PERS", dumpPackage);
11773        }
11774
11775        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11776
11777        if (mProcessCrashTimes.getMap().size() > 0) {
11778            boolean printed = false;
11779            long now = SystemClock.uptimeMillis();
11780            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11781            final int NP = pmap.size();
11782            for (int ip=0; ip<NP; ip++) {
11783                String pname = pmap.keyAt(ip);
11784                SparseArray<Long> uids = pmap.valueAt(ip);
11785                final int N = uids.size();
11786                for (int i=0; i<N; i++) {
11787                    int puid = uids.keyAt(i);
11788                    ProcessRecord r = mProcessNames.get(pname, puid);
11789                    if (dumpPackage != null && (r == null
11790                            || !r.pkgList.containsKey(dumpPackage))) {
11791                        continue;
11792                    }
11793                    if (!printed) {
11794                        if (needSep) pw.println();
11795                        needSep = true;
11796                        pw.println("  Time since processes crashed:");
11797                        printed = true;
11798                        printedAnything = true;
11799                    }
11800                    pw.print("    Process "); pw.print(pname);
11801                            pw.print(" uid "); pw.print(puid);
11802                            pw.print(": last crashed ");
11803                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11804                            pw.println(" ago");
11805                }
11806            }
11807        }
11808
11809        if (mBadProcesses.getMap().size() > 0) {
11810            boolean printed = false;
11811            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11812            final int NP = pmap.size();
11813            for (int ip=0; ip<NP; ip++) {
11814                String pname = pmap.keyAt(ip);
11815                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11816                final int N = uids.size();
11817                for (int i=0; i<N; i++) {
11818                    int puid = uids.keyAt(i);
11819                    ProcessRecord r = mProcessNames.get(pname, puid);
11820                    if (dumpPackage != null && (r == null
11821                            || !r.pkgList.containsKey(dumpPackage))) {
11822                        continue;
11823                    }
11824                    if (!printed) {
11825                        if (needSep) pw.println();
11826                        needSep = true;
11827                        pw.println("  Bad processes:");
11828                        printedAnything = true;
11829                    }
11830                    BadProcessInfo info = uids.valueAt(i);
11831                    pw.print("    Bad process "); pw.print(pname);
11832                            pw.print(" uid "); pw.print(puid);
11833                            pw.print(": crashed at time "); pw.println(info.time);
11834                    if (info.shortMsg != null) {
11835                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11836                    }
11837                    if (info.longMsg != null) {
11838                        pw.print("      Long msg: "); pw.println(info.longMsg);
11839                    }
11840                    if (info.stack != null) {
11841                        pw.println("      Stack:");
11842                        int lastPos = 0;
11843                        for (int pos=0; pos<info.stack.length(); pos++) {
11844                            if (info.stack.charAt(pos) == '\n') {
11845                                pw.print("        ");
11846                                pw.write(info.stack, lastPos, pos-lastPos);
11847                                pw.println();
11848                                lastPos = pos+1;
11849                            }
11850                        }
11851                        if (lastPos < info.stack.length()) {
11852                            pw.print("        ");
11853                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11854                            pw.println();
11855                        }
11856                    }
11857                }
11858            }
11859        }
11860
11861        if (dumpPackage == null) {
11862            pw.println();
11863            needSep = false;
11864            pw.println("  mStartedUsers:");
11865            for (int i=0; i<mStartedUsers.size(); i++) {
11866                UserStartedState uss = mStartedUsers.valueAt(i);
11867                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11868                        pw.print(": "); uss.dump("", pw);
11869            }
11870            pw.print("  mStartedUserArray: [");
11871            for (int i=0; i<mStartedUserArray.length; i++) {
11872                if (i > 0) pw.print(", ");
11873                pw.print(mStartedUserArray[i]);
11874            }
11875            pw.println("]");
11876            pw.print("  mUserLru: [");
11877            for (int i=0; i<mUserLru.size(); i++) {
11878                if (i > 0) pw.print(", ");
11879                pw.print(mUserLru.get(i));
11880            }
11881            pw.println("]");
11882            if (dumpAll) {
11883                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11884            }
11885            synchronized (mUserProfileGroupIdsSelfLocked) {
11886                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11887                    pw.println("  mUserProfileGroupIds:");
11888                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11889                        pw.print("    User #");
11890                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11891                        pw.print(" -> profile #");
11892                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11893                    }
11894                }
11895            }
11896        }
11897        if (mHomeProcess != null && (dumpPackage == null
11898                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11899            if (needSep) {
11900                pw.println();
11901                needSep = false;
11902            }
11903            pw.println("  mHomeProcess: " + mHomeProcess);
11904        }
11905        if (mPreviousProcess != null && (dumpPackage == null
11906                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11907            if (needSep) {
11908                pw.println();
11909                needSep = false;
11910            }
11911            pw.println("  mPreviousProcess: " + mPreviousProcess);
11912        }
11913        if (dumpAll) {
11914            StringBuilder sb = new StringBuilder(128);
11915            sb.append("  mPreviousProcessVisibleTime: ");
11916            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11917            pw.println(sb);
11918        }
11919        if (mHeavyWeightProcess != null && (dumpPackage == null
11920                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11921            if (needSep) {
11922                pw.println();
11923                needSep = false;
11924            }
11925            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11926        }
11927        if (dumpPackage == null) {
11928            pw.println("  mConfiguration: " + mConfiguration);
11929        }
11930        if (dumpAll) {
11931            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11932            if (mCompatModePackages.getPackages().size() > 0) {
11933                boolean printed = false;
11934                for (Map.Entry<String, Integer> entry
11935                        : mCompatModePackages.getPackages().entrySet()) {
11936                    String pkg = entry.getKey();
11937                    int mode = entry.getValue();
11938                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11939                        continue;
11940                    }
11941                    if (!printed) {
11942                        pw.println("  mScreenCompatPackages:");
11943                        printed = true;
11944                    }
11945                    pw.print("    "); pw.print(pkg); pw.print(": ");
11946                            pw.print(mode); pw.println();
11947                }
11948            }
11949        }
11950        if (dumpPackage == null) {
11951            if (mSleeping || mWentToSleep || mLockScreenShown) {
11952                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11953                        + " mLockScreenShown " + mLockScreenShown);
11954            }
11955            if (mShuttingDown || mRunningVoice) {
11956                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11957            }
11958        }
11959        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11960                || mOrigWaitForDebugger) {
11961            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11962                    || dumpPackage.equals(mOrigDebugApp)) {
11963                if (needSep) {
11964                    pw.println();
11965                    needSep = false;
11966                }
11967                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11968                        + " mDebugTransient=" + mDebugTransient
11969                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11970            }
11971        }
11972        if (mOpenGlTraceApp != null) {
11973            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11974                if (needSep) {
11975                    pw.println();
11976                    needSep = false;
11977                }
11978                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11979            }
11980        }
11981        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11982                || mProfileFd != null) {
11983            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11984                if (needSep) {
11985                    pw.println();
11986                    needSep = false;
11987                }
11988                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11989                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11990                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11991                        + mAutoStopProfiler);
11992            }
11993        }
11994        if (dumpPackage == null) {
11995            if (mAlwaysFinishActivities || mController != null) {
11996                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11997                        + " mController=" + mController);
11998            }
11999            if (dumpAll) {
12000                pw.println("  Total persistent processes: " + numPers);
12001                pw.println("  mProcessesReady=" + mProcessesReady
12002                        + " mSystemReady=" + mSystemReady);
12003                pw.println("  mBooting=" + mBooting
12004                        + " mBooted=" + mBooted
12005                        + " mFactoryTest=" + mFactoryTest);
12006                pw.print("  mLastPowerCheckRealtime=");
12007                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12008                        pw.println("");
12009                pw.print("  mLastPowerCheckUptime=");
12010                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12011                        pw.println("");
12012                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12013                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12014                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12015                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12016                        + " (" + mLruProcesses.size() + " total)"
12017                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12018                        + " mNumServiceProcs=" + mNumServiceProcs
12019                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12020                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12021                        + " mLastMemoryLevel" + mLastMemoryLevel
12022                        + " mLastNumProcesses" + mLastNumProcesses);
12023                long now = SystemClock.uptimeMillis();
12024                pw.print("  mLastIdleTime=");
12025                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12026                        pw.print(" mLowRamSinceLastIdle=");
12027                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12028                        pw.println();
12029            }
12030        }
12031
12032        if (!printedAnything) {
12033            pw.println("  (nothing)");
12034        }
12035    }
12036
12037    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12038            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12039        if (mProcessesToGc.size() > 0) {
12040            boolean printed = false;
12041            long now = SystemClock.uptimeMillis();
12042            for (int i=0; i<mProcessesToGc.size(); i++) {
12043                ProcessRecord proc = mProcessesToGc.get(i);
12044                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12045                    continue;
12046                }
12047                if (!printed) {
12048                    if (needSep) pw.println();
12049                    needSep = true;
12050                    pw.println("  Processes that are waiting to GC:");
12051                    printed = true;
12052                }
12053                pw.print("    Process "); pw.println(proc);
12054                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12055                        pw.print(", last gced=");
12056                        pw.print(now-proc.lastRequestedGc);
12057                        pw.print(" ms ago, last lowMem=");
12058                        pw.print(now-proc.lastLowMemory);
12059                        pw.println(" ms ago");
12060
12061            }
12062        }
12063        return needSep;
12064    }
12065
12066    void printOomLevel(PrintWriter pw, String name, int adj) {
12067        pw.print("    ");
12068        if (adj >= 0) {
12069            pw.print(' ');
12070            if (adj < 10) pw.print(' ');
12071        } else {
12072            if (adj > -10) pw.print(' ');
12073        }
12074        pw.print(adj);
12075        pw.print(": ");
12076        pw.print(name);
12077        pw.print(" (");
12078        pw.print(mProcessList.getMemLevel(adj)/1024);
12079        pw.println(" kB)");
12080    }
12081
12082    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12083            int opti, boolean dumpAll) {
12084        boolean needSep = false;
12085
12086        if (mLruProcesses.size() > 0) {
12087            if (needSep) pw.println();
12088            needSep = true;
12089            pw.println("  OOM levels:");
12090            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12091            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12092            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12093            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12094            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12095            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12096            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12097            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12098            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12099            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12100            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12101            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12102            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12103
12104            if (needSep) pw.println();
12105            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12106                    pw.print(" total, non-act at ");
12107                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12108                    pw.print(", non-svc at ");
12109                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12110                    pw.println("):");
12111            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12112            needSep = true;
12113        }
12114
12115        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12116
12117        pw.println();
12118        pw.println("  mHomeProcess: " + mHomeProcess);
12119        pw.println("  mPreviousProcess: " + mPreviousProcess);
12120        if (mHeavyWeightProcess != null) {
12121            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12122        }
12123
12124        return true;
12125    }
12126
12127    /**
12128     * There are three ways to call this:
12129     *  - no provider specified: dump all the providers
12130     *  - a flattened component name that matched an existing provider was specified as the
12131     *    first arg: dump that one provider
12132     *  - the first arg isn't the flattened component name of an existing provider:
12133     *    dump all providers whose component contains the first arg as a substring
12134     */
12135    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12136            int opti, boolean dumpAll) {
12137        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12138    }
12139
12140    static class ItemMatcher {
12141        ArrayList<ComponentName> components;
12142        ArrayList<String> strings;
12143        ArrayList<Integer> objects;
12144        boolean all;
12145
12146        ItemMatcher() {
12147            all = true;
12148        }
12149
12150        void build(String name) {
12151            ComponentName componentName = ComponentName.unflattenFromString(name);
12152            if (componentName != null) {
12153                if (components == null) {
12154                    components = new ArrayList<ComponentName>();
12155                }
12156                components.add(componentName);
12157                all = false;
12158            } else {
12159                int objectId = 0;
12160                // Not a '/' separated full component name; maybe an object ID?
12161                try {
12162                    objectId = Integer.parseInt(name, 16);
12163                    if (objects == null) {
12164                        objects = new ArrayList<Integer>();
12165                    }
12166                    objects.add(objectId);
12167                    all = false;
12168                } catch (RuntimeException e) {
12169                    // Not an integer; just do string match.
12170                    if (strings == null) {
12171                        strings = new ArrayList<String>();
12172                    }
12173                    strings.add(name);
12174                    all = false;
12175                }
12176            }
12177        }
12178
12179        int build(String[] args, int opti) {
12180            for (; opti<args.length; opti++) {
12181                String name = args[opti];
12182                if ("--".equals(name)) {
12183                    return opti+1;
12184                }
12185                build(name);
12186            }
12187            return opti;
12188        }
12189
12190        boolean match(Object object, ComponentName comp) {
12191            if (all) {
12192                return true;
12193            }
12194            if (components != null) {
12195                for (int i=0; i<components.size(); i++) {
12196                    if (components.get(i).equals(comp)) {
12197                        return true;
12198                    }
12199                }
12200            }
12201            if (objects != null) {
12202                for (int i=0; i<objects.size(); i++) {
12203                    if (System.identityHashCode(object) == objects.get(i)) {
12204                        return true;
12205                    }
12206                }
12207            }
12208            if (strings != null) {
12209                String flat = comp.flattenToString();
12210                for (int i=0; i<strings.size(); i++) {
12211                    if (flat.contains(strings.get(i))) {
12212                        return true;
12213                    }
12214                }
12215            }
12216            return false;
12217        }
12218    }
12219
12220    /**
12221     * There are three things that cmd can be:
12222     *  - a flattened component name that matches an existing activity
12223     *  - the cmd arg isn't the flattened component name of an existing activity:
12224     *    dump all activity whose component contains the cmd as a substring
12225     *  - A hex number of the ActivityRecord object instance.
12226     */
12227    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12228            int opti, boolean dumpAll) {
12229        ArrayList<ActivityRecord> activities;
12230
12231        synchronized (this) {
12232            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12233        }
12234
12235        if (activities.size() <= 0) {
12236            return false;
12237        }
12238
12239        String[] newArgs = new String[args.length - opti];
12240        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12241
12242        TaskRecord lastTask = null;
12243        boolean needSep = false;
12244        for (int i=activities.size()-1; i>=0; i--) {
12245            ActivityRecord r = activities.get(i);
12246            if (needSep) {
12247                pw.println();
12248            }
12249            needSep = true;
12250            synchronized (this) {
12251                if (lastTask != r.task) {
12252                    lastTask = r.task;
12253                    pw.print("TASK "); pw.print(lastTask.affinity);
12254                            pw.print(" id="); pw.println(lastTask.taskId);
12255                    if (dumpAll) {
12256                        lastTask.dump(pw, "  ");
12257                    }
12258                }
12259            }
12260            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12261        }
12262        return true;
12263    }
12264
12265    /**
12266     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12267     * there is a thread associated with the activity.
12268     */
12269    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12270            final ActivityRecord r, String[] args, boolean dumpAll) {
12271        String innerPrefix = prefix + "  ";
12272        synchronized (this) {
12273            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12274                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12275                    pw.print(" pid=");
12276                    if (r.app != null) pw.println(r.app.pid);
12277                    else pw.println("(not running)");
12278            if (dumpAll) {
12279                r.dump(pw, innerPrefix);
12280            }
12281        }
12282        if (r.app != null && r.app.thread != null) {
12283            // flush anything that is already in the PrintWriter since the thread is going
12284            // to write to the file descriptor directly
12285            pw.flush();
12286            try {
12287                TransferPipe tp = new TransferPipe();
12288                try {
12289                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12290                            r.appToken, innerPrefix, args);
12291                    tp.go(fd);
12292                } finally {
12293                    tp.kill();
12294                }
12295            } catch (IOException e) {
12296                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12297            } catch (RemoteException e) {
12298                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12299            }
12300        }
12301    }
12302
12303    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12304            int opti, boolean dumpAll, String dumpPackage) {
12305        boolean needSep = false;
12306        boolean onlyHistory = false;
12307        boolean printedAnything = false;
12308
12309        if ("history".equals(dumpPackage)) {
12310            if (opti < args.length && "-s".equals(args[opti])) {
12311                dumpAll = false;
12312            }
12313            onlyHistory = true;
12314            dumpPackage = null;
12315        }
12316
12317        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12318        if (!onlyHistory && dumpAll) {
12319            if (mRegisteredReceivers.size() > 0) {
12320                boolean printed = false;
12321                Iterator it = mRegisteredReceivers.values().iterator();
12322                while (it.hasNext()) {
12323                    ReceiverList r = (ReceiverList)it.next();
12324                    if (dumpPackage != null && (r.app == null ||
12325                            !dumpPackage.equals(r.app.info.packageName))) {
12326                        continue;
12327                    }
12328                    if (!printed) {
12329                        pw.println("  Registered Receivers:");
12330                        needSep = true;
12331                        printed = true;
12332                        printedAnything = true;
12333                    }
12334                    pw.print("  * "); pw.println(r);
12335                    r.dump(pw, "    ");
12336                }
12337            }
12338
12339            if (mReceiverResolver.dump(pw, needSep ?
12340                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12341                    "    ", dumpPackage, false)) {
12342                needSep = true;
12343                printedAnything = true;
12344            }
12345        }
12346
12347        for (BroadcastQueue q : mBroadcastQueues) {
12348            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12349            printedAnything |= needSep;
12350        }
12351
12352        needSep = true;
12353
12354        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12355            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12356                if (needSep) {
12357                    pw.println();
12358                }
12359                needSep = true;
12360                printedAnything = true;
12361                pw.print("  Sticky broadcasts for user ");
12362                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12363                StringBuilder sb = new StringBuilder(128);
12364                for (Map.Entry<String, ArrayList<Intent>> ent
12365                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12366                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12367                    if (dumpAll) {
12368                        pw.println(":");
12369                        ArrayList<Intent> intents = ent.getValue();
12370                        final int N = intents.size();
12371                        for (int i=0; i<N; i++) {
12372                            sb.setLength(0);
12373                            sb.append("    Intent: ");
12374                            intents.get(i).toShortString(sb, false, true, false, false);
12375                            pw.println(sb.toString());
12376                            Bundle bundle = intents.get(i).getExtras();
12377                            if (bundle != null) {
12378                                pw.print("      ");
12379                                pw.println(bundle.toString());
12380                            }
12381                        }
12382                    } else {
12383                        pw.println("");
12384                    }
12385                }
12386            }
12387        }
12388
12389        if (!onlyHistory && dumpAll) {
12390            pw.println();
12391            for (BroadcastQueue queue : mBroadcastQueues) {
12392                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12393                        + queue.mBroadcastsScheduled);
12394            }
12395            pw.println("  mHandler:");
12396            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12397            needSep = true;
12398            printedAnything = true;
12399        }
12400
12401        if (!printedAnything) {
12402            pw.println("  (nothing)");
12403        }
12404    }
12405
12406    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12407            int opti, boolean dumpAll, String dumpPackage) {
12408        boolean needSep;
12409        boolean printedAnything = false;
12410
12411        ItemMatcher matcher = new ItemMatcher();
12412        matcher.build(args, opti);
12413
12414        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12415
12416        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12417        printedAnything |= needSep;
12418
12419        if (mLaunchingProviders.size() > 0) {
12420            boolean printed = false;
12421            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12422                ContentProviderRecord r = mLaunchingProviders.get(i);
12423                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12424                    continue;
12425                }
12426                if (!printed) {
12427                    if (needSep) pw.println();
12428                    needSep = true;
12429                    pw.println("  Launching content providers:");
12430                    printed = true;
12431                    printedAnything = true;
12432                }
12433                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12434                        pw.println(r);
12435            }
12436        }
12437
12438        if (mGrantedUriPermissions.size() > 0) {
12439            boolean printed = false;
12440            int dumpUid = -2;
12441            if (dumpPackage != null) {
12442                try {
12443                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12444                } catch (NameNotFoundException e) {
12445                    dumpUid = -1;
12446                }
12447            }
12448            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12449                int uid = mGrantedUriPermissions.keyAt(i);
12450                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12451                    continue;
12452                }
12453                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12454                if (!printed) {
12455                    if (needSep) pw.println();
12456                    needSep = true;
12457                    pw.println("  Granted Uri Permissions:");
12458                    printed = true;
12459                    printedAnything = true;
12460                }
12461                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12462                for (UriPermission perm : perms.values()) {
12463                    pw.print("    "); pw.println(perm);
12464                    if (dumpAll) {
12465                        perm.dump(pw, "      ");
12466                    }
12467                }
12468            }
12469        }
12470
12471        if (!printedAnything) {
12472            pw.println("  (nothing)");
12473        }
12474    }
12475
12476    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12477            int opti, boolean dumpAll, String dumpPackage) {
12478        boolean printed = false;
12479
12480        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12481
12482        if (mIntentSenderRecords.size() > 0) {
12483            Iterator<WeakReference<PendingIntentRecord>> it
12484                    = mIntentSenderRecords.values().iterator();
12485            while (it.hasNext()) {
12486                WeakReference<PendingIntentRecord> ref = it.next();
12487                PendingIntentRecord rec = ref != null ? ref.get(): null;
12488                if (dumpPackage != null && (rec == null
12489                        || !dumpPackage.equals(rec.key.packageName))) {
12490                    continue;
12491                }
12492                printed = true;
12493                if (rec != null) {
12494                    pw.print("  * "); pw.println(rec);
12495                    if (dumpAll) {
12496                        rec.dump(pw, "    ");
12497                    }
12498                } else {
12499                    pw.print("  * "); pw.println(ref);
12500                }
12501            }
12502        }
12503
12504        if (!printed) {
12505            pw.println("  (nothing)");
12506        }
12507    }
12508
12509    private static final int dumpProcessList(PrintWriter pw,
12510            ActivityManagerService service, List list,
12511            String prefix, String normalLabel, String persistentLabel,
12512            String dumpPackage) {
12513        int numPers = 0;
12514        final int N = list.size()-1;
12515        for (int i=N; i>=0; i--) {
12516            ProcessRecord r = (ProcessRecord)list.get(i);
12517            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12518                continue;
12519            }
12520            pw.println(String.format("%s%s #%2d: %s",
12521                    prefix, (r.persistent ? persistentLabel : normalLabel),
12522                    i, r.toString()));
12523            if (r.persistent) {
12524                numPers++;
12525            }
12526        }
12527        return numPers;
12528    }
12529
12530    private static final boolean dumpProcessOomList(PrintWriter pw,
12531            ActivityManagerService service, List<ProcessRecord> origList,
12532            String prefix, String normalLabel, String persistentLabel,
12533            boolean inclDetails, String dumpPackage) {
12534
12535        ArrayList<Pair<ProcessRecord, Integer>> list
12536                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12537        for (int i=0; i<origList.size(); i++) {
12538            ProcessRecord r = origList.get(i);
12539            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12540                continue;
12541            }
12542            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12543        }
12544
12545        if (list.size() <= 0) {
12546            return false;
12547        }
12548
12549        Comparator<Pair<ProcessRecord, Integer>> comparator
12550                = new Comparator<Pair<ProcessRecord, Integer>>() {
12551            @Override
12552            public int compare(Pair<ProcessRecord, Integer> object1,
12553                    Pair<ProcessRecord, Integer> object2) {
12554                if (object1.first.setAdj != object2.first.setAdj) {
12555                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12556                }
12557                if (object1.second.intValue() != object2.second.intValue()) {
12558                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12559                }
12560                return 0;
12561            }
12562        };
12563
12564        Collections.sort(list, comparator);
12565
12566        final long curRealtime = SystemClock.elapsedRealtime();
12567        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12568        final long curUptime = SystemClock.uptimeMillis();
12569        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12570
12571        for (int i=list.size()-1; i>=0; i--) {
12572            ProcessRecord r = list.get(i).first;
12573            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12574            char schedGroup;
12575            switch (r.setSchedGroup) {
12576                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12577                    schedGroup = 'B';
12578                    break;
12579                case Process.THREAD_GROUP_DEFAULT:
12580                    schedGroup = 'F';
12581                    break;
12582                default:
12583                    schedGroup = '?';
12584                    break;
12585            }
12586            char foreground;
12587            if (r.foregroundActivities) {
12588                foreground = 'A';
12589            } else if (r.foregroundServices) {
12590                foreground = 'S';
12591            } else {
12592                foreground = ' ';
12593            }
12594            String procState = ProcessList.makeProcStateString(r.curProcState);
12595            pw.print(prefix);
12596            pw.print(r.persistent ? persistentLabel : normalLabel);
12597            pw.print(" #");
12598            int num = (origList.size()-1)-list.get(i).second;
12599            if (num < 10) pw.print(' ');
12600            pw.print(num);
12601            pw.print(": ");
12602            pw.print(oomAdj);
12603            pw.print(' ');
12604            pw.print(schedGroup);
12605            pw.print('/');
12606            pw.print(foreground);
12607            pw.print('/');
12608            pw.print(procState);
12609            pw.print(" trm:");
12610            if (r.trimMemoryLevel < 10) pw.print(' ');
12611            pw.print(r.trimMemoryLevel);
12612            pw.print(' ');
12613            pw.print(r.toShortString());
12614            pw.print(" (");
12615            pw.print(r.adjType);
12616            pw.println(')');
12617            if (r.adjSource != null || r.adjTarget != null) {
12618                pw.print(prefix);
12619                pw.print("    ");
12620                if (r.adjTarget instanceof ComponentName) {
12621                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12622                } else if (r.adjTarget != null) {
12623                    pw.print(r.adjTarget.toString());
12624                } else {
12625                    pw.print("{null}");
12626                }
12627                pw.print("<=");
12628                if (r.adjSource instanceof ProcessRecord) {
12629                    pw.print("Proc{");
12630                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12631                    pw.println("}");
12632                } else if (r.adjSource != null) {
12633                    pw.println(r.adjSource.toString());
12634                } else {
12635                    pw.println("{null}");
12636                }
12637            }
12638            if (inclDetails) {
12639                pw.print(prefix);
12640                pw.print("    ");
12641                pw.print("oom: max="); pw.print(r.maxAdj);
12642                pw.print(" curRaw="); pw.print(r.curRawAdj);
12643                pw.print(" setRaw="); pw.print(r.setRawAdj);
12644                pw.print(" cur="); pw.print(r.curAdj);
12645                pw.print(" set="); pw.println(r.setAdj);
12646                pw.print(prefix);
12647                pw.print("    ");
12648                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12649                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12650                pw.print(" lastPss="); pw.print(r.lastPss);
12651                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12652                pw.print(prefix);
12653                pw.print("    ");
12654                pw.print("cached="); pw.print(r.cached);
12655                pw.print(" empty="); pw.print(r.empty);
12656                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12657
12658                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12659                    if (r.lastWakeTime != 0) {
12660                        long wtime;
12661                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12662                        synchronized (stats) {
12663                            wtime = stats.getProcessWakeTime(r.info.uid,
12664                                    r.pid, curRealtime);
12665                        }
12666                        long timeUsed = wtime - r.lastWakeTime;
12667                        pw.print(prefix);
12668                        pw.print("    ");
12669                        pw.print("keep awake over ");
12670                        TimeUtils.formatDuration(realtimeSince, pw);
12671                        pw.print(" used ");
12672                        TimeUtils.formatDuration(timeUsed, pw);
12673                        pw.print(" (");
12674                        pw.print((timeUsed*100)/realtimeSince);
12675                        pw.println("%)");
12676                    }
12677                    if (r.lastCpuTime != 0) {
12678                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12679                        pw.print(prefix);
12680                        pw.print("    ");
12681                        pw.print("run cpu over ");
12682                        TimeUtils.formatDuration(uptimeSince, pw);
12683                        pw.print(" used ");
12684                        TimeUtils.formatDuration(timeUsed, pw);
12685                        pw.print(" (");
12686                        pw.print((timeUsed*100)/uptimeSince);
12687                        pw.println("%)");
12688                    }
12689                }
12690            }
12691        }
12692        return true;
12693    }
12694
12695    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12696        ArrayList<ProcessRecord> procs;
12697        synchronized (this) {
12698            if (args != null && args.length > start
12699                    && args[start].charAt(0) != '-') {
12700                procs = new ArrayList<ProcessRecord>();
12701                int pid = -1;
12702                try {
12703                    pid = Integer.parseInt(args[start]);
12704                } catch (NumberFormatException e) {
12705                }
12706                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12707                    ProcessRecord proc = mLruProcesses.get(i);
12708                    if (proc.pid == pid) {
12709                        procs.add(proc);
12710                    } else if (proc.processName.equals(args[start])) {
12711                        procs.add(proc);
12712                    }
12713                }
12714                if (procs.size() <= 0) {
12715                    return null;
12716                }
12717            } else {
12718                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12719            }
12720        }
12721        return procs;
12722    }
12723
12724    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12725            PrintWriter pw, String[] args) {
12726        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12727        if (procs == null) {
12728            pw.println("No process found for: " + args[0]);
12729            return;
12730        }
12731
12732        long uptime = SystemClock.uptimeMillis();
12733        long realtime = SystemClock.elapsedRealtime();
12734        pw.println("Applications Graphics Acceleration Info:");
12735        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12736
12737        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12738            ProcessRecord r = procs.get(i);
12739            if (r.thread != null) {
12740                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12741                pw.flush();
12742                try {
12743                    TransferPipe tp = new TransferPipe();
12744                    try {
12745                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12746                        tp.go(fd);
12747                    } finally {
12748                        tp.kill();
12749                    }
12750                } catch (IOException e) {
12751                    pw.println("Failure while dumping the app: " + r);
12752                    pw.flush();
12753                } catch (RemoteException e) {
12754                    pw.println("Got a RemoteException while dumping the app " + r);
12755                    pw.flush();
12756                }
12757            }
12758        }
12759    }
12760
12761    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12762        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12763        if (procs == null) {
12764            pw.println("No process found for: " + args[0]);
12765            return;
12766        }
12767
12768        pw.println("Applications Database Info:");
12769
12770        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12771            ProcessRecord r = procs.get(i);
12772            if (r.thread != null) {
12773                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12774                pw.flush();
12775                try {
12776                    TransferPipe tp = new TransferPipe();
12777                    try {
12778                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12779                        tp.go(fd);
12780                    } finally {
12781                        tp.kill();
12782                    }
12783                } catch (IOException e) {
12784                    pw.println("Failure while dumping the app: " + r);
12785                    pw.flush();
12786                } catch (RemoteException e) {
12787                    pw.println("Got a RemoteException while dumping the app " + r);
12788                    pw.flush();
12789                }
12790            }
12791        }
12792    }
12793
12794    final static class MemItem {
12795        final boolean isProc;
12796        final String label;
12797        final String shortLabel;
12798        final long pss;
12799        final int id;
12800        final boolean hasActivities;
12801        ArrayList<MemItem> subitems;
12802
12803        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12804                boolean _hasActivities) {
12805            isProc = true;
12806            label = _label;
12807            shortLabel = _shortLabel;
12808            pss = _pss;
12809            id = _id;
12810            hasActivities = _hasActivities;
12811        }
12812
12813        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12814            isProc = false;
12815            label = _label;
12816            shortLabel = _shortLabel;
12817            pss = _pss;
12818            id = _id;
12819            hasActivities = false;
12820        }
12821    }
12822
12823    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12824            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12825        if (sort && !isCompact) {
12826            Collections.sort(items, new Comparator<MemItem>() {
12827                @Override
12828                public int compare(MemItem lhs, MemItem rhs) {
12829                    if (lhs.pss < rhs.pss) {
12830                        return 1;
12831                    } else if (lhs.pss > rhs.pss) {
12832                        return -1;
12833                    }
12834                    return 0;
12835                }
12836            });
12837        }
12838
12839        for (int i=0; i<items.size(); i++) {
12840            MemItem mi = items.get(i);
12841            if (!isCompact) {
12842                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12843            } else if (mi.isProc) {
12844                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12845                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12846                pw.println(mi.hasActivities ? ",a" : ",e");
12847            } else {
12848                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12849                pw.println(mi.pss);
12850            }
12851            if (mi.subitems != null) {
12852                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12853                        true, isCompact);
12854            }
12855        }
12856    }
12857
12858    // These are in KB.
12859    static final long[] DUMP_MEM_BUCKETS = new long[] {
12860        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12861        120*1024, 160*1024, 200*1024,
12862        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12863        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12864    };
12865
12866    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12867            boolean stackLike) {
12868        int start = label.lastIndexOf('.');
12869        if (start >= 0) start++;
12870        else start = 0;
12871        int end = label.length();
12872        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12873            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12874                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12875                out.append(bucket);
12876                out.append(stackLike ? "MB." : "MB ");
12877                out.append(label, start, end);
12878                return;
12879            }
12880        }
12881        out.append(memKB/1024);
12882        out.append(stackLike ? "MB." : "MB ");
12883        out.append(label, start, end);
12884    }
12885
12886    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12887            ProcessList.NATIVE_ADJ,
12888            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12889            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12890            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12891            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12892            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12893    };
12894    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12895            "Native",
12896            "System", "Persistent", "Foreground",
12897            "Visible", "Perceptible",
12898            "Heavy Weight", "Backup",
12899            "A Services", "Home",
12900            "Previous", "B Services", "Cached"
12901    };
12902    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12903            "native",
12904            "sys", "pers", "fore",
12905            "vis", "percept",
12906            "heavy", "backup",
12907            "servicea", "home",
12908            "prev", "serviceb", "cached"
12909    };
12910
12911    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12912            long realtime, boolean isCheckinRequest, boolean isCompact) {
12913        if (isCheckinRequest || isCompact) {
12914            // short checkin version
12915            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12916        } else {
12917            pw.println("Applications Memory Usage (kB):");
12918            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12919        }
12920    }
12921
12922    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12923            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12924        boolean dumpDetails = false;
12925        boolean dumpFullDetails = false;
12926        boolean dumpDalvik = false;
12927        boolean oomOnly = false;
12928        boolean isCompact = false;
12929        boolean localOnly = false;
12930
12931        int opti = 0;
12932        while (opti < args.length) {
12933            String opt = args[opti];
12934            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12935                break;
12936            }
12937            opti++;
12938            if ("-a".equals(opt)) {
12939                dumpDetails = true;
12940                dumpFullDetails = true;
12941                dumpDalvik = true;
12942            } else if ("-d".equals(opt)) {
12943                dumpDalvik = true;
12944            } else if ("-c".equals(opt)) {
12945                isCompact = true;
12946            } else if ("--oom".equals(opt)) {
12947                oomOnly = true;
12948            } else if ("--local".equals(opt)) {
12949                localOnly = true;
12950            } else if ("-h".equals(opt)) {
12951                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12952                pw.println("  -a: include all available information for each process.");
12953                pw.println("  -d: include dalvik details when dumping process details.");
12954                pw.println("  -c: dump in a compact machine-parseable representation.");
12955                pw.println("  --oom: only show processes organized by oom adj.");
12956                pw.println("  --local: only collect details locally, don't call process.");
12957                pw.println("If [process] is specified it can be the name or ");
12958                pw.println("pid of a specific process to dump.");
12959                return;
12960            } else {
12961                pw.println("Unknown argument: " + opt + "; use -h for help");
12962            }
12963        }
12964
12965        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12966        long uptime = SystemClock.uptimeMillis();
12967        long realtime = SystemClock.elapsedRealtime();
12968        final long[] tmpLong = new long[1];
12969
12970        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12971        if (procs == null) {
12972            // No Java processes.  Maybe they want to print a native process.
12973            if (args != null && args.length > opti
12974                    && args[opti].charAt(0) != '-') {
12975                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12976                        = new ArrayList<ProcessCpuTracker.Stats>();
12977                updateCpuStatsNow();
12978                int findPid = -1;
12979                try {
12980                    findPid = Integer.parseInt(args[opti]);
12981                } catch (NumberFormatException e) {
12982                }
12983                synchronized (mProcessCpuThread) {
12984                    final int N = mProcessCpuTracker.countStats();
12985                    for (int i=0; i<N; i++) {
12986                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12987                        if (st.pid == findPid || (st.baseName != null
12988                                && st.baseName.equals(args[opti]))) {
12989                            nativeProcs.add(st);
12990                        }
12991                    }
12992                }
12993                if (nativeProcs.size() > 0) {
12994                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12995                            isCompact);
12996                    Debug.MemoryInfo mi = null;
12997                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12998                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12999                        final int pid = r.pid;
13000                        if (!isCheckinRequest && dumpDetails) {
13001                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13002                        }
13003                        if (mi == null) {
13004                            mi = new Debug.MemoryInfo();
13005                        }
13006                        if (dumpDetails || (!brief && !oomOnly)) {
13007                            Debug.getMemoryInfo(pid, mi);
13008                        } else {
13009                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13010                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13011                        }
13012                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13013                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13014                        if (isCheckinRequest) {
13015                            pw.println();
13016                        }
13017                    }
13018                    return;
13019                }
13020            }
13021            pw.println("No process found for: " + args[opti]);
13022            return;
13023        }
13024
13025        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13026            dumpDetails = true;
13027        }
13028
13029        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13030
13031        String[] innerArgs = new String[args.length-opti];
13032        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13033
13034        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13035        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13036        long nativePss=0, dalvikPss=0, otherPss=0;
13037        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13038
13039        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13040        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13041                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13042
13043        long totalPss = 0;
13044        long cachedPss = 0;
13045
13046        Debug.MemoryInfo mi = null;
13047        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13048            final ProcessRecord r = procs.get(i);
13049            final IApplicationThread thread;
13050            final int pid;
13051            final int oomAdj;
13052            final boolean hasActivities;
13053            synchronized (this) {
13054                thread = r.thread;
13055                pid = r.pid;
13056                oomAdj = r.getSetAdjWithServices();
13057                hasActivities = r.activities.size() > 0;
13058            }
13059            if (thread != null) {
13060                if (!isCheckinRequest && dumpDetails) {
13061                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13062                }
13063                if (mi == null) {
13064                    mi = new Debug.MemoryInfo();
13065                }
13066                if (dumpDetails || (!brief && !oomOnly)) {
13067                    Debug.getMemoryInfo(pid, mi);
13068                } else {
13069                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13070                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13071                }
13072                if (dumpDetails) {
13073                    if (localOnly) {
13074                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13075                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13076                        if (isCheckinRequest) {
13077                            pw.println();
13078                        }
13079                    } else {
13080                        try {
13081                            pw.flush();
13082                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13083                                    dumpDalvik, innerArgs);
13084                        } catch (RemoteException e) {
13085                            if (!isCheckinRequest) {
13086                                pw.println("Got RemoteException!");
13087                                pw.flush();
13088                            }
13089                        }
13090                    }
13091                }
13092
13093                final long myTotalPss = mi.getTotalPss();
13094                final long myTotalUss = mi.getTotalUss();
13095
13096                synchronized (this) {
13097                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13098                        // Record this for posterity if the process has been stable.
13099                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13100                    }
13101                }
13102
13103                if (!isCheckinRequest && mi != null) {
13104                    totalPss += myTotalPss;
13105                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13106                            (hasActivities ? " / activities)" : ")"),
13107                            r.processName, myTotalPss, pid, hasActivities);
13108                    procMems.add(pssItem);
13109                    procMemsMap.put(pid, pssItem);
13110
13111                    nativePss += mi.nativePss;
13112                    dalvikPss += mi.dalvikPss;
13113                    otherPss += mi.otherPss;
13114                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13115                        long mem = mi.getOtherPss(j);
13116                        miscPss[j] += mem;
13117                        otherPss -= mem;
13118                    }
13119
13120                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13121                        cachedPss += myTotalPss;
13122                    }
13123
13124                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13125                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13126                                || oomIndex == (oomPss.length-1)) {
13127                            oomPss[oomIndex] += myTotalPss;
13128                            if (oomProcs[oomIndex] == null) {
13129                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13130                            }
13131                            oomProcs[oomIndex].add(pssItem);
13132                            break;
13133                        }
13134                    }
13135                }
13136            }
13137        }
13138
13139        long nativeProcTotalPss = 0;
13140
13141        if (!isCheckinRequest && procs.size() > 1) {
13142            // If we are showing aggregations, also look for native processes to
13143            // include so that our aggregations are more accurate.
13144            updateCpuStatsNow();
13145            synchronized (mProcessCpuThread) {
13146                final int N = mProcessCpuTracker.countStats();
13147                for (int i=0; i<N; i++) {
13148                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13149                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13150                        if (mi == null) {
13151                            mi = new Debug.MemoryInfo();
13152                        }
13153                        if (!brief && !oomOnly) {
13154                            Debug.getMemoryInfo(st.pid, mi);
13155                        } else {
13156                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13157                            mi.nativePrivateDirty = (int)tmpLong[0];
13158                        }
13159
13160                        final long myTotalPss = mi.getTotalPss();
13161                        totalPss += myTotalPss;
13162                        nativeProcTotalPss += myTotalPss;
13163
13164                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13165                                st.name, myTotalPss, st.pid, false);
13166                        procMems.add(pssItem);
13167
13168                        nativePss += mi.nativePss;
13169                        dalvikPss += mi.dalvikPss;
13170                        otherPss += mi.otherPss;
13171                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13172                            long mem = mi.getOtherPss(j);
13173                            miscPss[j] += mem;
13174                            otherPss -= mem;
13175                        }
13176                        oomPss[0] += myTotalPss;
13177                        if (oomProcs[0] == null) {
13178                            oomProcs[0] = new ArrayList<MemItem>();
13179                        }
13180                        oomProcs[0].add(pssItem);
13181                    }
13182                }
13183            }
13184
13185            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13186
13187            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13188            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13189            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13190            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13191                String label = Debug.MemoryInfo.getOtherLabel(j);
13192                catMems.add(new MemItem(label, label, miscPss[j], j));
13193            }
13194
13195            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13196            for (int j=0; j<oomPss.length; j++) {
13197                if (oomPss[j] != 0) {
13198                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13199                            : DUMP_MEM_OOM_LABEL[j];
13200                    MemItem item = new MemItem(label, label, oomPss[j],
13201                            DUMP_MEM_OOM_ADJ[j]);
13202                    item.subitems = oomProcs[j];
13203                    oomMems.add(item);
13204                }
13205            }
13206
13207            if (!brief && !oomOnly && !isCompact) {
13208                pw.println();
13209                pw.println("Total PSS by process:");
13210                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13211                pw.println();
13212            }
13213            if (!isCompact) {
13214                pw.println("Total PSS by OOM adjustment:");
13215            }
13216            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13217            if (!brief && !oomOnly) {
13218                PrintWriter out = categoryPw != null ? categoryPw : pw;
13219                if (!isCompact) {
13220                    out.println();
13221                    out.println("Total PSS by category:");
13222                }
13223                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13224            }
13225            if (!isCompact) {
13226                pw.println();
13227            }
13228            MemInfoReader memInfo = new MemInfoReader();
13229            memInfo.readMemInfo();
13230            if (nativeProcTotalPss > 0) {
13231                synchronized (this) {
13232                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13233                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13234                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13235                            nativeProcTotalPss);
13236                }
13237            }
13238            if (!brief) {
13239                if (!isCompact) {
13240                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13241                    pw.print(" kB (status ");
13242                    switch (mLastMemoryLevel) {
13243                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13244                            pw.println("normal)");
13245                            break;
13246                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13247                            pw.println("moderate)");
13248                            break;
13249                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13250                            pw.println("low)");
13251                            break;
13252                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13253                            pw.println("critical)");
13254                            break;
13255                        default:
13256                            pw.print(mLastMemoryLevel);
13257                            pw.println(")");
13258                            break;
13259                    }
13260                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13261                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13262                            pw.print(cachedPss); pw.print(" cached pss + ");
13263                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13264                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13265                } else {
13266                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13267                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13268                            + memInfo.getFreeSizeKb()); pw.print(",");
13269                    pw.println(totalPss - cachedPss);
13270                }
13271            }
13272            if (!isCompact) {
13273                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13274                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13275                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13276                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13277                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13278                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13279                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13280                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13281                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13282                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13283                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13284            }
13285            if (!brief) {
13286                if (memInfo.getZramTotalSizeKb() != 0) {
13287                    if (!isCompact) {
13288                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13289                                pw.print(" kB physical used for ");
13290                                pw.print(memInfo.getSwapTotalSizeKb()
13291                                        - memInfo.getSwapFreeSizeKb());
13292                                pw.print(" kB in swap (");
13293                                pw.print(memInfo.getSwapTotalSizeKb());
13294                                pw.println(" kB total swap)");
13295                    } else {
13296                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13297                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13298                                pw.println(memInfo.getSwapFreeSizeKb());
13299                    }
13300                }
13301                final int[] SINGLE_LONG_FORMAT = new int[] {
13302                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13303                };
13304                long[] longOut = new long[1];
13305                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13306                        SINGLE_LONG_FORMAT, null, longOut, null);
13307                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13308                longOut[0] = 0;
13309                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13310                        SINGLE_LONG_FORMAT, null, longOut, null);
13311                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13312                longOut[0] = 0;
13313                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13314                        SINGLE_LONG_FORMAT, null, longOut, null);
13315                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13316                longOut[0] = 0;
13317                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13318                        SINGLE_LONG_FORMAT, null, longOut, null);
13319                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13320                if (!isCompact) {
13321                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13322                        pw.print("      KSM: "); pw.print(sharing);
13323                                pw.print(" kB saved from shared ");
13324                                pw.print(shared); pw.println(" kB");
13325                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13326                                pw.print(voltile); pw.println(" kB volatile");
13327                    }
13328                    pw.print("   Tuning: ");
13329                    pw.print(ActivityManager.staticGetMemoryClass());
13330                    pw.print(" (large ");
13331                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13332                    pw.print("), oom ");
13333                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13334                    pw.print(" kB");
13335                    pw.print(", restore limit ");
13336                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13337                    pw.print(" kB");
13338                    if (ActivityManager.isLowRamDeviceStatic()) {
13339                        pw.print(" (low-ram)");
13340                    }
13341                    if (ActivityManager.isHighEndGfx()) {
13342                        pw.print(" (high-end-gfx)");
13343                    }
13344                    pw.println();
13345                } else {
13346                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13347                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13348                    pw.println(voltile);
13349                    pw.print("tuning,");
13350                    pw.print(ActivityManager.staticGetMemoryClass());
13351                    pw.print(',');
13352                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13353                    pw.print(',');
13354                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13355                    if (ActivityManager.isLowRamDeviceStatic()) {
13356                        pw.print(",low-ram");
13357                    }
13358                    if (ActivityManager.isHighEndGfx()) {
13359                        pw.print(",high-end-gfx");
13360                    }
13361                    pw.println();
13362                }
13363            }
13364        }
13365    }
13366
13367    /**
13368     * Searches array of arguments for the specified string
13369     * @param args array of argument strings
13370     * @param value value to search for
13371     * @return true if the value is contained in the array
13372     */
13373    private static boolean scanArgs(String[] args, String value) {
13374        if (args != null) {
13375            for (String arg : args) {
13376                if (value.equals(arg)) {
13377                    return true;
13378                }
13379            }
13380        }
13381        return false;
13382    }
13383
13384    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13385            ContentProviderRecord cpr, boolean always) {
13386        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13387
13388        if (!inLaunching || always) {
13389            synchronized (cpr) {
13390                cpr.launchingApp = null;
13391                cpr.notifyAll();
13392            }
13393            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13394            String names[] = cpr.info.authority.split(";");
13395            for (int j = 0; j < names.length; j++) {
13396                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13397            }
13398        }
13399
13400        for (int i=0; i<cpr.connections.size(); i++) {
13401            ContentProviderConnection conn = cpr.connections.get(i);
13402            if (conn.waiting) {
13403                // If this connection is waiting for the provider, then we don't
13404                // need to mess with its process unless we are always removing
13405                // or for some reason the provider is not currently launching.
13406                if (inLaunching && !always) {
13407                    continue;
13408                }
13409            }
13410            ProcessRecord capp = conn.client;
13411            conn.dead = true;
13412            if (conn.stableCount > 0) {
13413                if (!capp.persistent && capp.thread != null
13414                        && capp.pid != 0
13415                        && capp.pid != MY_PID) {
13416                    killUnneededProcessLocked(capp, "depends on provider "
13417                            + cpr.name.flattenToShortString()
13418                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13419                }
13420            } else if (capp.thread != null && conn.provider.provider != null) {
13421                try {
13422                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13423                } catch (RemoteException e) {
13424                }
13425                // In the protocol here, we don't expect the client to correctly
13426                // clean up this connection, we'll just remove it.
13427                cpr.connections.remove(i);
13428                conn.client.conProviders.remove(conn);
13429            }
13430        }
13431
13432        if (inLaunching && always) {
13433            mLaunchingProviders.remove(cpr);
13434        }
13435        return inLaunching;
13436    }
13437
13438    /**
13439     * Main code for cleaning up a process when it has gone away.  This is
13440     * called both as a result of the process dying, or directly when stopping
13441     * a process when running in single process mode.
13442     */
13443    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13444            boolean restarting, boolean allowRestart, int index) {
13445        if (index >= 0) {
13446            removeLruProcessLocked(app);
13447            ProcessList.remove(app.pid);
13448        }
13449
13450        mProcessesToGc.remove(app);
13451        mPendingPssProcesses.remove(app);
13452
13453        // Dismiss any open dialogs.
13454        if (app.crashDialog != null && !app.forceCrashReport) {
13455            app.crashDialog.dismiss();
13456            app.crashDialog = null;
13457        }
13458        if (app.anrDialog != null) {
13459            app.anrDialog.dismiss();
13460            app.anrDialog = null;
13461        }
13462        if (app.waitDialog != null) {
13463            app.waitDialog.dismiss();
13464            app.waitDialog = null;
13465        }
13466
13467        app.crashing = false;
13468        app.notResponding = false;
13469
13470        app.resetPackageList(mProcessStats);
13471        app.unlinkDeathRecipient();
13472        app.makeInactive(mProcessStats);
13473        app.waitingToKill = null;
13474        app.forcingToForeground = null;
13475        updateProcessForegroundLocked(app, false, false);
13476        app.foregroundActivities = false;
13477        app.hasShownUi = false;
13478        app.treatLikeActivity = false;
13479        app.hasAboveClient = false;
13480        app.hasClientActivities = false;
13481
13482        mServices.killServicesLocked(app, allowRestart);
13483
13484        boolean restart = false;
13485
13486        // Remove published content providers.
13487        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13488            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13489            final boolean always = app.bad || !allowRestart;
13490            if (removeDyingProviderLocked(app, cpr, always) || always) {
13491                // We left the provider in the launching list, need to
13492                // restart it.
13493                restart = true;
13494            }
13495
13496            cpr.provider = null;
13497            cpr.proc = null;
13498        }
13499        app.pubProviders.clear();
13500
13501        // Take care of any launching providers waiting for this process.
13502        if (checkAppInLaunchingProvidersLocked(app, false)) {
13503            restart = true;
13504        }
13505
13506        // Unregister from connected content providers.
13507        if (!app.conProviders.isEmpty()) {
13508            for (int i=0; i<app.conProviders.size(); i++) {
13509                ContentProviderConnection conn = app.conProviders.get(i);
13510                conn.provider.connections.remove(conn);
13511            }
13512            app.conProviders.clear();
13513        }
13514
13515        // At this point there may be remaining entries in mLaunchingProviders
13516        // where we were the only one waiting, so they are no longer of use.
13517        // Look for these and clean up if found.
13518        // XXX Commented out for now.  Trying to figure out a way to reproduce
13519        // the actual situation to identify what is actually going on.
13520        if (false) {
13521            for (int i=0; i<mLaunchingProviders.size(); i++) {
13522                ContentProviderRecord cpr = (ContentProviderRecord)
13523                        mLaunchingProviders.get(i);
13524                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13525                    synchronized (cpr) {
13526                        cpr.launchingApp = null;
13527                        cpr.notifyAll();
13528                    }
13529                }
13530            }
13531        }
13532
13533        skipCurrentReceiverLocked(app);
13534
13535        // Unregister any receivers.
13536        for (int i=app.receivers.size()-1; i>=0; i--) {
13537            removeReceiverLocked(app.receivers.valueAt(i));
13538        }
13539        app.receivers.clear();
13540
13541        // If the app is undergoing backup, tell the backup manager about it
13542        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13543            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13544                    + mBackupTarget.appInfo + " died during backup");
13545            try {
13546                IBackupManager bm = IBackupManager.Stub.asInterface(
13547                        ServiceManager.getService(Context.BACKUP_SERVICE));
13548                bm.agentDisconnected(app.info.packageName);
13549            } catch (RemoteException e) {
13550                // can't happen; backup manager is local
13551            }
13552        }
13553
13554        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13555            ProcessChangeItem item = mPendingProcessChanges.get(i);
13556            if (item.pid == app.pid) {
13557                mPendingProcessChanges.remove(i);
13558                mAvailProcessChanges.add(item);
13559            }
13560        }
13561        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13562
13563        // If the caller is restarting this app, then leave it in its
13564        // current lists and let the caller take care of it.
13565        if (restarting) {
13566            return;
13567        }
13568
13569        if (!app.persistent || app.isolated) {
13570            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13571                    "Removing non-persistent process during cleanup: " + app);
13572            mProcessNames.remove(app.processName, app.uid);
13573            mIsolatedProcesses.remove(app.uid);
13574            if (mHeavyWeightProcess == app) {
13575                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13576                        mHeavyWeightProcess.userId, 0));
13577                mHeavyWeightProcess = null;
13578            }
13579        } else if (!app.removed) {
13580            // This app is persistent, so we need to keep its record around.
13581            // If it is not already on the pending app list, add it there
13582            // and start a new process for it.
13583            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13584                mPersistentStartingProcesses.add(app);
13585                restart = true;
13586            }
13587        }
13588        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13589                "Clean-up removing on hold: " + app);
13590        mProcessesOnHold.remove(app);
13591
13592        if (app == mHomeProcess) {
13593            mHomeProcess = null;
13594        }
13595        if (app == mPreviousProcess) {
13596            mPreviousProcess = null;
13597        }
13598
13599        if (restart && !app.isolated) {
13600            // We have components that still need to be running in the
13601            // process, so re-launch it.
13602            mProcessNames.put(app.processName, app.uid, app);
13603            startProcessLocked(app, "restart", app.processName);
13604        } else if (app.pid > 0 && app.pid != MY_PID) {
13605            // Goodbye!
13606            boolean removed;
13607            synchronized (mPidsSelfLocked) {
13608                mPidsSelfLocked.remove(app.pid);
13609                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13610            }
13611            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13612            if (app.isolated) {
13613                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13614            }
13615            app.setPid(0);
13616        }
13617    }
13618
13619    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13620        // Look through the content providers we are waiting to have launched,
13621        // and if any run in this process then either schedule a restart of
13622        // the process or kill the client waiting for it if this process has
13623        // gone bad.
13624        int NL = mLaunchingProviders.size();
13625        boolean restart = false;
13626        for (int i=0; i<NL; i++) {
13627            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13628            if (cpr.launchingApp == app) {
13629                if (!alwaysBad && !app.bad) {
13630                    restart = true;
13631                } else {
13632                    removeDyingProviderLocked(app, cpr, true);
13633                    // cpr should have been removed from mLaunchingProviders
13634                    NL = mLaunchingProviders.size();
13635                    i--;
13636                }
13637            }
13638        }
13639        return restart;
13640    }
13641
13642    // =========================================================
13643    // SERVICES
13644    // =========================================================
13645
13646    @Override
13647    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13648            int flags) {
13649        enforceNotIsolatedCaller("getServices");
13650        synchronized (this) {
13651            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13652        }
13653    }
13654
13655    @Override
13656    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13657        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13658        synchronized (this) {
13659            return mServices.getRunningServiceControlPanelLocked(name);
13660        }
13661    }
13662
13663    @Override
13664    public ComponentName startService(IApplicationThread caller, Intent service,
13665            String resolvedType, int userId) {
13666        enforceNotIsolatedCaller("startService");
13667        // Refuse possible leaked file descriptors
13668        if (service != null && service.hasFileDescriptors() == true) {
13669            throw new IllegalArgumentException("File descriptors passed in Intent");
13670        }
13671
13672        if (DEBUG_SERVICE)
13673            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13674        synchronized(this) {
13675            final int callingPid = Binder.getCallingPid();
13676            final int callingUid = Binder.getCallingUid();
13677            final long origId = Binder.clearCallingIdentity();
13678            ComponentName res = mServices.startServiceLocked(caller, service,
13679                    resolvedType, callingPid, callingUid, userId);
13680            Binder.restoreCallingIdentity(origId);
13681            return res;
13682        }
13683    }
13684
13685    ComponentName startServiceInPackage(int uid,
13686            Intent service, String resolvedType, int userId) {
13687        synchronized(this) {
13688            if (DEBUG_SERVICE)
13689                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13690            final long origId = Binder.clearCallingIdentity();
13691            ComponentName res = mServices.startServiceLocked(null, service,
13692                    resolvedType, -1, uid, userId);
13693            Binder.restoreCallingIdentity(origId);
13694            return res;
13695        }
13696    }
13697
13698    @Override
13699    public int stopService(IApplicationThread caller, Intent service,
13700            String resolvedType, int userId) {
13701        enforceNotIsolatedCaller("stopService");
13702        // Refuse possible leaked file descriptors
13703        if (service != null && service.hasFileDescriptors() == true) {
13704            throw new IllegalArgumentException("File descriptors passed in Intent");
13705        }
13706
13707        synchronized(this) {
13708            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13709        }
13710    }
13711
13712    @Override
13713    public IBinder peekService(Intent service, String resolvedType) {
13714        enforceNotIsolatedCaller("peekService");
13715        // Refuse possible leaked file descriptors
13716        if (service != null && service.hasFileDescriptors() == true) {
13717            throw new IllegalArgumentException("File descriptors passed in Intent");
13718        }
13719        synchronized(this) {
13720            return mServices.peekServiceLocked(service, resolvedType);
13721        }
13722    }
13723
13724    @Override
13725    public boolean stopServiceToken(ComponentName className, IBinder token,
13726            int startId) {
13727        synchronized(this) {
13728            return mServices.stopServiceTokenLocked(className, token, startId);
13729        }
13730    }
13731
13732    @Override
13733    public void setServiceForeground(ComponentName className, IBinder token,
13734            int id, Notification notification, boolean removeNotification) {
13735        synchronized(this) {
13736            mServices.setServiceForegroundLocked(className, token, id, notification,
13737                    removeNotification);
13738        }
13739    }
13740
13741    @Override
13742    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13743            boolean requireFull, String name, String callerPackage) {
13744        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13745                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13746    }
13747
13748    int unsafeConvertIncomingUser(int userId) {
13749        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13750                ? mCurrentUserId : userId;
13751    }
13752
13753    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13754            int allowMode, String name, String callerPackage) {
13755        final int callingUserId = UserHandle.getUserId(callingUid);
13756        if (callingUserId == userId) {
13757            return userId;
13758        }
13759
13760        // Note that we may be accessing mCurrentUserId outside of a lock...
13761        // shouldn't be a big deal, if this is being called outside
13762        // of a locked context there is intrinsically a race with
13763        // the value the caller will receive and someone else changing it.
13764        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13765        // we will switch to the calling user if access to the current user fails.
13766        int targetUserId = unsafeConvertIncomingUser(userId);
13767
13768        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13769            final boolean allow;
13770            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13771                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13772                // If the caller has this permission, they always pass go.  And collect $200.
13773                allow = true;
13774            } else if (allowMode == ALLOW_FULL_ONLY) {
13775                // We require full access, sucks to be you.
13776                allow = false;
13777            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13778                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13779                // If the caller does not have either permission, they are always doomed.
13780                allow = false;
13781            } else if (allowMode == ALLOW_NON_FULL) {
13782                // We are blanket allowing non-full access, you lucky caller!
13783                allow = true;
13784            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13785                // We may or may not allow this depending on whether the two users are
13786                // in the same profile.
13787                synchronized (mUserProfileGroupIdsSelfLocked) {
13788                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13789                            UserInfo.NO_PROFILE_GROUP_ID);
13790                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13791                            UserInfo.NO_PROFILE_GROUP_ID);
13792                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13793                            && callingProfile == targetProfile;
13794                }
13795            } else {
13796                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13797            }
13798            if (!allow) {
13799                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13800                    // In this case, they would like to just execute as their
13801                    // owner user instead of failing.
13802                    targetUserId = callingUserId;
13803                } else {
13804                    StringBuilder builder = new StringBuilder(128);
13805                    builder.append("Permission Denial: ");
13806                    builder.append(name);
13807                    if (callerPackage != null) {
13808                        builder.append(" from ");
13809                        builder.append(callerPackage);
13810                    }
13811                    builder.append(" asks to run as user ");
13812                    builder.append(userId);
13813                    builder.append(" but is calling from user ");
13814                    builder.append(UserHandle.getUserId(callingUid));
13815                    builder.append("; this requires ");
13816                    builder.append(INTERACT_ACROSS_USERS_FULL);
13817                    if (allowMode != ALLOW_FULL_ONLY) {
13818                        builder.append(" or ");
13819                        builder.append(INTERACT_ACROSS_USERS);
13820                    }
13821                    String msg = builder.toString();
13822                    Slog.w(TAG, msg);
13823                    throw new SecurityException(msg);
13824                }
13825            }
13826        }
13827        if (!allowAll && targetUserId < 0) {
13828            throw new IllegalArgumentException(
13829                    "Call does not support special user #" + targetUserId);
13830        }
13831        return targetUserId;
13832    }
13833
13834    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13835            String className, int flags) {
13836        boolean result = false;
13837        // For apps that don't have pre-defined UIDs, check for permission
13838        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13839            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13840                if (ActivityManager.checkUidPermission(
13841                        INTERACT_ACROSS_USERS,
13842                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13843                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13844                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13845                            + " requests FLAG_SINGLE_USER, but app does not hold "
13846                            + INTERACT_ACROSS_USERS;
13847                    Slog.w(TAG, msg);
13848                    throw new SecurityException(msg);
13849                }
13850                // Permission passed
13851                result = true;
13852            }
13853        } else if ("system".equals(componentProcessName)) {
13854            result = true;
13855        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13856                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13857            // Phone app is allowed to export singleuser providers.
13858            result = true;
13859        } else {
13860            // App with pre-defined UID, check if it's a persistent app
13861            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13862        }
13863        if (DEBUG_MU) {
13864            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13865                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13866        }
13867        return result;
13868    }
13869
13870    /**
13871     * Checks to see if the caller is in the same app as the singleton
13872     * component, or the component is in a special app. It allows special apps
13873     * to export singleton components but prevents exporting singleton
13874     * components for regular apps.
13875     */
13876    boolean isValidSingletonCall(int callingUid, int componentUid) {
13877        int componentAppId = UserHandle.getAppId(componentUid);
13878        return UserHandle.isSameApp(callingUid, componentUid)
13879                || componentAppId == Process.SYSTEM_UID
13880                || componentAppId == Process.PHONE_UID
13881                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13882                        == PackageManager.PERMISSION_GRANTED;
13883    }
13884
13885    public int bindService(IApplicationThread caller, IBinder token,
13886            Intent service, String resolvedType,
13887            IServiceConnection connection, int flags, int userId) {
13888        enforceNotIsolatedCaller("bindService");
13889        // Refuse possible leaked file descriptors
13890        if (service != null && service.hasFileDescriptors() == true) {
13891            throw new IllegalArgumentException("File descriptors passed in Intent");
13892        }
13893
13894        synchronized(this) {
13895            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13896                    connection, flags, userId);
13897        }
13898    }
13899
13900    public boolean unbindService(IServiceConnection connection) {
13901        synchronized (this) {
13902            return mServices.unbindServiceLocked(connection);
13903        }
13904    }
13905
13906    public void publishService(IBinder token, Intent intent, IBinder service) {
13907        // Refuse possible leaked file descriptors
13908        if (intent != null && intent.hasFileDescriptors() == true) {
13909            throw new IllegalArgumentException("File descriptors passed in Intent");
13910        }
13911
13912        synchronized(this) {
13913            if (!(token instanceof ServiceRecord)) {
13914                throw new IllegalArgumentException("Invalid service token");
13915            }
13916            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13917        }
13918    }
13919
13920    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13921        // Refuse possible leaked file descriptors
13922        if (intent != null && intent.hasFileDescriptors() == true) {
13923            throw new IllegalArgumentException("File descriptors passed in Intent");
13924        }
13925
13926        synchronized(this) {
13927            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13928        }
13929    }
13930
13931    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13932        synchronized(this) {
13933            if (!(token instanceof ServiceRecord)) {
13934                throw new IllegalArgumentException("Invalid service token");
13935            }
13936            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13937        }
13938    }
13939
13940    // =========================================================
13941    // BACKUP AND RESTORE
13942    // =========================================================
13943
13944    // Cause the target app to be launched if necessary and its backup agent
13945    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13946    // activity manager to announce its creation.
13947    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13948        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13949        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13950
13951        synchronized(this) {
13952            // !!! TODO: currently no check here that we're already bound
13953            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13954            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13955            synchronized (stats) {
13956                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13957            }
13958
13959            // Backup agent is now in use, its package can't be stopped.
13960            try {
13961                AppGlobals.getPackageManager().setPackageStoppedState(
13962                        app.packageName, false, UserHandle.getUserId(app.uid));
13963            } catch (RemoteException e) {
13964            } catch (IllegalArgumentException e) {
13965                Slog.w(TAG, "Failed trying to unstop package "
13966                        + app.packageName + ": " + e);
13967            }
13968
13969            BackupRecord r = new BackupRecord(ss, app, backupMode);
13970            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13971                    ? new ComponentName(app.packageName, app.backupAgentName)
13972                    : new ComponentName("android", "FullBackupAgent");
13973            // startProcessLocked() returns existing proc's record if it's already running
13974            ProcessRecord proc = startProcessLocked(app.processName, app,
13975                    false, 0, "backup", hostingName, false, false, false);
13976            if (proc == null) {
13977                Slog.e(TAG, "Unable to start backup agent process " + r);
13978                return false;
13979            }
13980
13981            r.app = proc;
13982            mBackupTarget = r;
13983            mBackupAppName = app.packageName;
13984
13985            // Try not to kill the process during backup
13986            updateOomAdjLocked(proc);
13987
13988            // If the process is already attached, schedule the creation of the backup agent now.
13989            // If it is not yet live, this will be done when it attaches to the framework.
13990            if (proc.thread != null) {
13991                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13992                try {
13993                    proc.thread.scheduleCreateBackupAgent(app,
13994                            compatibilityInfoForPackageLocked(app), backupMode);
13995                } catch (RemoteException e) {
13996                    // Will time out on the backup manager side
13997                }
13998            } else {
13999                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14000            }
14001            // Invariants: at this point, the target app process exists and the application
14002            // is either already running or in the process of coming up.  mBackupTarget and
14003            // mBackupAppName describe the app, so that when it binds back to the AM we
14004            // know that it's scheduled for a backup-agent operation.
14005        }
14006
14007        return true;
14008    }
14009
14010    @Override
14011    public void clearPendingBackup() {
14012        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14013        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14014
14015        synchronized (this) {
14016            mBackupTarget = null;
14017            mBackupAppName = null;
14018        }
14019    }
14020
14021    // A backup agent has just come up
14022    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14023        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14024                + " = " + agent);
14025
14026        synchronized(this) {
14027            if (!agentPackageName.equals(mBackupAppName)) {
14028                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14029                return;
14030            }
14031        }
14032
14033        long oldIdent = Binder.clearCallingIdentity();
14034        try {
14035            IBackupManager bm = IBackupManager.Stub.asInterface(
14036                    ServiceManager.getService(Context.BACKUP_SERVICE));
14037            bm.agentConnected(agentPackageName, agent);
14038        } catch (RemoteException e) {
14039            // can't happen; the backup manager service is local
14040        } catch (Exception e) {
14041            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14042            e.printStackTrace();
14043        } finally {
14044            Binder.restoreCallingIdentity(oldIdent);
14045        }
14046    }
14047
14048    // done with this agent
14049    public void unbindBackupAgent(ApplicationInfo appInfo) {
14050        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14051        if (appInfo == null) {
14052            Slog.w(TAG, "unbind backup agent for null app");
14053            return;
14054        }
14055
14056        synchronized(this) {
14057            try {
14058                if (mBackupAppName == null) {
14059                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14060                    return;
14061                }
14062
14063                if (!mBackupAppName.equals(appInfo.packageName)) {
14064                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14065                    return;
14066                }
14067
14068                // Not backing this app up any more; reset its OOM adjustment
14069                final ProcessRecord proc = mBackupTarget.app;
14070                updateOomAdjLocked(proc);
14071
14072                // If the app crashed during backup, 'thread' will be null here
14073                if (proc.thread != null) {
14074                    try {
14075                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14076                                compatibilityInfoForPackageLocked(appInfo));
14077                    } catch (Exception e) {
14078                        Slog.e(TAG, "Exception when unbinding backup agent:");
14079                        e.printStackTrace();
14080                    }
14081                }
14082            } finally {
14083                mBackupTarget = null;
14084                mBackupAppName = null;
14085            }
14086        }
14087    }
14088    // =========================================================
14089    // BROADCASTS
14090    // =========================================================
14091
14092    private final List getStickiesLocked(String action, IntentFilter filter,
14093            List cur, int userId) {
14094        final ContentResolver resolver = mContext.getContentResolver();
14095        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14096        if (stickies == null) {
14097            return cur;
14098        }
14099        final ArrayList<Intent> list = stickies.get(action);
14100        if (list == null) {
14101            return cur;
14102        }
14103        int N = list.size();
14104        for (int i=0; i<N; i++) {
14105            Intent intent = list.get(i);
14106            if (filter.match(resolver, intent, true, TAG) >= 0) {
14107                if (cur == null) {
14108                    cur = new ArrayList<Intent>();
14109                }
14110                cur.add(intent);
14111            }
14112        }
14113        return cur;
14114    }
14115
14116    boolean isPendingBroadcastProcessLocked(int pid) {
14117        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14118                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14119    }
14120
14121    void skipPendingBroadcastLocked(int pid) {
14122            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14123            for (BroadcastQueue queue : mBroadcastQueues) {
14124                queue.skipPendingBroadcastLocked(pid);
14125            }
14126    }
14127
14128    // The app just attached; send any pending broadcasts that it should receive
14129    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14130        boolean didSomething = false;
14131        for (BroadcastQueue queue : mBroadcastQueues) {
14132            didSomething |= queue.sendPendingBroadcastsLocked(app);
14133        }
14134        return didSomething;
14135    }
14136
14137    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14138            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14139        enforceNotIsolatedCaller("registerReceiver");
14140        int callingUid;
14141        int callingPid;
14142        synchronized(this) {
14143            ProcessRecord callerApp = null;
14144            if (caller != null) {
14145                callerApp = getRecordForAppLocked(caller);
14146                if (callerApp == null) {
14147                    throw new SecurityException(
14148                            "Unable to find app for caller " + caller
14149                            + " (pid=" + Binder.getCallingPid()
14150                            + ") when registering receiver " + receiver);
14151                }
14152                if (callerApp.info.uid != Process.SYSTEM_UID &&
14153                        !callerApp.pkgList.containsKey(callerPackage) &&
14154                        !"android".equals(callerPackage)) {
14155                    throw new SecurityException("Given caller package " + callerPackage
14156                            + " is not running in process " + callerApp);
14157                }
14158                callingUid = callerApp.info.uid;
14159                callingPid = callerApp.pid;
14160            } else {
14161                callerPackage = null;
14162                callingUid = Binder.getCallingUid();
14163                callingPid = Binder.getCallingPid();
14164            }
14165
14166            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14167                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14168
14169            List allSticky = null;
14170
14171            // Look for any matching sticky broadcasts...
14172            Iterator actions = filter.actionsIterator();
14173            if (actions != null) {
14174                while (actions.hasNext()) {
14175                    String action = (String)actions.next();
14176                    allSticky = getStickiesLocked(action, filter, allSticky,
14177                            UserHandle.USER_ALL);
14178                    allSticky = getStickiesLocked(action, filter, allSticky,
14179                            UserHandle.getUserId(callingUid));
14180                }
14181            } else {
14182                allSticky = getStickiesLocked(null, filter, allSticky,
14183                        UserHandle.USER_ALL);
14184                allSticky = getStickiesLocked(null, filter, allSticky,
14185                        UserHandle.getUserId(callingUid));
14186            }
14187
14188            // The first sticky in the list is returned directly back to
14189            // the client.
14190            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14191
14192            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14193                    + ": " + sticky);
14194
14195            if (receiver == null) {
14196                return sticky;
14197            }
14198
14199            ReceiverList rl
14200                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14201            if (rl == null) {
14202                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14203                        userId, receiver);
14204                if (rl.app != null) {
14205                    rl.app.receivers.add(rl);
14206                } else {
14207                    try {
14208                        receiver.asBinder().linkToDeath(rl, 0);
14209                    } catch (RemoteException e) {
14210                        return sticky;
14211                    }
14212                    rl.linkedToDeath = true;
14213                }
14214                mRegisteredReceivers.put(receiver.asBinder(), rl);
14215            } else if (rl.uid != callingUid) {
14216                throw new IllegalArgumentException(
14217                        "Receiver requested to register for uid " + callingUid
14218                        + " was previously registered for uid " + rl.uid);
14219            } else if (rl.pid != callingPid) {
14220                throw new IllegalArgumentException(
14221                        "Receiver requested to register for pid " + callingPid
14222                        + " was previously registered for pid " + rl.pid);
14223            } else if (rl.userId != userId) {
14224                throw new IllegalArgumentException(
14225                        "Receiver requested to register for user " + userId
14226                        + " was previously registered for user " + rl.userId);
14227            }
14228            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14229                    permission, callingUid, userId);
14230            rl.add(bf);
14231            if (!bf.debugCheck()) {
14232                Slog.w(TAG, "==> For Dynamic broadast");
14233            }
14234            mReceiverResolver.addFilter(bf);
14235
14236            // Enqueue broadcasts for all existing stickies that match
14237            // this filter.
14238            if (allSticky != null) {
14239                ArrayList receivers = new ArrayList();
14240                receivers.add(bf);
14241
14242                int N = allSticky.size();
14243                for (int i=0; i<N; i++) {
14244                    Intent intent = (Intent)allSticky.get(i);
14245                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14246                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14247                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14248                            null, null, false, true, true, -1);
14249                    queue.enqueueParallelBroadcastLocked(r);
14250                    queue.scheduleBroadcastsLocked();
14251                }
14252            }
14253
14254            return sticky;
14255        }
14256    }
14257
14258    public void unregisterReceiver(IIntentReceiver receiver) {
14259        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14260
14261        final long origId = Binder.clearCallingIdentity();
14262        try {
14263            boolean doTrim = false;
14264
14265            synchronized(this) {
14266                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14267                if (rl != null) {
14268                    if (rl.curBroadcast != null) {
14269                        BroadcastRecord r = rl.curBroadcast;
14270                        final boolean doNext = finishReceiverLocked(
14271                                receiver.asBinder(), r.resultCode, r.resultData,
14272                                r.resultExtras, r.resultAbort);
14273                        if (doNext) {
14274                            doTrim = true;
14275                            r.queue.processNextBroadcast(false);
14276                        }
14277                    }
14278
14279                    if (rl.app != null) {
14280                        rl.app.receivers.remove(rl);
14281                    }
14282                    removeReceiverLocked(rl);
14283                    if (rl.linkedToDeath) {
14284                        rl.linkedToDeath = false;
14285                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14286                    }
14287                }
14288            }
14289
14290            // If we actually concluded any broadcasts, we might now be able
14291            // to trim the recipients' apps from our working set
14292            if (doTrim) {
14293                trimApplications();
14294                return;
14295            }
14296
14297        } finally {
14298            Binder.restoreCallingIdentity(origId);
14299        }
14300    }
14301
14302    void removeReceiverLocked(ReceiverList rl) {
14303        mRegisteredReceivers.remove(rl.receiver.asBinder());
14304        int N = rl.size();
14305        for (int i=0; i<N; i++) {
14306            mReceiverResolver.removeFilter(rl.get(i));
14307        }
14308    }
14309
14310    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14311        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14312            ProcessRecord r = mLruProcesses.get(i);
14313            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14314                try {
14315                    r.thread.dispatchPackageBroadcast(cmd, packages);
14316                } catch (RemoteException ex) {
14317                }
14318            }
14319        }
14320    }
14321
14322    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14323            int[] users) {
14324        List<ResolveInfo> receivers = null;
14325        try {
14326            HashSet<ComponentName> singleUserReceivers = null;
14327            boolean scannedFirstReceivers = false;
14328            for (int user : users) {
14329                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14330                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14331                if (user != 0 && newReceivers != null) {
14332                    // If this is not the primary user, we need to check for
14333                    // any receivers that should be filtered out.
14334                    for (int i=0; i<newReceivers.size(); i++) {
14335                        ResolveInfo ri = newReceivers.get(i);
14336                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14337                            newReceivers.remove(i);
14338                            i--;
14339                        }
14340                    }
14341                }
14342                if (newReceivers != null && newReceivers.size() == 0) {
14343                    newReceivers = null;
14344                }
14345                if (receivers == null) {
14346                    receivers = newReceivers;
14347                } else if (newReceivers != null) {
14348                    // We need to concatenate the additional receivers
14349                    // found with what we have do far.  This would be easy,
14350                    // but we also need to de-dup any receivers that are
14351                    // singleUser.
14352                    if (!scannedFirstReceivers) {
14353                        // Collect any single user receivers we had already retrieved.
14354                        scannedFirstReceivers = true;
14355                        for (int i=0; i<receivers.size(); i++) {
14356                            ResolveInfo ri = receivers.get(i);
14357                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14358                                ComponentName cn = new ComponentName(
14359                                        ri.activityInfo.packageName, ri.activityInfo.name);
14360                                if (singleUserReceivers == null) {
14361                                    singleUserReceivers = new HashSet<ComponentName>();
14362                                }
14363                                singleUserReceivers.add(cn);
14364                            }
14365                        }
14366                    }
14367                    // Add the new results to the existing results, tracking
14368                    // and de-dupping single user receivers.
14369                    for (int i=0; i<newReceivers.size(); i++) {
14370                        ResolveInfo ri = newReceivers.get(i);
14371                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14372                            ComponentName cn = new ComponentName(
14373                                    ri.activityInfo.packageName, ri.activityInfo.name);
14374                            if (singleUserReceivers == null) {
14375                                singleUserReceivers = new HashSet<ComponentName>();
14376                            }
14377                            if (!singleUserReceivers.contains(cn)) {
14378                                singleUserReceivers.add(cn);
14379                                receivers.add(ri);
14380                            }
14381                        } else {
14382                            receivers.add(ri);
14383                        }
14384                    }
14385                }
14386            }
14387        } catch (RemoteException ex) {
14388            // pm is in same process, this will never happen.
14389        }
14390        return receivers;
14391    }
14392
14393    private final int broadcastIntentLocked(ProcessRecord callerApp,
14394            String callerPackage, Intent intent, String resolvedType,
14395            IIntentReceiver resultTo, int resultCode, String resultData,
14396            Bundle map, String requiredPermission, int appOp,
14397            boolean ordered, boolean sticky, int callingPid, int callingUid,
14398            int userId) {
14399        intent = new Intent(intent);
14400
14401        // By default broadcasts do not go to stopped apps.
14402        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14403
14404        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14405            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14406            + " ordered=" + ordered + " userid=" + userId);
14407        if ((resultTo != null) && !ordered) {
14408            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14409        }
14410
14411        userId = handleIncomingUser(callingPid, callingUid, userId,
14412                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14413
14414        // Make sure that the user who is receiving this broadcast is started.
14415        // If not, we will just skip it.
14416
14417
14418        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14419            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14420                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14421                Slog.w(TAG, "Skipping broadcast of " + intent
14422                        + ": user " + userId + " is stopped");
14423                return ActivityManager.BROADCAST_SUCCESS;
14424            }
14425        }
14426
14427        /*
14428         * Prevent non-system code (defined here to be non-persistent
14429         * processes) from sending protected broadcasts.
14430         */
14431        int callingAppId = UserHandle.getAppId(callingUid);
14432        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14433            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14434            || callingAppId == Process.NFC_UID || callingUid == 0) {
14435            // Always okay.
14436        } else if (callerApp == null || !callerApp.persistent) {
14437            try {
14438                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14439                        intent.getAction())) {
14440                    String msg = "Permission Denial: not allowed to send broadcast "
14441                            + intent.getAction() + " from pid="
14442                            + callingPid + ", uid=" + callingUid;
14443                    Slog.w(TAG, msg);
14444                    throw new SecurityException(msg);
14445                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14446                    // Special case for compatibility: we don't want apps to send this,
14447                    // but historically it has not been protected and apps may be using it
14448                    // to poke their own app widget.  So, instead of making it protected,
14449                    // just limit it to the caller.
14450                    if (callerApp == null) {
14451                        String msg = "Permission Denial: not allowed to send broadcast "
14452                                + intent.getAction() + " from unknown caller.";
14453                        Slog.w(TAG, msg);
14454                        throw new SecurityException(msg);
14455                    } else if (intent.getComponent() != null) {
14456                        // They are good enough to send to an explicit component...  verify
14457                        // it is being sent to the calling app.
14458                        if (!intent.getComponent().getPackageName().equals(
14459                                callerApp.info.packageName)) {
14460                            String msg = "Permission Denial: not allowed to send broadcast "
14461                                    + intent.getAction() + " to "
14462                                    + intent.getComponent().getPackageName() + " from "
14463                                    + callerApp.info.packageName;
14464                            Slog.w(TAG, msg);
14465                            throw new SecurityException(msg);
14466                        }
14467                    } else {
14468                        // Limit broadcast to their own package.
14469                        intent.setPackage(callerApp.info.packageName);
14470                    }
14471                }
14472            } catch (RemoteException e) {
14473                Slog.w(TAG, "Remote exception", e);
14474                return ActivityManager.BROADCAST_SUCCESS;
14475            }
14476        }
14477
14478        // Handle special intents: if this broadcast is from the package
14479        // manager about a package being removed, we need to remove all of
14480        // its activities from the history stack.
14481        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14482                intent.getAction());
14483        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14484                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14485                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14486                || uidRemoved) {
14487            if (checkComponentPermission(
14488                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14489                    callingPid, callingUid, -1, true)
14490                    == PackageManager.PERMISSION_GRANTED) {
14491                if (uidRemoved) {
14492                    final Bundle intentExtras = intent.getExtras();
14493                    final int uid = intentExtras != null
14494                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14495                    if (uid >= 0) {
14496                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14497                        synchronized (bs) {
14498                            bs.removeUidStatsLocked(uid);
14499                        }
14500                        mAppOpsService.uidRemoved(uid);
14501                    }
14502                } else {
14503                    // If resources are unavailable just force stop all
14504                    // those packages and flush the attribute cache as well.
14505                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14506                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14507                        if (list != null && (list.length > 0)) {
14508                            for (String pkg : list) {
14509                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14510                                        "storage unmount");
14511                            }
14512                            sendPackageBroadcastLocked(
14513                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14514                        }
14515                    } else {
14516                        Uri data = intent.getData();
14517                        String ssp;
14518                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14519                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14520                                    intent.getAction());
14521                            boolean fullUninstall = removed &&
14522                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14523                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14524                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14525                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14526                                        false, fullUninstall, userId,
14527                                        removed ? "pkg removed" : "pkg changed");
14528                            }
14529                            if (removed) {
14530                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14531                                        new String[] {ssp}, userId);
14532                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14533                                    mAppOpsService.packageRemoved(
14534                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14535
14536                                    // Remove all permissions granted from/to this package
14537                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14538                                }
14539                            }
14540                        }
14541                    }
14542                }
14543            } else {
14544                String msg = "Permission Denial: " + intent.getAction()
14545                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14546                        + ", uid=" + callingUid + ")"
14547                        + " requires "
14548                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14549                Slog.w(TAG, msg);
14550                throw new SecurityException(msg);
14551            }
14552
14553        // Special case for adding a package: by default turn on compatibility
14554        // mode.
14555        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14556            Uri data = intent.getData();
14557            String ssp;
14558            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14559                mCompatModePackages.handlePackageAddedLocked(ssp,
14560                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14561            }
14562        }
14563
14564        /*
14565         * If this is the time zone changed action, queue up a message that will reset the timezone
14566         * of all currently running processes. This message will get queued up before the broadcast
14567         * happens.
14568         */
14569        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14570            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14571        }
14572
14573        /*
14574         * If the user set the time, let all running processes know.
14575         */
14576        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14577            final int is24Hour = intent.getBooleanExtra(
14578                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14579            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14580        }
14581
14582        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14583            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14584        }
14585
14586        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14587            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14588            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14589        }
14590
14591        // Add to the sticky list if requested.
14592        if (sticky) {
14593            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14594                    callingPid, callingUid)
14595                    != PackageManager.PERMISSION_GRANTED) {
14596                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14597                        + callingPid + ", uid=" + callingUid
14598                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14599                Slog.w(TAG, msg);
14600                throw new SecurityException(msg);
14601            }
14602            if (requiredPermission != null) {
14603                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14604                        + " and enforce permission " + requiredPermission);
14605                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14606            }
14607            if (intent.getComponent() != null) {
14608                throw new SecurityException(
14609                        "Sticky broadcasts can't target a specific component");
14610            }
14611            // We use userId directly here, since the "all" target is maintained
14612            // as a separate set of sticky broadcasts.
14613            if (userId != UserHandle.USER_ALL) {
14614                // But first, if this is not a broadcast to all users, then
14615                // make sure it doesn't conflict with an existing broadcast to
14616                // all users.
14617                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14618                        UserHandle.USER_ALL);
14619                if (stickies != null) {
14620                    ArrayList<Intent> list = stickies.get(intent.getAction());
14621                    if (list != null) {
14622                        int N = list.size();
14623                        int i;
14624                        for (i=0; i<N; i++) {
14625                            if (intent.filterEquals(list.get(i))) {
14626                                throw new IllegalArgumentException(
14627                                        "Sticky broadcast " + intent + " for user "
14628                                        + userId + " conflicts with existing global broadcast");
14629                            }
14630                        }
14631                    }
14632                }
14633            }
14634            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14635            if (stickies == null) {
14636                stickies = new ArrayMap<String, ArrayList<Intent>>();
14637                mStickyBroadcasts.put(userId, stickies);
14638            }
14639            ArrayList<Intent> list = stickies.get(intent.getAction());
14640            if (list == null) {
14641                list = new ArrayList<Intent>();
14642                stickies.put(intent.getAction(), list);
14643            }
14644            int N = list.size();
14645            int i;
14646            for (i=0; i<N; i++) {
14647                if (intent.filterEquals(list.get(i))) {
14648                    // This sticky already exists, replace it.
14649                    list.set(i, new Intent(intent));
14650                    break;
14651                }
14652            }
14653            if (i >= N) {
14654                list.add(new Intent(intent));
14655            }
14656        }
14657
14658        int[] users;
14659        if (userId == UserHandle.USER_ALL) {
14660            // Caller wants broadcast to go to all started users.
14661            users = mStartedUserArray;
14662        } else {
14663            // Caller wants broadcast to go to one specific user.
14664            users = new int[] {userId};
14665        }
14666
14667        // Figure out who all will receive this broadcast.
14668        List receivers = null;
14669        List<BroadcastFilter> registeredReceivers = null;
14670        // Need to resolve the intent to interested receivers...
14671        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14672                 == 0) {
14673            receivers = collectReceiverComponents(intent, resolvedType, users);
14674        }
14675        if (intent.getComponent() == null) {
14676            registeredReceivers = mReceiverResolver.queryIntent(intent,
14677                    resolvedType, false, userId);
14678        }
14679
14680        final boolean replacePending =
14681                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14682
14683        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14684                + " replacePending=" + replacePending);
14685
14686        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14687        if (!ordered && NR > 0) {
14688            // If we are not serializing this broadcast, then send the
14689            // registered receivers separately so they don't wait for the
14690            // components to be launched.
14691            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14692            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14693                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14694                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14695                    ordered, sticky, false, userId);
14696            if (DEBUG_BROADCAST) Slog.v(
14697                    TAG, "Enqueueing parallel broadcast " + r);
14698            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14699            if (!replaced) {
14700                queue.enqueueParallelBroadcastLocked(r);
14701                queue.scheduleBroadcastsLocked();
14702            }
14703            registeredReceivers = null;
14704            NR = 0;
14705        }
14706
14707        // Merge into one list.
14708        int ir = 0;
14709        if (receivers != null) {
14710            // A special case for PACKAGE_ADDED: do not allow the package
14711            // being added to see this broadcast.  This prevents them from
14712            // using this as a back door to get run as soon as they are
14713            // installed.  Maybe in the future we want to have a special install
14714            // broadcast or such for apps, but we'd like to deliberately make
14715            // this decision.
14716            String skipPackages[] = null;
14717            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14718                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14719                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14720                Uri data = intent.getData();
14721                if (data != null) {
14722                    String pkgName = data.getSchemeSpecificPart();
14723                    if (pkgName != null) {
14724                        skipPackages = new String[] { pkgName };
14725                    }
14726                }
14727            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14728                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14729            }
14730            if (skipPackages != null && (skipPackages.length > 0)) {
14731                for (String skipPackage : skipPackages) {
14732                    if (skipPackage != null) {
14733                        int NT = receivers.size();
14734                        for (int it=0; it<NT; it++) {
14735                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14736                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14737                                receivers.remove(it);
14738                                it--;
14739                                NT--;
14740                            }
14741                        }
14742                    }
14743                }
14744            }
14745
14746            int NT = receivers != null ? receivers.size() : 0;
14747            int it = 0;
14748            ResolveInfo curt = null;
14749            BroadcastFilter curr = null;
14750            while (it < NT && ir < NR) {
14751                if (curt == null) {
14752                    curt = (ResolveInfo)receivers.get(it);
14753                }
14754                if (curr == null) {
14755                    curr = registeredReceivers.get(ir);
14756                }
14757                if (curr.getPriority() >= curt.priority) {
14758                    // Insert this broadcast record into the final list.
14759                    receivers.add(it, curr);
14760                    ir++;
14761                    curr = null;
14762                    it++;
14763                    NT++;
14764                } else {
14765                    // Skip to the next ResolveInfo in the final list.
14766                    it++;
14767                    curt = null;
14768                }
14769            }
14770        }
14771        while (ir < NR) {
14772            if (receivers == null) {
14773                receivers = new ArrayList();
14774            }
14775            receivers.add(registeredReceivers.get(ir));
14776            ir++;
14777        }
14778
14779        if ((receivers != null && receivers.size() > 0)
14780                || resultTo != null) {
14781            BroadcastQueue queue = broadcastQueueForIntent(intent);
14782            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14783                    callerPackage, callingPid, callingUid, resolvedType,
14784                    requiredPermission, appOp, receivers, resultTo, resultCode,
14785                    resultData, map, ordered, sticky, false, userId);
14786            if (DEBUG_BROADCAST) Slog.v(
14787                    TAG, "Enqueueing ordered broadcast " + r
14788                    + ": prev had " + queue.mOrderedBroadcasts.size());
14789            if (DEBUG_BROADCAST) {
14790                int seq = r.intent.getIntExtra("seq", -1);
14791                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14792            }
14793            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14794            if (!replaced) {
14795                queue.enqueueOrderedBroadcastLocked(r);
14796                queue.scheduleBroadcastsLocked();
14797            }
14798        }
14799
14800        return ActivityManager.BROADCAST_SUCCESS;
14801    }
14802
14803    final Intent verifyBroadcastLocked(Intent intent) {
14804        // Refuse possible leaked file descriptors
14805        if (intent != null && intent.hasFileDescriptors() == true) {
14806            throw new IllegalArgumentException("File descriptors passed in Intent");
14807        }
14808
14809        int flags = intent.getFlags();
14810
14811        if (!mProcessesReady) {
14812            // if the caller really truly claims to know what they're doing, go
14813            // ahead and allow the broadcast without launching any receivers
14814            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14815                intent = new Intent(intent);
14816                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14817            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14818                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14819                        + " before boot completion");
14820                throw new IllegalStateException("Cannot broadcast before boot completed");
14821            }
14822        }
14823
14824        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14825            throw new IllegalArgumentException(
14826                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14827        }
14828
14829        return intent;
14830    }
14831
14832    public final int broadcastIntent(IApplicationThread caller,
14833            Intent intent, String resolvedType, IIntentReceiver resultTo,
14834            int resultCode, String resultData, Bundle map,
14835            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14836        enforceNotIsolatedCaller("broadcastIntent");
14837        synchronized(this) {
14838            intent = verifyBroadcastLocked(intent);
14839
14840            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14841            final int callingPid = Binder.getCallingPid();
14842            final int callingUid = Binder.getCallingUid();
14843            final long origId = Binder.clearCallingIdentity();
14844            int res = broadcastIntentLocked(callerApp,
14845                    callerApp != null ? callerApp.info.packageName : null,
14846                    intent, resolvedType, resultTo,
14847                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14848                    callingPid, callingUid, userId);
14849            Binder.restoreCallingIdentity(origId);
14850            return res;
14851        }
14852    }
14853
14854    int broadcastIntentInPackage(String packageName, int uid,
14855            Intent intent, String resolvedType, IIntentReceiver resultTo,
14856            int resultCode, String resultData, Bundle map,
14857            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14858        synchronized(this) {
14859            intent = verifyBroadcastLocked(intent);
14860
14861            final long origId = Binder.clearCallingIdentity();
14862            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14863                    resultTo, resultCode, resultData, map, requiredPermission,
14864                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14865            Binder.restoreCallingIdentity(origId);
14866            return res;
14867        }
14868    }
14869
14870    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14871        // Refuse possible leaked file descriptors
14872        if (intent != null && intent.hasFileDescriptors() == true) {
14873            throw new IllegalArgumentException("File descriptors passed in Intent");
14874        }
14875
14876        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14877                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14878
14879        synchronized(this) {
14880            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14881                    != PackageManager.PERMISSION_GRANTED) {
14882                String msg = "Permission Denial: unbroadcastIntent() from pid="
14883                        + Binder.getCallingPid()
14884                        + ", uid=" + Binder.getCallingUid()
14885                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14886                Slog.w(TAG, msg);
14887                throw new SecurityException(msg);
14888            }
14889            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14890            if (stickies != null) {
14891                ArrayList<Intent> list = stickies.get(intent.getAction());
14892                if (list != null) {
14893                    int N = list.size();
14894                    int i;
14895                    for (i=0; i<N; i++) {
14896                        if (intent.filterEquals(list.get(i))) {
14897                            list.remove(i);
14898                            break;
14899                        }
14900                    }
14901                    if (list.size() <= 0) {
14902                        stickies.remove(intent.getAction());
14903                    }
14904                }
14905                if (stickies.size() <= 0) {
14906                    mStickyBroadcasts.remove(userId);
14907                }
14908            }
14909        }
14910    }
14911
14912    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14913            String resultData, Bundle resultExtras, boolean resultAbort) {
14914        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14915        if (r == null) {
14916            Slog.w(TAG, "finishReceiver called but not found on queue");
14917            return false;
14918        }
14919
14920        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14921    }
14922
14923    void backgroundServicesFinishedLocked(int userId) {
14924        for (BroadcastQueue queue : mBroadcastQueues) {
14925            queue.backgroundServicesFinishedLocked(userId);
14926        }
14927    }
14928
14929    public void finishReceiver(IBinder who, int resultCode, String resultData,
14930            Bundle resultExtras, boolean resultAbort) {
14931        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14932
14933        // Refuse possible leaked file descriptors
14934        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14935            throw new IllegalArgumentException("File descriptors passed in Bundle");
14936        }
14937
14938        final long origId = Binder.clearCallingIdentity();
14939        try {
14940            boolean doNext = false;
14941            BroadcastRecord r;
14942
14943            synchronized(this) {
14944                r = broadcastRecordForReceiverLocked(who);
14945                if (r != null) {
14946                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14947                        resultData, resultExtras, resultAbort, true);
14948                }
14949            }
14950
14951            if (doNext) {
14952                r.queue.processNextBroadcast(false);
14953            }
14954            trimApplications();
14955        } finally {
14956            Binder.restoreCallingIdentity(origId);
14957        }
14958    }
14959
14960    // =========================================================
14961    // INSTRUMENTATION
14962    // =========================================================
14963
14964    public boolean startInstrumentation(ComponentName className,
14965            String profileFile, int flags, Bundle arguments,
14966            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14967            int userId, String abiOverride) {
14968        enforceNotIsolatedCaller("startInstrumentation");
14969        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14970                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14971        // Refuse possible leaked file descriptors
14972        if (arguments != null && arguments.hasFileDescriptors()) {
14973            throw new IllegalArgumentException("File descriptors passed in Bundle");
14974        }
14975
14976        synchronized(this) {
14977            InstrumentationInfo ii = null;
14978            ApplicationInfo ai = null;
14979            try {
14980                ii = mContext.getPackageManager().getInstrumentationInfo(
14981                    className, STOCK_PM_FLAGS);
14982                ai = AppGlobals.getPackageManager().getApplicationInfo(
14983                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14984            } catch (PackageManager.NameNotFoundException e) {
14985            } catch (RemoteException e) {
14986            }
14987            if (ii == null) {
14988                reportStartInstrumentationFailure(watcher, className,
14989                        "Unable to find instrumentation info for: " + className);
14990                return false;
14991            }
14992            if (ai == null) {
14993                reportStartInstrumentationFailure(watcher, className,
14994                        "Unable to find instrumentation target package: " + ii.targetPackage);
14995                return false;
14996            }
14997
14998            int match = mContext.getPackageManager().checkSignatures(
14999                    ii.targetPackage, ii.packageName);
15000            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15001                String msg = "Permission Denial: starting instrumentation "
15002                        + className + " from pid="
15003                        + Binder.getCallingPid()
15004                        + ", uid=" + Binder.getCallingPid()
15005                        + " not allowed because package " + ii.packageName
15006                        + " does not have a signature matching the target "
15007                        + ii.targetPackage;
15008                reportStartInstrumentationFailure(watcher, className, msg);
15009                throw new SecurityException(msg);
15010            }
15011
15012            final long origId = Binder.clearCallingIdentity();
15013            // Instrumentation can kill and relaunch even persistent processes
15014            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15015                    "start instr");
15016            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15017            app.instrumentationClass = className;
15018            app.instrumentationInfo = ai;
15019            app.instrumentationProfileFile = profileFile;
15020            app.instrumentationArguments = arguments;
15021            app.instrumentationWatcher = watcher;
15022            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15023            app.instrumentationResultClass = className;
15024            Binder.restoreCallingIdentity(origId);
15025        }
15026
15027        return true;
15028    }
15029
15030    /**
15031     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15032     * error to the logs, but if somebody is watching, send the report there too.  This enables
15033     * the "am" command to report errors with more information.
15034     *
15035     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15036     * @param cn The component name of the instrumentation.
15037     * @param report The error report.
15038     */
15039    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15040            ComponentName cn, String report) {
15041        Slog.w(TAG, report);
15042        try {
15043            if (watcher != null) {
15044                Bundle results = new Bundle();
15045                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15046                results.putString("Error", report);
15047                watcher.instrumentationStatus(cn, -1, results);
15048            }
15049        } catch (RemoteException e) {
15050            Slog.w(TAG, e);
15051        }
15052    }
15053
15054    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15055        if (app.instrumentationWatcher != null) {
15056            try {
15057                // NOTE:  IInstrumentationWatcher *must* be oneway here
15058                app.instrumentationWatcher.instrumentationFinished(
15059                    app.instrumentationClass,
15060                    resultCode,
15061                    results);
15062            } catch (RemoteException e) {
15063            }
15064        }
15065        if (app.instrumentationUiAutomationConnection != null) {
15066            try {
15067                app.instrumentationUiAutomationConnection.shutdown();
15068            } catch (RemoteException re) {
15069                /* ignore */
15070            }
15071            // Only a UiAutomation can set this flag and now that
15072            // it is finished we make sure it is reset to its default.
15073            mUserIsMonkey = false;
15074        }
15075        app.instrumentationWatcher = null;
15076        app.instrumentationUiAutomationConnection = null;
15077        app.instrumentationClass = null;
15078        app.instrumentationInfo = null;
15079        app.instrumentationProfileFile = null;
15080        app.instrumentationArguments = null;
15081
15082        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15083                "finished inst");
15084    }
15085
15086    public void finishInstrumentation(IApplicationThread target,
15087            int resultCode, Bundle results) {
15088        int userId = UserHandle.getCallingUserId();
15089        // Refuse possible leaked file descriptors
15090        if (results != null && results.hasFileDescriptors()) {
15091            throw new IllegalArgumentException("File descriptors passed in Intent");
15092        }
15093
15094        synchronized(this) {
15095            ProcessRecord app = getRecordForAppLocked(target);
15096            if (app == null) {
15097                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15098                return;
15099            }
15100            final long origId = Binder.clearCallingIdentity();
15101            finishInstrumentationLocked(app, resultCode, results);
15102            Binder.restoreCallingIdentity(origId);
15103        }
15104    }
15105
15106    // =========================================================
15107    // CONFIGURATION
15108    // =========================================================
15109
15110    public ConfigurationInfo getDeviceConfigurationInfo() {
15111        ConfigurationInfo config = new ConfigurationInfo();
15112        synchronized (this) {
15113            config.reqTouchScreen = mConfiguration.touchscreen;
15114            config.reqKeyboardType = mConfiguration.keyboard;
15115            config.reqNavigation = mConfiguration.navigation;
15116            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15117                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15118                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15119            }
15120            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15121                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15122                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15123            }
15124            config.reqGlEsVersion = GL_ES_VERSION;
15125        }
15126        return config;
15127    }
15128
15129    ActivityStack getFocusedStack() {
15130        return mStackSupervisor.getFocusedStack();
15131    }
15132
15133    public Configuration getConfiguration() {
15134        Configuration ci;
15135        synchronized(this) {
15136            ci = new Configuration(mConfiguration);
15137        }
15138        return ci;
15139    }
15140
15141    public void updatePersistentConfiguration(Configuration values) {
15142        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15143                "updateConfiguration()");
15144        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15145                "updateConfiguration()");
15146        if (values == null) {
15147            throw new NullPointerException("Configuration must not be null");
15148        }
15149
15150        synchronized(this) {
15151            final long origId = Binder.clearCallingIdentity();
15152            updateConfigurationLocked(values, null, true, false);
15153            Binder.restoreCallingIdentity(origId);
15154        }
15155    }
15156
15157    public void updateConfiguration(Configuration values) {
15158        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15159                "updateConfiguration()");
15160
15161        synchronized(this) {
15162            if (values == null && mWindowManager != null) {
15163                // sentinel: fetch the current configuration from the window manager
15164                values = mWindowManager.computeNewConfiguration();
15165            }
15166
15167            if (mWindowManager != null) {
15168                mProcessList.applyDisplaySize(mWindowManager);
15169            }
15170
15171            final long origId = Binder.clearCallingIdentity();
15172            if (values != null) {
15173                Settings.System.clearConfiguration(values);
15174            }
15175            updateConfigurationLocked(values, null, false, false);
15176            Binder.restoreCallingIdentity(origId);
15177        }
15178    }
15179
15180    /**
15181     * Do either or both things: (1) change the current configuration, and (2)
15182     * make sure the given activity is running with the (now) current
15183     * configuration.  Returns true if the activity has been left running, or
15184     * false if <var>starting</var> is being destroyed to match the new
15185     * configuration.
15186     * @param persistent TODO
15187     */
15188    boolean updateConfigurationLocked(Configuration values,
15189            ActivityRecord starting, boolean persistent, boolean initLocale) {
15190        int changes = 0;
15191
15192        if (values != null) {
15193            Configuration newConfig = new Configuration(mConfiguration);
15194            changes = newConfig.updateFrom(values);
15195            if (changes != 0) {
15196                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15197                    Slog.i(TAG, "Updating configuration to: " + values);
15198                }
15199
15200                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15201
15202                if (values.locale != null && !initLocale) {
15203                    saveLocaleLocked(values.locale,
15204                                     !values.locale.equals(mConfiguration.locale),
15205                                     values.userSetLocale);
15206                }
15207
15208                mConfigurationSeq++;
15209                if (mConfigurationSeq <= 0) {
15210                    mConfigurationSeq = 1;
15211                }
15212                newConfig.seq = mConfigurationSeq;
15213                mConfiguration = newConfig;
15214                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15215                //mUsageStatsService.noteStartConfig(newConfig);
15216
15217                final Configuration configCopy = new Configuration(mConfiguration);
15218
15219                // TODO: If our config changes, should we auto dismiss any currently
15220                // showing dialogs?
15221                mShowDialogs = shouldShowDialogs(newConfig);
15222
15223                AttributeCache ac = AttributeCache.instance();
15224                if (ac != null) {
15225                    ac.updateConfiguration(configCopy);
15226                }
15227
15228                // Make sure all resources in our process are updated
15229                // right now, so that anyone who is going to retrieve
15230                // resource values after we return will be sure to get
15231                // the new ones.  This is especially important during
15232                // boot, where the first config change needs to guarantee
15233                // all resources have that config before following boot
15234                // code is executed.
15235                mSystemThread.applyConfigurationToResources(configCopy);
15236
15237                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15238                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15239                    msg.obj = new Configuration(configCopy);
15240                    mHandler.sendMessage(msg);
15241                }
15242
15243                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15244                    ProcessRecord app = mLruProcesses.get(i);
15245                    try {
15246                        if (app.thread != null) {
15247                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15248                                    + app.processName + " new config " + mConfiguration);
15249                            app.thread.scheduleConfigurationChanged(configCopy);
15250                        }
15251                    } catch (Exception e) {
15252                    }
15253                }
15254                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15255                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15256                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15257                        | Intent.FLAG_RECEIVER_FOREGROUND);
15258                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15259                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15260                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15261                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15262                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15263                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15264                    broadcastIntentLocked(null, null, intent,
15265                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15266                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15267                }
15268            }
15269        }
15270
15271        boolean kept = true;
15272        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15273        // mainStack is null during startup.
15274        if (mainStack != null) {
15275            if (changes != 0 && starting == null) {
15276                // If the configuration changed, and the caller is not already
15277                // in the process of starting an activity, then find the top
15278                // activity to check if its configuration needs to change.
15279                starting = mainStack.topRunningActivityLocked(null);
15280            }
15281
15282            if (starting != null) {
15283                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15284                // And we need to make sure at this point that all other activities
15285                // are made visible with the correct configuration.
15286                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15287            }
15288        }
15289
15290        if (values != null && mWindowManager != null) {
15291            mWindowManager.setNewConfiguration(mConfiguration);
15292        }
15293
15294        return kept;
15295    }
15296
15297    /**
15298     * Decide based on the configuration whether we should shouw the ANR,
15299     * crash, etc dialogs.  The idea is that if there is no affordnace to
15300     * press the on-screen buttons, we shouldn't show the dialog.
15301     *
15302     * A thought: SystemUI might also want to get told about this, the Power
15303     * dialog / global actions also might want different behaviors.
15304     */
15305    private static final boolean shouldShowDialogs(Configuration config) {
15306        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15307                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15308    }
15309
15310    /**
15311     * Save the locale.  You must be inside a synchronized (this) block.
15312     */
15313    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15314        if(isDiff) {
15315            SystemProperties.set("user.language", l.getLanguage());
15316            SystemProperties.set("user.region", l.getCountry());
15317        }
15318
15319        if(isPersist) {
15320            SystemProperties.set("persist.sys.language", l.getLanguage());
15321            SystemProperties.set("persist.sys.country", l.getCountry());
15322            SystemProperties.set("persist.sys.localevar", l.getVariant());
15323        }
15324    }
15325
15326    @Override
15327    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15328        ActivityRecord srec = ActivityRecord.forToken(token);
15329        return srec != null && srec.task.affinity != null &&
15330                srec.task.affinity.equals(destAffinity);
15331    }
15332
15333    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15334            Intent resultData) {
15335
15336        synchronized (this) {
15337            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15338            if (stack != null) {
15339                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15340            }
15341            return false;
15342        }
15343    }
15344
15345    public int getLaunchedFromUid(IBinder activityToken) {
15346        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15347        if (srec == null) {
15348            return -1;
15349        }
15350        return srec.launchedFromUid;
15351    }
15352
15353    public String getLaunchedFromPackage(IBinder activityToken) {
15354        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15355        if (srec == null) {
15356            return null;
15357        }
15358        return srec.launchedFromPackage;
15359    }
15360
15361    // =========================================================
15362    // LIFETIME MANAGEMENT
15363    // =========================================================
15364
15365    // Returns which broadcast queue the app is the current [or imminent] receiver
15366    // on, or 'null' if the app is not an active broadcast recipient.
15367    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15368        BroadcastRecord r = app.curReceiver;
15369        if (r != null) {
15370            return r.queue;
15371        }
15372
15373        // It's not the current receiver, but it might be starting up to become one
15374        synchronized (this) {
15375            for (BroadcastQueue queue : mBroadcastQueues) {
15376                r = queue.mPendingBroadcast;
15377                if (r != null && r.curApp == app) {
15378                    // found it; report which queue it's in
15379                    return queue;
15380                }
15381            }
15382        }
15383
15384        return null;
15385    }
15386
15387    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15388            boolean doingAll, long now) {
15389        if (mAdjSeq == app.adjSeq) {
15390            // This adjustment has already been computed.
15391            return app.curRawAdj;
15392        }
15393
15394        if (app.thread == null) {
15395            app.adjSeq = mAdjSeq;
15396            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15397            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15398            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15399        }
15400
15401        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15402        app.adjSource = null;
15403        app.adjTarget = null;
15404        app.empty = false;
15405        app.cached = false;
15406
15407        final int activitiesSize = app.activities.size();
15408
15409        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15410            // The max adjustment doesn't allow this app to be anything
15411            // below foreground, so it is not worth doing work for it.
15412            app.adjType = "fixed";
15413            app.adjSeq = mAdjSeq;
15414            app.curRawAdj = app.maxAdj;
15415            app.foregroundActivities = false;
15416            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15417            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15418            // System processes can do UI, and when they do we want to have
15419            // them trim their memory after the user leaves the UI.  To
15420            // facilitate this, here we need to determine whether or not it
15421            // is currently showing UI.
15422            app.systemNoUi = true;
15423            if (app == TOP_APP) {
15424                app.systemNoUi = false;
15425            } else if (activitiesSize > 0) {
15426                for (int j = 0; j < activitiesSize; j++) {
15427                    final ActivityRecord r = app.activities.get(j);
15428                    if (r.visible) {
15429                        app.systemNoUi = false;
15430                    }
15431                }
15432            }
15433            if (!app.systemNoUi) {
15434                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15435            }
15436            return (app.curAdj=app.maxAdj);
15437        }
15438
15439        app.systemNoUi = false;
15440
15441        // Determine the importance of the process, starting with most
15442        // important to least, and assign an appropriate OOM adjustment.
15443        int adj;
15444        int schedGroup;
15445        int procState;
15446        boolean foregroundActivities = false;
15447        BroadcastQueue queue;
15448        if (app == TOP_APP) {
15449            // The last app on the list is the foreground app.
15450            adj = ProcessList.FOREGROUND_APP_ADJ;
15451            schedGroup = Process.THREAD_GROUP_DEFAULT;
15452            app.adjType = "top-activity";
15453            foregroundActivities = true;
15454            procState = ActivityManager.PROCESS_STATE_TOP;
15455        } else if (app.instrumentationClass != null) {
15456            // Don't want to kill running instrumentation.
15457            adj = ProcessList.FOREGROUND_APP_ADJ;
15458            schedGroup = Process.THREAD_GROUP_DEFAULT;
15459            app.adjType = "instrumentation";
15460            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15461        } else if ((queue = isReceivingBroadcast(app)) != null) {
15462            // An app that is currently receiving a broadcast also
15463            // counts as being in the foreground for OOM killer purposes.
15464            // It's placed in a sched group based on the nature of the
15465            // broadcast as reflected by which queue it's active in.
15466            adj = ProcessList.FOREGROUND_APP_ADJ;
15467            schedGroup = (queue == mFgBroadcastQueue)
15468                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15469            app.adjType = "broadcast";
15470            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15471        } else if (app.executingServices.size() > 0) {
15472            // An app that is currently executing a service callback also
15473            // counts as being in the foreground.
15474            adj = ProcessList.FOREGROUND_APP_ADJ;
15475            schedGroup = app.execServicesFg ?
15476                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15477            app.adjType = "exec-service";
15478            procState = ActivityManager.PROCESS_STATE_SERVICE;
15479            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15480        } else {
15481            // As far as we know the process is empty.  We may change our mind later.
15482            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15483            // At this point we don't actually know the adjustment.  Use the cached adj
15484            // value that the caller wants us to.
15485            adj = cachedAdj;
15486            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15487            app.cached = true;
15488            app.empty = true;
15489            app.adjType = "cch-empty";
15490        }
15491
15492        // Examine all activities if not already foreground.
15493        if (!foregroundActivities && activitiesSize > 0) {
15494            for (int j = 0; j < activitiesSize; j++) {
15495                final ActivityRecord r = app.activities.get(j);
15496                if (r.app != app) {
15497                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15498                            + app + "?!?");
15499                    continue;
15500                }
15501                if (r.visible) {
15502                    // App has a visible activity; only upgrade adjustment.
15503                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15504                        adj = ProcessList.VISIBLE_APP_ADJ;
15505                        app.adjType = "visible";
15506                    }
15507                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15508                        procState = ActivityManager.PROCESS_STATE_TOP;
15509                    }
15510                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15511                    app.cached = false;
15512                    app.empty = false;
15513                    foregroundActivities = true;
15514                    break;
15515                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15516                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15517                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15518                        app.adjType = "pausing";
15519                    }
15520                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15521                        procState = ActivityManager.PROCESS_STATE_TOP;
15522                    }
15523                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15524                    app.cached = false;
15525                    app.empty = false;
15526                    foregroundActivities = true;
15527                } else if (r.state == ActivityState.STOPPING) {
15528                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15529                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15530                        app.adjType = "stopping";
15531                    }
15532                    // For the process state, we will at this point consider the
15533                    // process to be cached.  It will be cached either as an activity
15534                    // or empty depending on whether the activity is finishing.  We do
15535                    // this so that we can treat the process as cached for purposes of
15536                    // memory trimming (determing current memory level, trim command to
15537                    // send to process) since there can be an arbitrary number of stopping
15538                    // processes and they should soon all go into the cached state.
15539                    if (!r.finishing) {
15540                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15541                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15542                        }
15543                    }
15544                    app.cached = false;
15545                    app.empty = false;
15546                    foregroundActivities = true;
15547                } else {
15548                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15549                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15550                        app.adjType = "cch-act";
15551                    }
15552                }
15553            }
15554        }
15555
15556        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15557            if (app.foregroundServices) {
15558                // The user is aware of this app, so make it visible.
15559                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15560                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15561                app.cached = false;
15562                app.adjType = "fg-service";
15563                schedGroup = Process.THREAD_GROUP_DEFAULT;
15564            } else if (app.forcingToForeground != null) {
15565                // The user is aware of this app, so make it visible.
15566                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15567                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15568                app.cached = false;
15569                app.adjType = "force-fg";
15570                app.adjSource = app.forcingToForeground;
15571                schedGroup = Process.THREAD_GROUP_DEFAULT;
15572            }
15573        }
15574
15575        if (app == mHeavyWeightProcess) {
15576            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15577                // We don't want to kill the current heavy-weight process.
15578                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15579                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15580                app.cached = false;
15581                app.adjType = "heavy";
15582            }
15583            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15584                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15585            }
15586        }
15587
15588        if (app == mHomeProcess) {
15589            if (adj > ProcessList.HOME_APP_ADJ) {
15590                // This process is hosting what we currently consider to be the
15591                // home app, so we don't want to let it go into the background.
15592                adj = ProcessList.HOME_APP_ADJ;
15593                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15594                app.cached = false;
15595                app.adjType = "home";
15596            }
15597            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15598                procState = ActivityManager.PROCESS_STATE_HOME;
15599            }
15600        }
15601
15602        if (app == mPreviousProcess && app.activities.size() > 0) {
15603            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15604                // This was the previous process that showed UI to the user.
15605                // We want to try to keep it around more aggressively, to give
15606                // a good experience around switching between two apps.
15607                adj = ProcessList.PREVIOUS_APP_ADJ;
15608                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15609                app.cached = false;
15610                app.adjType = "previous";
15611            }
15612            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15613                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15614            }
15615        }
15616
15617        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15618                + " reason=" + app.adjType);
15619
15620        // By default, we use the computed adjustment.  It may be changed if
15621        // there are applications dependent on our services or providers, but
15622        // this gives us a baseline and makes sure we don't get into an
15623        // infinite recursion.
15624        app.adjSeq = mAdjSeq;
15625        app.curRawAdj = adj;
15626        app.hasStartedServices = false;
15627
15628        if (mBackupTarget != null && app == mBackupTarget.app) {
15629            // If possible we want to avoid killing apps while they're being backed up
15630            if (adj > ProcessList.BACKUP_APP_ADJ) {
15631                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15632                adj = ProcessList.BACKUP_APP_ADJ;
15633                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15634                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15635                }
15636                app.adjType = "backup";
15637                app.cached = false;
15638            }
15639            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15640                procState = ActivityManager.PROCESS_STATE_BACKUP;
15641            }
15642        }
15643
15644        boolean mayBeTop = false;
15645
15646        for (int is = app.services.size()-1;
15647                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15648                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15649                        || procState > ActivityManager.PROCESS_STATE_TOP);
15650                is--) {
15651            ServiceRecord s = app.services.valueAt(is);
15652            if (s.startRequested) {
15653                app.hasStartedServices = true;
15654                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15655                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15656                }
15657                if (app.hasShownUi && app != mHomeProcess) {
15658                    // If this process has shown some UI, let it immediately
15659                    // go to the LRU list because it may be pretty heavy with
15660                    // UI stuff.  We'll tag it with a label just to help
15661                    // debug and understand what is going on.
15662                    if (adj > ProcessList.SERVICE_ADJ) {
15663                        app.adjType = "cch-started-ui-services";
15664                    }
15665                } else {
15666                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15667                        // This service has seen some activity within
15668                        // recent memory, so we will keep its process ahead
15669                        // of the background processes.
15670                        if (adj > ProcessList.SERVICE_ADJ) {
15671                            adj = ProcessList.SERVICE_ADJ;
15672                            app.adjType = "started-services";
15673                            app.cached = false;
15674                        }
15675                    }
15676                    // If we have let the service slide into the background
15677                    // state, still have some text describing what it is doing
15678                    // even though the service no longer has an impact.
15679                    if (adj > ProcessList.SERVICE_ADJ) {
15680                        app.adjType = "cch-started-services";
15681                    }
15682                }
15683            }
15684            for (int conni = s.connections.size()-1;
15685                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15686                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15687                            || procState > ActivityManager.PROCESS_STATE_TOP);
15688                    conni--) {
15689                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15690                for (int i = 0;
15691                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15692                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15693                                || procState > ActivityManager.PROCESS_STATE_TOP);
15694                        i++) {
15695                    // XXX should compute this based on the max of
15696                    // all connected clients.
15697                    ConnectionRecord cr = clist.get(i);
15698                    if (cr.binding.client == app) {
15699                        // Binding to ourself is not interesting.
15700                        continue;
15701                    }
15702                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15703                        ProcessRecord client = cr.binding.client;
15704                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15705                                TOP_APP, doingAll, now);
15706                        int clientProcState = client.curProcState;
15707                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15708                            // If the other app is cached for any reason, for purposes here
15709                            // we are going to consider it empty.  The specific cached state
15710                            // doesn't propagate except under certain conditions.
15711                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15712                        }
15713                        String adjType = null;
15714                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15715                            // Not doing bind OOM management, so treat
15716                            // this guy more like a started service.
15717                            if (app.hasShownUi && app != mHomeProcess) {
15718                                // If this process has shown some UI, let it immediately
15719                                // go to the LRU list because it may be pretty heavy with
15720                                // UI stuff.  We'll tag it with a label just to help
15721                                // debug and understand what is going on.
15722                                if (adj > clientAdj) {
15723                                    adjType = "cch-bound-ui-services";
15724                                }
15725                                app.cached = false;
15726                                clientAdj = adj;
15727                                clientProcState = procState;
15728                            } else {
15729                                if (now >= (s.lastActivity
15730                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15731                                    // This service has not seen activity within
15732                                    // recent memory, so allow it to drop to the
15733                                    // LRU list if there is no other reason to keep
15734                                    // it around.  We'll also tag it with a label just
15735                                    // to help debug and undertand what is going on.
15736                                    if (adj > clientAdj) {
15737                                        adjType = "cch-bound-services";
15738                                    }
15739                                    clientAdj = adj;
15740                                }
15741                            }
15742                        }
15743                        if (adj > clientAdj) {
15744                            // If this process has recently shown UI, and
15745                            // the process that is binding to it is less
15746                            // important than being visible, then we don't
15747                            // care about the binding as much as we care
15748                            // about letting this process get into the LRU
15749                            // list to be killed and restarted if needed for
15750                            // memory.
15751                            if (app.hasShownUi && app != mHomeProcess
15752                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15753                                adjType = "cch-bound-ui-services";
15754                            } else {
15755                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15756                                        |Context.BIND_IMPORTANT)) != 0) {
15757                                    adj = clientAdj;
15758                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15759                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15760                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15761                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15762                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15763                                    adj = clientAdj;
15764                                } else {
15765                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15766                                        adj = ProcessList.VISIBLE_APP_ADJ;
15767                                    }
15768                                }
15769                                if (!client.cached) {
15770                                    app.cached = false;
15771                                }
15772                                adjType = "service";
15773                            }
15774                        }
15775                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15776                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15777                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15778                            }
15779                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15780                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15781                                    // Special handling of clients who are in the top state.
15782                                    // We *may* want to consider this process to be in the
15783                                    // top state as well, but only if there is not another
15784                                    // reason for it to be running.  Being on the top is a
15785                                    // special state, meaning you are specifically running
15786                                    // for the current top app.  If the process is already
15787                                    // running in the background for some other reason, it
15788                                    // is more important to continue considering it to be
15789                                    // in the background state.
15790                                    mayBeTop = true;
15791                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15792                                } else {
15793                                    // Special handling for above-top states (persistent
15794                                    // processes).  These should not bring the current process
15795                                    // into the top state, since they are not on top.  Instead
15796                                    // give them the best state after that.
15797                                    clientProcState =
15798                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15799                                }
15800                            }
15801                        } else {
15802                            if (clientProcState <
15803                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15804                                clientProcState =
15805                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15806                            }
15807                        }
15808                        if (procState > clientProcState) {
15809                            procState = clientProcState;
15810                        }
15811                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15812                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15813                            app.pendingUiClean = true;
15814                        }
15815                        if (adjType != null) {
15816                            app.adjType = adjType;
15817                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15818                                    .REASON_SERVICE_IN_USE;
15819                            app.adjSource = cr.binding.client;
15820                            app.adjSourceProcState = clientProcState;
15821                            app.adjTarget = s.name;
15822                        }
15823                    }
15824                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15825                        app.treatLikeActivity = true;
15826                    }
15827                    final ActivityRecord a = cr.activity;
15828                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15829                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15830                                (a.visible || a.state == ActivityState.RESUMED
15831                                 || a.state == ActivityState.PAUSING)) {
15832                            adj = ProcessList.FOREGROUND_APP_ADJ;
15833                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15834                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15835                            }
15836                            app.cached = false;
15837                            app.adjType = "service";
15838                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15839                                    .REASON_SERVICE_IN_USE;
15840                            app.adjSource = a;
15841                            app.adjSourceProcState = procState;
15842                            app.adjTarget = s.name;
15843                        }
15844                    }
15845                }
15846            }
15847        }
15848
15849        for (int provi = app.pubProviders.size()-1;
15850                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15851                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15852                        || procState > ActivityManager.PROCESS_STATE_TOP);
15853                provi--) {
15854            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15855            for (int i = cpr.connections.size()-1;
15856                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15857                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15858                            || procState > ActivityManager.PROCESS_STATE_TOP);
15859                    i--) {
15860                ContentProviderConnection conn = cpr.connections.get(i);
15861                ProcessRecord client = conn.client;
15862                if (client == app) {
15863                    // Being our own client is not interesting.
15864                    continue;
15865                }
15866                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15867                int clientProcState = client.curProcState;
15868                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15869                    // If the other app is cached for any reason, for purposes here
15870                    // we are going to consider it empty.
15871                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15872                }
15873                if (adj > clientAdj) {
15874                    if (app.hasShownUi && app != mHomeProcess
15875                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15876                        app.adjType = "cch-ui-provider";
15877                    } else {
15878                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15879                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15880                        app.adjType = "provider";
15881                    }
15882                    app.cached &= client.cached;
15883                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15884                            .REASON_PROVIDER_IN_USE;
15885                    app.adjSource = client;
15886                    app.adjSourceProcState = clientProcState;
15887                    app.adjTarget = cpr.name;
15888                }
15889                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15890                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15891                        // Special handling of clients who are in the top state.
15892                        // We *may* want to consider this process to be in the
15893                        // top state as well, but only if there is not another
15894                        // reason for it to be running.  Being on the top is a
15895                        // special state, meaning you are specifically running
15896                        // for the current top app.  If the process is already
15897                        // running in the background for some other reason, it
15898                        // is more important to continue considering it to be
15899                        // in the background state.
15900                        mayBeTop = true;
15901                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15902                    } else {
15903                        // Special handling for above-top states (persistent
15904                        // processes).  These should not bring the current process
15905                        // into the top state, since they are not on top.  Instead
15906                        // give them the best state after that.
15907                        clientProcState =
15908                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15909                    }
15910                }
15911                if (procState > clientProcState) {
15912                    procState = clientProcState;
15913                }
15914                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15915                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15916                }
15917            }
15918            // If the provider has external (non-framework) process
15919            // dependencies, ensure that its adjustment is at least
15920            // FOREGROUND_APP_ADJ.
15921            if (cpr.hasExternalProcessHandles()) {
15922                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15923                    adj = ProcessList.FOREGROUND_APP_ADJ;
15924                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15925                    app.cached = false;
15926                    app.adjType = "provider";
15927                    app.adjTarget = cpr.name;
15928                }
15929                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15930                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15931                }
15932            }
15933        }
15934
15935        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15936            // A client of one of our services or providers is in the top state.  We
15937            // *may* want to be in the top state, but not if we are already running in
15938            // the background for some other reason.  For the decision here, we are going
15939            // to pick out a few specific states that we want to remain in when a client
15940            // is top (states that tend to be longer-term) and otherwise allow it to go
15941            // to the top state.
15942            switch (procState) {
15943                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15944                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15945                case ActivityManager.PROCESS_STATE_SERVICE:
15946                    // These all are longer-term states, so pull them up to the top
15947                    // of the background states, but not all the way to the top state.
15948                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15949                    break;
15950                default:
15951                    // Otherwise, top is a better choice, so take it.
15952                    procState = ActivityManager.PROCESS_STATE_TOP;
15953                    break;
15954            }
15955        }
15956
15957        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15958            if (app.hasClientActivities) {
15959                // This is a cached process, but with client activities.  Mark it so.
15960                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15961                app.adjType = "cch-client-act";
15962            } else if (app.treatLikeActivity) {
15963                // This is a cached process, but somebody wants us to treat it like it has
15964                // an activity, okay!
15965                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15966                app.adjType = "cch-as-act";
15967            }
15968        }
15969
15970        if (adj == ProcessList.SERVICE_ADJ) {
15971            if (doingAll) {
15972                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15973                mNewNumServiceProcs++;
15974                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15975                if (!app.serviceb) {
15976                    // This service isn't far enough down on the LRU list to
15977                    // normally be a B service, but if we are low on RAM and it
15978                    // is large we want to force it down since we would prefer to
15979                    // keep launcher over it.
15980                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15981                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15982                        app.serviceHighRam = true;
15983                        app.serviceb = true;
15984                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15985                    } else {
15986                        mNewNumAServiceProcs++;
15987                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15988                    }
15989                } else {
15990                    app.serviceHighRam = false;
15991                }
15992            }
15993            if (app.serviceb) {
15994                adj = ProcessList.SERVICE_B_ADJ;
15995            }
15996        }
15997
15998        app.curRawAdj = adj;
15999
16000        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16001        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16002        if (adj > app.maxAdj) {
16003            adj = app.maxAdj;
16004            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16005                schedGroup = Process.THREAD_GROUP_DEFAULT;
16006            }
16007        }
16008
16009        // Do final modification to adj.  Everything we do between here and applying
16010        // the final setAdj must be done in this function, because we will also use
16011        // it when computing the final cached adj later.  Note that we don't need to
16012        // worry about this for max adj above, since max adj will always be used to
16013        // keep it out of the cached vaues.
16014        app.curAdj = app.modifyRawOomAdj(adj);
16015        app.curSchedGroup = schedGroup;
16016        app.curProcState = procState;
16017        app.foregroundActivities = foregroundActivities;
16018
16019        return app.curRawAdj;
16020    }
16021
16022    /**
16023     * Schedule PSS collection of a process.
16024     */
16025    void requestPssLocked(ProcessRecord proc, int procState) {
16026        if (mPendingPssProcesses.contains(proc)) {
16027            return;
16028        }
16029        if (mPendingPssProcesses.size() == 0) {
16030            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16031        }
16032        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16033        proc.pssProcState = procState;
16034        mPendingPssProcesses.add(proc);
16035    }
16036
16037    /**
16038     * Schedule PSS collection of all processes.
16039     */
16040    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16041        if (!always) {
16042            if (now < (mLastFullPssTime +
16043                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16044                return;
16045            }
16046        }
16047        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16048        mLastFullPssTime = now;
16049        mFullPssPending = true;
16050        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16051        mPendingPssProcesses.clear();
16052        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16053            ProcessRecord app = mLruProcesses.get(i);
16054            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16055                app.pssProcState = app.setProcState;
16056                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16057                        isSleeping(), now);
16058                mPendingPssProcesses.add(app);
16059            }
16060        }
16061        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16062    }
16063
16064    /**
16065     * Ask a given process to GC right now.
16066     */
16067    final void performAppGcLocked(ProcessRecord app) {
16068        try {
16069            app.lastRequestedGc = SystemClock.uptimeMillis();
16070            if (app.thread != null) {
16071                if (app.reportLowMemory) {
16072                    app.reportLowMemory = false;
16073                    app.thread.scheduleLowMemory();
16074                } else {
16075                    app.thread.processInBackground();
16076                }
16077            }
16078        } catch (Exception e) {
16079            // whatever.
16080        }
16081    }
16082
16083    /**
16084     * Returns true if things are idle enough to perform GCs.
16085     */
16086    private final boolean canGcNowLocked() {
16087        boolean processingBroadcasts = false;
16088        for (BroadcastQueue q : mBroadcastQueues) {
16089            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16090                processingBroadcasts = true;
16091            }
16092        }
16093        return !processingBroadcasts
16094                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16095    }
16096
16097    /**
16098     * Perform GCs on all processes that are waiting for it, but only
16099     * if things are idle.
16100     */
16101    final void performAppGcsLocked() {
16102        final int N = mProcessesToGc.size();
16103        if (N <= 0) {
16104            return;
16105        }
16106        if (canGcNowLocked()) {
16107            while (mProcessesToGc.size() > 0) {
16108                ProcessRecord proc = mProcessesToGc.remove(0);
16109                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16110                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16111                            <= SystemClock.uptimeMillis()) {
16112                        // To avoid spamming the system, we will GC processes one
16113                        // at a time, waiting a few seconds between each.
16114                        performAppGcLocked(proc);
16115                        scheduleAppGcsLocked();
16116                        return;
16117                    } else {
16118                        // It hasn't been long enough since we last GCed this
16119                        // process...  put it in the list to wait for its time.
16120                        addProcessToGcListLocked(proc);
16121                        break;
16122                    }
16123                }
16124            }
16125
16126            scheduleAppGcsLocked();
16127        }
16128    }
16129
16130    /**
16131     * If all looks good, perform GCs on all processes waiting for them.
16132     */
16133    final void performAppGcsIfAppropriateLocked() {
16134        if (canGcNowLocked()) {
16135            performAppGcsLocked();
16136            return;
16137        }
16138        // Still not idle, wait some more.
16139        scheduleAppGcsLocked();
16140    }
16141
16142    /**
16143     * Schedule the execution of all pending app GCs.
16144     */
16145    final void scheduleAppGcsLocked() {
16146        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16147
16148        if (mProcessesToGc.size() > 0) {
16149            // Schedule a GC for the time to the next process.
16150            ProcessRecord proc = mProcessesToGc.get(0);
16151            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16152
16153            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16154            long now = SystemClock.uptimeMillis();
16155            if (when < (now+GC_TIMEOUT)) {
16156                when = now + GC_TIMEOUT;
16157            }
16158            mHandler.sendMessageAtTime(msg, when);
16159        }
16160    }
16161
16162    /**
16163     * Add a process to the array of processes waiting to be GCed.  Keeps the
16164     * list in sorted order by the last GC time.  The process can't already be
16165     * on the list.
16166     */
16167    final void addProcessToGcListLocked(ProcessRecord proc) {
16168        boolean added = false;
16169        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16170            if (mProcessesToGc.get(i).lastRequestedGc <
16171                    proc.lastRequestedGc) {
16172                added = true;
16173                mProcessesToGc.add(i+1, proc);
16174                break;
16175            }
16176        }
16177        if (!added) {
16178            mProcessesToGc.add(0, proc);
16179        }
16180    }
16181
16182    /**
16183     * Set up to ask a process to GC itself.  This will either do it
16184     * immediately, or put it on the list of processes to gc the next
16185     * time things are idle.
16186     */
16187    final void scheduleAppGcLocked(ProcessRecord app) {
16188        long now = SystemClock.uptimeMillis();
16189        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16190            return;
16191        }
16192        if (!mProcessesToGc.contains(app)) {
16193            addProcessToGcListLocked(app);
16194            scheduleAppGcsLocked();
16195        }
16196    }
16197
16198    final void checkExcessivePowerUsageLocked(boolean doKills) {
16199        updateCpuStatsNow();
16200
16201        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16202        boolean doWakeKills = doKills;
16203        boolean doCpuKills = doKills;
16204        if (mLastPowerCheckRealtime == 0) {
16205            doWakeKills = false;
16206        }
16207        if (mLastPowerCheckUptime == 0) {
16208            doCpuKills = false;
16209        }
16210        if (stats.isScreenOn()) {
16211            doWakeKills = false;
16212        }
16213        final long curRealtime = SystemClock.elapsedRealtime();
16214        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16215        final long curUptime = SystemClock.uptimeMillis();
16216        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16217        mLastPowerCheckRealtime = curRealtime;
16218        mLastPowerCheckUptime = curUptime;
16219        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16220            doWakeKills = false;
16221        }
16222        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16223            doCpuKills = false;
16224        }
16225        int i = mLruProcesses.size();
16226        while (i > 0) {
16227            i--;
16228            ProcessRecord app = mLruProcesses.get(i);
16229            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16230                long wtime;
16231                synchronized (stats) {
16232                    wtime = stats.getProcessWakeTime(app.info.uid,
16233                            app.pid, curRealtime);
16234                }
16235                long wtimeUsed = wtime - app.lastWakeTime;
16236                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16237                if (DEBUG_POWER) {
16238                    StringBuilder sb = new StringBuilder(128);
16239                    sb.append("Wake for ");
16240                    app.toShortString(sb);
16241                    sb.append(": over ");
16242                    TimeUtils.formatDuration(realtimeSince, sb);
16243                    sb.append(" used ");
16244                    TimeUtils.formatDuration(wtimeUsed, sb);
16245                    sb.append(" (");
16246                    sb.append((wtimeUsed*100)/realtimeSince);
16247                    sb.append("%)");
16248                    Slog.i(TAG, sb.toString());
16249                    sb.setLength(0);
16250                    sb.append("CPU for ");
16251                    app.toShortString(sb);
16252                    sb.append(": over ");
16253                    TimeUtils.formatDuration(uptimeSince, sb);
16254                    sb.append(" used ");
16255                    TimeUtils.formatDuration(cputimeUsed, sb);
16256                    sb.append(" (");
16257                    sb.append((cputimeUsed*100)/uptimeSince);
16258                    sb.append("%)");
16259                    Slog.i(TAG, sb.toString());
16260                }
16261                // If a process has held a wake lock for more
16262                // than 50% of the time during this period,
16263                // that sounds bad.  Kill!
16264                if (doWakeKills && realtimeSince > 0
16265                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16266                    synchronized (stats) {
16267                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16268                                realtimeSince, wtimeUsed);
16269                    }
16270                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16271                            + " during " + realtimeSince);
16272                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16273                } else if (doCpuKills && uptimeSince > 0
16274                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16275                    synchronized (stats) {
16276                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16277                                uptimeSince, cputimeUsed);
16278                    }
16279                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16280                            + " during " + uptimeSince);
16281                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16282                } else {
16283                    app.lastWakeTime = wtime;
16284                    app.lastCpuTime = app.curCpuTime;
16285                }
16286            }
16287        }
16288    }
16289
16290    private final boolean applyOomAdjLocked(ProcessRecord app,
16291            ProcessRecord TOP_APP, boolean doingAll, long now) {
16292        boolean success = true;
16293
16294        if (app.curRawAdj != app.setRawAdj) {
16295            app.setRawAdj = app.curRawAdj;
16296        }
16297
16298        int changes = 0;
16299
16300        if (app.curAdj != app.setAdj) {
16301            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16302            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16303                TAG, "Set " + app.pid + " " + app.processName +
16304                " adj " + app.curAdj + ": " + app.adjType);
16305            app.setAdj = app.curAdj;
16306        }
16307
16308        if (app.setSchedGroup != app.curSchedGroup) {
16309            app.setSchedGroup = app.curSchedGroup;
16310            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16311                    "Setting process group of " + app.processName
16312                    + " to " + app.curSchedGroup);
16313            if (app.waitingToKill != null &&
16314                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16315                killUnneededProcessLocked(app, app.waitingToKill);
16316                success = false;
16317            } else {
16318                if (true) {
16319                    long oldId = Binder.clearCallingIdentity();
16320                    try {
16321                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16322                    } catch (Exception e) {
16323                        Slog.w(TAG, "Failed setting process group of " + app.pid
16324                                + " to " + app.curSchedGroup);
16325                        e.printStackTrace();
16326                    } finally {
16327                        Binder.restoreCallingIdentity(oldId);
16328                    }
16329                } else {
16330                    if (app.thread != null) {
16331                        try {
16332                            app.thread.setSchedulingGroup(app.curSchedGroup);
16333                        } catch (RemoteException e) {
16334                        }
16335                    }
16336                }
16337                Process.setSwappiness(app.pid,
16338                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16339            }
16340        }
16341        if (app.repForegroundActivities != app.foregroundActivities) {
16342            app.repForegroundActivities = app.foregroundActivities;
16343            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16344        }
16345        if (app.repProcState != app.curProcState) {
16346            app.repProcState = app.curProcState;
16347            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16348            if (app.thread != null) {
16349                try {
16350                    if (false) {
16351                        //RuntimeException h = new RuntimeException("here");
16352                        Slog.i(TAG, "Sending new process state " + app.repProcState
16353                                + " to " + app /*, h*/);
16354                    }
16355                    app.thread.setProcessState(app.repProcState);
16356                } catch (RemoteException e) {
16357                }
16358            }
16359        }
16360        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16361                app.setProcState)) {
16362            app.lastStateTime = now;
16363            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16364                    isSleeping(), now);
16365            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16366                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16367                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16368                    + (app.nextPssTime-now) + ": " + app);
16369        } else {
16370            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16371                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16372                requestPssLocked(app, app.setProcState);
16373                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16374                        isSleeping(), now);
16375            } else if (false && DEBUG_PSS) {
16376                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16377            }
16378        }
16379        if (app.setProcState != app.curProcState) {
16380            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16381                    "Proc state change of " + app.processName
16382                    + " to " + app.curProcState);
16383            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16384            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16385            if (setImportant && !curImportant) {
16386                // This app is no longer something we consider important enough to allow to
16387                // use arbitrary amounts of battery power.  Note
16388                // its current wake lock time to later know to kill it if
16389                // it is not behaving well.
16390                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16391                synchronized (stats) {
16392                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16393                            app.pid, SystemClock.elapsedRealtime());
16394                }
16395                app.lastCpuTime = app.curCpuTime;
16396
16397            }
16398            app.setProcState = app.curProcState;
16399            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16400                app.notCachedSinceIdle = false;
16401            }
16402            if (!doingAll) {
16403                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16404            } else {
16405                app.procStateChanged = true;
16406            }
16407        }
16408
16409        if (changes != 0) {
16410            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16411            int i = mPendingProcessChanges.size()-1;
16412            ProcessChangeItem item = null;
16413            while (i >= 0) {
16414                item = mPendingProcessChanges.get(i);
16415                if (item.pid == app.pid) {
16416                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16417                    break;
16418                }
16419                i--;
16420            }
16421            if (i < 0) {
16422                // No existing item in pending changes; need a new one.
16423                final int NA = mAvailProcessChanges.size();
16424                if (NA > 0) {
16425                    item = mAvailProcessChanges.remove(NA-1);
16426                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16427                } else {
16428                    item = new ProcessChangeItem();
16429                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16430                }
16431                item.changes = 0;
16432                item.pid = app.pid;
16433                item.uid = app.info.uid;
16434                if (mPendingProcessChanges.size() == 0) {
16435                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16436                            "*** Enqueueing dispatch processes changed!");
16437                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16438                }
16439                mPendingProcessChanges.add(item);
16440            }
16441            item.changes |= changes;
16442            item.processState = app.repProcState;
16443            item.foregroundActivities = app.repForegroundActivities;
16444            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16445                    + Integer.toHexString(System.identityHashCode(item))
16446                    + " " + app.toShortString() + ": changes=" + item.changes
16447                    + " procState=" + item.processState
16448                    + " foreground=" + item.foregroundActivities
16449                    + " type=" + app.adjType + " source=" + app.adjSource
16450                    + " target=" + app.adjTarget);
16451        }
16452
16453        return success;
16454    }
16455
16456    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16457        if (proc.thread != null) {
16458            if (proc.baseProcessTracker != null) {
16459                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16460            }
16461            if (proc.repProcState >= 0) {
16462                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16463                        proc.repProcState);
16464            }
16465        }
16466    }
16467
16468    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16469            ProcessRecord TOP_APP, boolean doingAll, long now) {
16470        if (app.thread == null) {
16471            return false;
16472        }
16473
16474        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16475
16476        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16477    }
16478
16479    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16480            boolean oomAdj) {
16481        if (isForeground != proc.foregroundServices) {
16482            proc.foregroundServices = isForeground;
16483            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16484                    proc.info.uid);
16485            if (isForeground) {
16486                if (curProcs == null) {
16487                    curProcs = new ArrayList<ProcessRecord>();
16488                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16489                }
16490                if (!curProcs.contains(proc)) {
16491                    curProcs.add(proc);
16492                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16493                            proc.info.packageName, proc.info.uid);
16494                }
16495            } else {
16496                if (curProcs != null) {
16497                    if (curProcs.remove(proc)) {
16498                        mBatteryStatsService.noteEvent(
16499                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16500                                proc.info.packageName, proc.info.uid);
16501                        if (curProcs.size() <= 0) {
16502                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16503                        }
16504                    }
16505                }
16506            }
16507            if (oomAdj) {
16508                updateOomAdjLocked();
16509            }
16510        }
16511    }
16512
16513    private final ActivityRecord resumedAppLocked() {
16514        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16515        String pkg;
16516        int uid;
16517        if (act != null) {
16518            pkg = act.packageName;
16519            uid = act.info.applicationInfo.uid;
16520        } else {
16521            pkg = null;
16522            uid = -1;
16523        }
16524        // Has the UID or resumed package name changed?
16525        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16526                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16527            if (mCurResumedPackage != null) {
16528                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16529                        mCurResumedPackage, mCurResumedUid);
16530            }
16531            mCurResumedPackage = pkg;
16532            mCurResumedUid = uid;
16533            if (mCurResumedPackage != null) {
16534                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16535                        mCurResumedPackage, mCurResumedUid);
16536            }
16537        }
16538        return act;
16539    }
16540
16541    final boolean updateOomAdjLocked(ProcessRecord app) {
16542        final ActivityRecord TOP_ACT = resumedAppLocked();
16543        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16544        final boolean wasCached = app.cached;
16545
16546        mAdjSeq++;
16547
16548        // This is the desired cached adjusment we want to tell it to use.
16549        // If our app is currently cached, we know it, and that is it.  Otherwise,
16550        // we don't know it yet, and it needs to now be cached we will then
16551        // need to do a complete oom adj.
16552        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16553                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16554        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16555                SystemClock.uptimeMillis());
16556        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16557            // Changed to/from cached state, so apps after it in the LRU
16558            // list may also be changed.
16559            updateOomAdjLocked();
16560        }
16561        return success;
16562    }
16563
16564    final void updateOomAdjLocked() {
16565        final ActivityRecord TOP_ACT = resumedAppLocked();
16566        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16567        final long now = SystemClock.uptimeMillis();
16568        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16569        final int N = mLruProcesses.size();
16570
16571        if (false) {
16572            RuntimeException e = new RuntimeException();
16573            e.fillInStackTrace();
16574            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16575        }
16576
16577        mAdjSeq++;
16578        mNewNumServiceProcs = 0;
16579        mNewNumAServiceProcs = 0;
16580
16581        final int emptyProcessLimit;
16582        final int cachedProcessLimit;
16583        if (mProcessLimit <= 0) {
16584            emptyProcessLimit = cachedProcessLimit = 0;
16585        } else if (mProcessLimit == 1) {
16586            emptyProcessLimit = 1;
16587            cachedProcessLimit = 0;
16588        } else {
16589            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16590            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16591        }
16592
16593        // Let's determine how many processes we have running vs.
16594        // how many slots we have for background processes; we may want
16595        // to put multiple processes in a slot of there are enough of
16596        // them.
16597        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16598                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16599        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16600        if (numEmptyProcs > cachedProcessLimit) {
16601            // If there are more empty processes than our limit on cached
16602            // processes, then use the cached process limit for the factor.
16603            // This ensures that the really old empty processes get pushed
16604            // down to the bottom, so if we are running low on memory we will
16605            // have a better chance at keeping around more cached processes
16606            // instead of a gazillion empty processes.
16607            numEmptyProcs = cachedProcessLimit;
16608        }
16609        int emptyFactor = numEmptyProcs/numSlots;
16610        if (emptyFactor < 1) emptyFactor = 1;
16611        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16612        if (cachedFactor < 1) cachedFactor = 1;
16613        int stepCached = 0;
16614        int stepEmpty = 0;
16615        int numCached = 0;
16616        int numEmpty = 0;
16617        int numTrimming = 0;
16618
16619        mNumNonCachedProcs = 0;
16620        mNumCachedHiddenProcs = 0;
16621
16622        // First update the OOM adjustment for each of the
16623        // application processes based on their current state.
16624        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16625        int nextCachedAdj = curCachedAdj+1;
16626        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16627        int nextEmptyAdj = curEmptyAdj+2;
16628        for (int i=N-1; i>=0; i--) {
16629            ProcessRecord app = mLruProcesses.get(i);
16630            if (!app.killedByAm && app.thread != null) {
16631                app.procStateChanged = false;
16632                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16633
16634                // If we haven't yet assigned the final cached adj
16635                // to the process, do that now.
16636                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16637                    switch (app.curProcState) {
16638                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16639                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16640                            // This process is a cached process holding activities...
16641                            // assign it the next cached value for that type, and then
16642                            // step that cached level.
16643                            app.curRawAdj = curCachedAdj;
16644                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16645                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16646                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16647                                    + ")");
16648                            if (curCachedAdj != nextCachedAdj) {
16649                                stepCached++;
16650                                if (stepCached >= cachedFactor) {
16651                                    stepCached = 0;
16652                                    curCachedAdj = nextCachedAdj;
16653                                    nextCachedAdj += 2;
16654                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16655                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16656                                    }
16657                                }
16658                            }
16659                            break;
16660                        default:
16661                            // For everything else, assign next empty cached process
16662                            // level and bump that up.  Note that this means that
16663                            // long-running services that have dropped down to the
16664                            // cached level will be treated as empty (since their process
16665                            // state is still as a service), which is what we want.
16666                            app.curRawAdj = curEmptyAdj;
16667                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16668                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16669                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16670                                    + ")");
16671                            if (curEmptyAdj != nextEmptyAdj) {
16672                                stepEmpty++;
16673                                if (stepEmpty >= emptyFactor) {
16674                                    stepEmpty = 0;
16675                                    curEmptyAdj = nextEmptyAdj;
16676                                    nextEmptyAdj += 2;
16677                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16678                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16679                                    }
16680                                }
16681                            }
16682                            break;
16683                    }
16684                }
16685
16686                applyOomAdjLocked(app, TOP_APP, true, now);
16687
16688                // Count the number of process types.
16689                switch (app.curProcState) {
16690                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16691                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16692                        mNumCachedHiddenProcs++;
16693                        numCached++;
16694                        if (numCached > cachedProcessLimit) {
16695                            killUnneededProcessLocked(app, "cached #" + numCached);
16696                        }
16697                        break;
16698                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16699                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16700                                && app.lastActivityTime < oldTime) {
16701                            killUnneededProcessLocked(app, "empty for "
16702                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16703                                    / 1000) + "s");
16704                        } else {
16705                            numEmpty++;
16706                            if (numEmpty > emptyProcessLimit) {
16707                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16708                            }
16709                        }
16710                        break;
16711                    default:
16712                        mNumNonCachedProcs++;
16713                        break;
16714                }
16715
16716                if (app.isolated && app.services.size() <= 0) {
16717                    // If this is an isolated process, and there are no
16718                    // services running in it, then the process is no longer
16719                    // needed.  We agressively kill these because we can by
16720                    // definition not re-use the same process again, and it is
16721                    // good to avoid having whatever code was running in them
16722                    // left sitting around after no longer needed.
16723                    killUnneededProcessLocked(app, "isolated not needed");
16724                }
16725
16726                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16727                        && !app.killedByAm) {
16728                    numTrimming++;
16729                }
16730            }
16731        }
16732
16733        mNumServiceProcs = mNewNumServiceProcs;
16734
16735        // Now determine the memory trimming level of background processes.
16736        // Unfortunately we need to start at the back of the list to do this
16737        // properly.  We only do this if the number of background apps we
16738        // are managing to keep around is less than half the maximum we desire;
16739        // if we are keeping a good number around, we'll let them use whatever
16740        // memory they want.
16741        final int numCachedAndEmpty = numCached + numEmpty;
16742        int memFactor;
16743        if (numCached <= ProcessList.TRIM_CACHED_APPS
16744                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16745            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16746                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16747            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16748                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16749            } else {
16750                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16751            }
16752        } else {
16753            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16754        }
16755        // We always allow the memory level to go up (better).  We only allow it to go
16756        // down if we are in a state where that is allowed, *and* the total number of processes
16757        // has gone down since last time.
16758        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16759                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16760                + " last=" + mLastNumProcesses);
16761        if (memFactor > mLastMemoryLevel) {
16762            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16763                memFactor = mLastMemoryLevel;
16764                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16765            }
16766        }
16767        mLastMemoryLevel = memFactor;
16768        mLastNumProcesses = mLruProcesses.size();
16769        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16770        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16771        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16772            if (mLowRamStartTime == 0) {
16773                mLowRamStartTime = now;
16774            }
16775            int step = 0;
16776            int fgTrimLevel;
16777            switch (memFactor) {
16778                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16779                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16780                    break;
16781                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16782                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16783                    break;
16784                default:
16785                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16786                    break;
16787            }
16788            int factor = numTrimming/3;
16789            int minFactor = 2;
16790            if (mHomeProcess != null) minFactor++;
16791            if (mPreviousProcess != null) minFactor++;
16792            if (factor < minFactor) factor = minFactor;
16793            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16794            for (int i=N-1; i>=0; i--) {
16795                ProcessRecord app = mLruProcesses.get(i);
16796                if (allChanged || app.procStateChanged) {
16797                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16798                    app.procStateChanged = false;
16799                }
16800                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16801                        && !app.killedByAm) {
16802                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16803                        try {
16804                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16805                                    "Trimming memory of " + app.processName
16806                                    + " to " + curLevel);
16807                            app.thread.scheduleTrimMemory(curLevel);
16808                        } catch (RemoteException e) {
16809                        }
16810                        if (false) {
16811                            // For now we won't do this; our memory trimming seems
16812                            // to be good enough at this point that destroying
16813                            // activities causes more harm than good.
16814                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16815                                    && app != mHomeProcess && app != mPreviousProcess) {
16816                                // Need to do this on its own message because the stack may not
16817                                // be in a consistent state at this point.
16818                                // For these apps we will also finish their activities
16819                                // to help them free memory.
16820                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16821                            }
16822                        }
16823                    }
16824                    app.trimMemoryLevel = curLevel;
16825                    step++;
16826                    if (step >= factor) {
16827                        step = 0;
16828                        switch (curLevel) {
16829                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16830                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16831                                break;
16832                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16833                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16834                                break;
16835                        }
16836                    }
16837                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16838                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16839                            && app.thread != null) {
16840                        try {
16841                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16842                                    "Trimming memory of heavy-weight " + app.processName
16843                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16844                            app.thread.scheduleTrimMemory(
16845                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16846                        } catch (RemoteException e) {
16847                        }
16848                    }
16849                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16850                } else {
16851                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16852                            || app.systemNoUi) && app.pendingUiClean) {
16853                        // If this application is now in the background and it
16854                        // had done UI, then give it the special trim level to
16855                        // have it free UI resources.
16856                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16857                        if (app.trimMemoryLevel < level && app.thread != null) {
16858                            try {
16859                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16860                                        "Trimming memory of bg-ui " + app.processName
16861                                        + " to " + level);
16862                                app.thread.scheduleTrimMemory(level);
16863                            } catch (RemoteException e) {
16864                            }
16865                        }
16866                        app.pendingUiClean = false;
16867                    }
16868                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16869                        try {
16870                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16871                                    "Trimming memory of fg " + app.processName
16872                                    + " to " + fgTrimLevel);
16873                            app.thread.scheduleTrimMemory(fgTrimLevel);
16874                        } catch (RemoteException e) {
16875                        }
16876                    }
16877                    app.trimMemoryLevel = fgTrimLevel;
16878                }
16879            }
16880        } else {
16881            if (mLowRamStartTime != 0) {
16882                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16883                mLowRamStartTime = 0;
16884            }
16885            for (int i=N-1; i>=0; i--) {
16886                ProcessRecord app = mLruProcesses.get(i);
16887                if (allChanged || app.procStateChanged) {
16888                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16889                    app.procStateChanged = false;
16890                }
16891                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16892                        || app.systemNoUi) && app.pendingUiClean) {
16893                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16894                            && app.thread != null) {
16895                        try {
16896                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16897                                    "Trimming memory of ui hidden " + app.processName
16898                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16899                            app.thread.scheduleTrimMemory(
16900                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16901                        } catch (RemoteException e) {
16902                        }
16903                    }
16904                    app.pendingUiClean = false;
16905                }
16906                app.trimMemoryLevel = 0;
16907            }
16908        }
16909
16910        if (mAlwaysFinishActivities) {
16911            // Need to do this on its own message because the stack may not
16912            // be in a consistent state at this point.
16913            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16914        }
16915
16916        if (allChanged) {
16917            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16918        }
16919
16920        if (mProcessStats.shouldWriteNowLocked(now)) {
16921            mHandler.post(new Runnable() {
16922                @Override public void run() {
16923                    synchronized (ActivityManagerService.this) {
16924                        mProcessStats.writeStateAsyncLocked();
16925                    }
16926                }
16927            });
16928        }
16929
16930        if (DEBUG_OOM_ADJ) {
16931            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16932        }
16933    }
16934
16935    final void trimApplications() {
16936        synchronized (this) {
16937            int i;
16938
16939            // First remove any unused application processes whose package
16940            // has been removed.
16941            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16942                final ProcessRecord app = mRemovedProcesses.get(i);
16943                if (app.activities.size() == 0
16944                        && app.curReceiver == null && app.services.size() == 0) {
16945                    Slog.i(
16946                        TAG, "Exiting empty application process "
16947                        + app.processName + " ("
16948                        + (app.thread != null ? app.thread.asBinder() : null)
16949                        + ")\n");
16950                    if (app.pid > 0 && app.pid != MY_PID) {
16951                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16952                                app.processName, app.setAdj, "empty");
16953                        app.killedByAm = true;
16954                        Process.killProcessQuiet(app.pid);
16955                        Process.killProcessGroup(app.info.uid, app.pid);
16956                    } else {
16957                        try {
16958                            app.thread.scheduleExit();
16959                        } catch (Exception e) {
16960                            // Ignore exceptions.
16961                        }
16962                    }
16963                    cleanUpApplicationRecordLocked(app, false, true, -1);
16964                    mRemovedProcesses.remove(i);
16965
16966                    if (app.persistent) {
16967                        addAppLocked(app.info, false, null /* ABI override */);
16968                    }
16969                }
16970            }
16971
16972            // Now update the oom adj for all processes.
16973            updateOomAdjLocked();
16974        }
16975    }
16976
16977    /** This method sends the specified signal to each of the persistent apps */
16978    public void signalPersistentProcesses(int sig) throws RemoteException {
16979        if (sig != Process.SIGNAL_USR1) {
16980            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16981        }
16982
16983        synchronized (this) {
16984            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16985                    != PackageManager.PERMISSION_GRANTED) {
16986                throw new SecurityException("Requires permission "
16987                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16988            }
16989
16990            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16991                ProcessRecord r = mLruProcesses.get(i);
16992                if (r.thread != null && r.persistent) {
16993                    Process.sendSignal(r.pid, sig);
16994                }
16995            }
16996        }
16997    }
16998
16999    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17000        if (proc == null || proc == mProfileProc) {
17001            proc = mProfileProc;
17002            path = mProfileFile;
17003            profileType = mProfileType;
17004            clearProfilerLocked();
17005        }
17006        if (proc == null) {
17007            return;
17008        }
17009        try {
17010            proc.thread.profilerControl(false, path, null, profileType);
17011        } catch (RemoteException e) {
17012            throw new IllegalStateException("Process disappeared");
17013        }
17014    }
17015
17016    private void clearProfilerLocked() {
17017        if (mProfileFd != null) {
17018            try {
17019                mProfileFd.close();
17020            } catch (IOException e) {
17021            }
17022        }
17023        mProfileApp = null;
17024        mProfileProc = null;
17025        mProfileFile = null;
17026        mProfileType = 0;
17027        mAutoStopProfiler = false;
17028    }
17029
17030    public boolean profileControl(String process, int userId, boolean start,
17031            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17032
17033        try {
17034            synchronized (this) {
17035                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17036                // its own permission.
17037                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17038                        != PackageManager.PERMISSION_GRANTED) {
17039                    throw new SecurityException("Requires permission "
17040                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17041                }
17042
17043                if (start && fd == null) {
17044                    throw new IllegalArgumentException("null fd");
17045                }
17046
17047                ProcessRecord proc = null;
17048                if (process != null) {
17049                    proc = findProcessLocked(process, userId, "profileControl");
17050                }
17051
17052                if (start && (proc == null || proc.thread == null)) {
17053                    throw new IllegalArgumentException("Unknown process: " + process);
17054                }
17055
17056                if (start) {
17057                    stopProfilerLocked(null, null, 0);
17058                    setProfileApp(proc.info, proc.processName, path, fd, false);
17059                    mProfileProc = proc;
17060                    mProfileType = profileType;
17061                    try {
17062                        fd = fd.dup();
17063                    } catch (IOException e) {
17064                        fd = null;
17065                    }
17066                    proc.thread.profilerControl(start, path, fd, profileType);
17067                    fd = null;
17068                    mProfileFd = null;
17069                } else {
17070                    stopProfilerLocked(proc, path, profileType);
17071                    if (fd != null) {
17072                        try {
17073                            fd.close();
17074                        } catch (IOException e) {
17075                        }
17076                    }
17077                }
17078
17079                return true;
17080            }
17081        } catch (RemoteException e) {
17082            throw new IllegalStateException("Process disappeared");
17083        } finally {
17084            if (fd != null) {
17085                try {
17086                    fd.close();
17087                } catch (IOException e) {
17088                }
17089            }
17090        }
17091    }
17092
17093    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17094        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17095                userId, true, ALLOW_FULL_ONLY, callName, null);
17096        ProcessRecord proc = null;
17097        try {
17098            int pid = Integer.parseInt(process);
17099            synchronized (mPidsSelfLocked) {
17100                proc = mPidsSelfLocked.get(pid);
17101            }
17102        } catch (NumberFormatException e) {
17103        }
17104
17105        if (proc == null) {
17106            ArrayMap<String, SparseArray<ProcessRecord>> all
17107                    = mProcessNames.getMap();
17108            SparseArray<ProcessRecord> procs = all.get(process);
17109            if (procs != null && procs.size() > 0) {
17110                proc = procs.valueAt(0);
17111                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17112                    for (int i=1; i<procs.size(); i++) {
17113                        ProcessRecord thisProc = procs.valueAt(i);
17114                        if (thisProc.userId == userId) {
17115                            proc = thisProc;
17116                            break;
17117                        }
17118                    }
17119                }
17120            }
17121        }
17122
17123        return proc;
17124    }
17125
17126    public boolean dumpHeap(String process, int userId, boolean managed,
17127            String path, ParcelFileDescriptor fd) throws RemoteException {
17128
17129        try {
17130            synchronized (this) {
17131                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17132                // its own permission (same as profileControl).
17133                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17134                        != PackageManager.PERMISSION_GRANTED) {
17135                    throw new SecurityException("Requires permission "
17136                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17137                }
17138
17139                if (fd == null) {
17140                    throw new IllegalArgumentException("null fd");
17141                }
17142
17143                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17144                if (proc == null || proc.thread == null) {
17145                    throw new IllegalArgumentException("Unknown process: " + process);
17146                }
17147
17148                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17149                if (!isDebuggable) {
17150                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17151                        throw new SecurityException("Process not debuggable: " + proc);
17152                    }
17153                }
17154
17155                proc.thread.dumpHeap(managed, path, fd);
17156                fd = null;
17157                return true;
17158            }
17159        } catch (RemoteException e) {
17160            throw new IllegalStateException("Process disappeared");
17161        } finally {
17162            if (fd != null) {
17163                try {
17164                    fd.close();
17165                } catch (IOException e) {
17166                }
17167            }
17168        }
17169    }
17170
17171    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17172    public void monitor() {
17173        synchronized (this) { }
17174    }
17175
17176    void onCoreSettingsChange(Bundle settings) {
17177        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17178            ProcessRecord processRecord = mLruProcesses.get(i);
17179            try {
17180                if (processRecord.thread != null) {
17181                    processRecord.thread.setCoreSettings(settings);
17182                }
17183            } catch (RemoteException re) {
17184                /* ignore */
17185            }
17186        }
17187    }
17188
17189    // Multi-user methods
17190
17191    /**
17192     * Start user, if its not already running, but don't bring it to foreground.
17193     */
17194    @Override
17195    public boolean startUserInBackground(final int userId) {
17196        return startUser(userId, /* foreground */ false);
17197    }
17198
17199    /**
17200     * Refreshes the list of users related to the current user when either a
17201     * user switch happens or when a new related user is started in the
17202     * background.
17203     */
17204    private void updateCurrentProfileIdsLocked() {
17205        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17206                mCurrentUserId, false /* enabledOnly */);
17207        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17208        for (int i = 0; i < currentProfileIds.length; i++) {
17209            currentProfileIds[i] = profiles.get(i).id;
17210        }
17211        mCurrentProfileIds = currentProfileIds;
17212
17213        synchronized (mUserProfileGroupIdsSelfLocked) {
17214            mUserProfileGroupIdsSelfLocked.clear();
17215            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17216            for (int i = 0; i < users.size(); i++) {
17217                UserInfo user = users.get(i);
17218                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17219                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17220                }
17221            }
17222        }
17223    }
17224
17225    private Set getProfileIdsLocked(int userId) {
17226        Set userIds = new HashSet<Integer>();
17227        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17228                userId, false /* enabledOnly */);
17229        for (UserInfo user : profiles) {
17230            userIds.add(Integer.valueOf(user.id));
17231        }
17232        return userIds;
17233    }
17234
17235    @Override
17236    public boolean switchUser(final int userId) {
17237        return startUser(userId, /* foregound */ true);
17238    }
17239
17240    private boolean startUser(final int userId, boolean foreground) {
17241        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17242                != PackageManager.PERMISSION_GRANTED) {
17243            String msg = "Permission Denial: switchUser() from pid="
17244                    + Binder.getCallingPid()
17245                    + ", uid=" + Binder.getCallingUid()
17246                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17247            Slog.w(TAG, msg);
17248            throw new SecurityException(msg);
17249        }
17250
17251        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17252
17253        final long ident = Binder.clearCallingIdentity();
17254        try {
17255            synchronized (this) {
17256                final int oldUserId = mCurrentUserId;
17257                if (oldUserId == userId) {
17258                    return true;
17259                }
17260
17261                mStackSupervisor.setLockTaskModeLocked(null, false);
17262
17263                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17264                if (userInfo == null) {
17265                    Slog.w(TAG, "No user info for user #" + userId);
17266                    return false;
17267                }
17268                if (foreground && userInfo.isManagedProfile()) {
17269                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17270                    return false;
17271                }
17272
17273                if (foreground) {
17274                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17275                            R.anim.screen_user_enter);
17276                }
17277
17278                boolean needStart = false;
17279
17280                // If the user we are switching to is not currently started, then
17281                // we need to start it now.
17282                if (mStartedUsers.get(userId) == null) {
17283                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17284                    updateStartedUserArrayLocked();
17285                    needStart = true;
17286                }
17287
17288                final Integer userIdInt = Integer.valueOf(userId);
17289                mUserLru.remove(userIdInt);
17290                mUserLru.add(userIdInt);
17291
17292                if (foreground) {
17293                    mCurrentUserId = userId;
17294                    updateCurrentProfileIdsLocked();
17295                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17296                    // Once the internal notion of the active user has switched, we lock the device
17297                    // with the option to show the user switcher on the keyguard.
17298                    mWindowManager.lockNow(null);
17299                } else {
17300                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17301                    updateCurrentProfileIdsLocked();
17302                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17303                    mUserLru.remove(currentUserIdInt);
17304                    mUserLru.add(currentUserIdInt);
17305                }
17306
17307                final UserStartedState uss = mStartedUsers.get(userId);
17308
17309                // Make sure user is in the started state.  If it is currently
17310                // stopping, we need to knock that off.
17311                if (uss.mState == UserStartedState.STATE_STOPPING) {
17312                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17313                    // so we can just fairly silently bring the user back from
17314                    // the almost-dead.
17315                    uss.mState = UserStartedState.STATE_RUNNING;
17316                    updateStartedUserArrayLocked();
17317                    needStart = true;
17318                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17319                    // This means ACTION_SHUTDOWN has been sent, so we will
17320                    // need to treat this as a new boot of the user.
17321                    uss.mState = UserStartedState.STATE_BOOTING;
17322                    updateStartedUserArrayLocked();
17323                    needStart = true;
17324                }
17325
17326                if (uss.mState == UserStartedState.STATE_BOOTING) {
17327                    // Booting up a new user, need to tell system services about it.
17328                    // Note that this is on the same handler as scheduling of broadcasts,
17329                    // which is important because it needs to go first.
17330                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17331                }
17332
17333                if (foreground) {
17334                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17335                            oldUserId));
17336                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17337                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17338                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17339                            oldUserId, userId, uss));
17340                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17341                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17342                }
17343
17344                if (needStart) {
17345                    // Send USER_STARTED broadcast
17346                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17347                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17348                            | Intent.FLAG_RECEIVER_FOREGROUND);
17349                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17350                    broadcastIntentLocked(null, null, intent,
17351                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17352                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17353                }
17354
17355                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17356                    if (userId != UserHandle.USER_OWNER) {
17357                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17358                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17359                        broadcastIntentLocked(null, null, intent, null,
17360                                new IIntentReceiver.Stub() {
17361                                    public void performReceive(Intent intent, int resultCode,
17362                                            String data, Bundle extras, boolean ordered,
17363                                            boolean sticky, int sendingUser) {
17364                                        userInitialized(uss, userId);
17365                                    }
17366                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17367                                true, false, MY_PID, Process.SYSTEM_UID,
17368                                userId);
17369                        uss.initializing = true;
17370                    } else {
17371                        getUserManagerLocked().makeInitialized(userInfo.id);
17372                    }
17373                }
17374
17375                if (foreground) {
17376                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17377                    if (homeInFront) {
17378                        startHomeActivityLocked(userId);
17379                    } else {
17380                        mStackSupervisor.resumeTopActivitiesLocked();
17381                    }
17382                    EventLogTags.writeAmSwitchUser(userId);
17383                    getUserManagerLocked().userForeground(userId);
17384                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17385                } else {
17386                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17387                }
17388
17389                if (needStart) {
17390                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17391                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17392                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17393                    broadcastIntentLocked(null, null, intent,
17394                            null, new IIntentReceiver.Stub() {
17395                                @Override
17396                                public void performReceive(Intent intent, int resultCode, String data,
17397                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17398                                        throws RemoteException {
17399                                }
17400                            }, 0, null, null,
17401                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17402                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17403                }
17404            }
17405        } finally {
17406            Binder.restoreCallingIdentity(ident);
17407        }
17408
17409        return true;
17410    }
17411
17412    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17413        long ident = Binder.clearCallingIdentity();
17414        try {
17415            Intent intent;
17416            if (oldUserId >= 0) {
17417                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17418                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17419                int count = profiles.size();
17420                for (int i = 0; i < count; i++) {
17421                    int profileUserId = profiles.get(i).id;
17422                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17423                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17424                            | Intent.FLAG_RECEIVER_FOREGROUND);
17425                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17426                    broadcastIntentLocked(null, null, intent,
17427                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17428                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17429                }
17430            }
17431            if (newUserId >= 0) {
17432                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17433                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17434                int count = profiles.size();
17435                for (int i = 0; i < count; i++) {
17436                    int profileUserId = profiles.get(i).id;
17437                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17438                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17439                            | Intent.FLAG_RECEIVER_FOREGROUND);
17440                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17441                    broadcastIntentLocked(null, null, intent,
17442                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17443                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17444                }
17445                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17446                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17447                        | Intent.FLAG_RECEIVER_FOREGROUND);
17448                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17449                broadcastIntentLocked(null, null, intent,
17450                        null, null, 0, null, null,
17451                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17452                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17453            }
17454        } finally {
17455            Binder.restoreCallingIdentity(ident);
17456        }
17457    }
17458
17459    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17460            final int newUserId) {
17461        final int N = mUserSwitchObservers.beginBroadcast();
17462        if (N > 0) {
17463            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17464                int mCount = 0;
17465                @Override
17466                public void sendResult(Bundle data) throws RemoteException {
17467                    synchronized (ActivityManagerService.this) {
17468                        if (mCurUserSwitchCallback == this) {
17469                            mCount++;
17470                            if (mCount == N) {
17471                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17472                            }
17473                        }
17474                    }
17475                }
17476            };
17477            synchronized (this) {
17478                uss.switching = true;
17479                mCurUserSwitchCallback = callback;
17480            }
17481            for (int i=0; i<N; i++) {
17482                try {
17483                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17484                            newUserId, callback);
17485                } catch (RemoteException e) {
17486                }
17487            }
17488        } else {
17489            synchronized (this) {
17490                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17491            }
17492        }
17493        mUserSwitchObservers.finishBroadcast();
17494    }
17495
17496    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17497        synchronized (this) {
17498            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17499            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17500        }
17501    }
17502
17503    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17504        mCurUserSwitchCallback = null;
17505        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17506        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17507                oldUserId, newUserId, uss));
17508    }
17509
17510    void userInitialized(UserStartedState uss, int newUserId) {
17511        completeSwitchAndInitalize(uss, newUserId, true, false);
17512    }
17513
17514    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17515        completeSwitchAndInitalize(uss, newUserId, false, true);
17516    }
17517
17518    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17519            boolean clearInitializing, boolean clearSwitching) {
17520        boolean unfrozen = false;
17521        synchronized (this) {
17522            if (clearInitializing) {
17523                uss.initializing = false;
17524                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17525            }
17526            if (clearSwitching) {
17527                uss.switching = false;
17528            }
17529            if (!uss.switching && !uss.initializing) {
17530                mWindowManager.stopFreezingScreen();
17531                unfrozen = true;
17532            }
17533        }
17534        if (unfrozen) {
17535            final int N = mUserSwitchObservers.beginBroadcast();
17536            for (int i=0; i<N; i++) {
17537                try {
17538                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17539                } catch (RemoteException e) {
17540                }
17541            }
17542            mUserSwitchObservers.finishBroadcast();
17543        }
17544    }
17545
17546    void scheduleStartProfilesLocked() {
17547        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17548            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17549                    DateUtils.SECOND_IN_MILLIS);
17550        }
17551    }
17552
17553    void startProfilesLocked() {
17554        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17555        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17556                mCurrentUserId, false /* enabledOnly */);
17557        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17558        for (UserInfo user : profiles) {
17559            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17560                    && user.id != mCurrentUserId) {
17561                toStart.add(user);
17562            }
17563        }
17564        final int n = toStart.size();
17565        int i = 0;
17566        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17567            startUserInBackground(toStart.get(i).id);
17568        }
17569        if (i < n) {
17570            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17571        }
17572    }
17573
17574    void finishUserBoot(UserStartedState uss) {
17575        synchronized (this) {
17576            if (uss.mState == UserStartedState.STATE_BOOTING
17577                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17578                uss.mState = UserStartedState.STATE_RUNNING;
17579                final int userId = uss.mHandle.getIdentifier();
17580                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17581                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17582                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17583                broadcastIntentLocked(null, null, intent,
17584                        null, null, 0, null, null,
17585                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17586                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17587            }
17588        }
17589    }
17590
17591    void finishUserSwitch(UserStartedState uss) {
17592        synchronized (this) {
17593            finishUserBoot(uss);
17594
17595            startProfilesLocked();
17596
17597            int num = mUserLru.size();
17598            int i = 0;
17599            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17600                Integer oldUserId = mUserLru.get(i);
17601                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17602                if (oldUss == null) {
17603                    // Shouldn't happen, but be sane if it does.
17604                    mUserLru.remove(i);
17605                    num--;
17606                    continue;
17607                }
17608                if (oldUss.mState == UserStartedState.STATE_STOPPING
17609                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17610                    // This user is already stopping, doesn't count.
17611                    num--;
17612                    i++;
17613                    continue;
17614                }
17615                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17616                    // Owner and current can't be stopped, but count as running.
17617                    i++;
17618                    continue;
17619                }
17620                // This is a user to be stopped.
17621                stopUserLocked(oldUserId, null);
17622                num--;
17623                i++;
17624            }
17625        }
17626    }
17627
17628    @Override
17629    public int stopUser(final int userId, final IStopUserCallback callback) {
17630        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17631                != PackageManager.PERMISSION_GRANTED) {
17632            String msg = "Permission Denial: switchUser() from pid="
17633                    + Binder.getCallingPid()
17634                    + ", uid=" + Binder.getCallingUid()
17635                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17636            Slog.w(TAG, msg);
17637            throw new SecurityException(msg);
17638        }
17639        if (userId <= 0) {
17640            throw new IllegalArgumentException("Can't stop primary user " + userId);
17641        }
17642        synchronized (this) {
17643            return stopUserLocked(userId, callback);
17644        }
17645    }
17646
17647    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17648        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17649        if (mCurrentUserId == userId) {
17650            return ActivityManager.USER_OP_IS_CURRENT;
17651        }
17652
17653        final UserStartedState uss = mStartedUsers.get(userId);
17654        if (uss == null) {
17655            // User is not started, nothing to do...  but we do need to
17656            // callback if requested.
17657            if (callback != null) {
17658                mHandler.post(new Runnable() {
17659                    @Override
17660                    public void run() {
17661                        try {
17662                            callback.userStopped(userId);
17663                        } catch (RemoteException e) {
17664                        }
17665                    }
17666                });
17667            }
17668            return ActivityManager.USER_OP_SUCCESS;
17669        }
17670
17671        if (callback != null) {
17672            uss.mStopCallbacks.add(callback);
17673        }
17674
17675        if (uss.mState != UserStartedState.STATE_STOPPING
17676                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17677            uss.mState = UserStartedState.STATE_STOPPING;
17678            updateStartedUserArrayLocked();
17679
17680            long ident = Binder.clearCallingIdentity();
17681            try {
17682                // We are going to broadcast ACTION_USER_STOPPING and then
17683                // once that is done send a final ACTION_SHUTDOWN and then
17684                // stop the user.
17685                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17686                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17687                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17688                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17689                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17690                // This is the result receiver for the final shutdown broadcast.
17691                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17692                    @Override
17693                    public void performReceive(Intent intent, int resultCode, String data,
17694                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17695                        finishUserStop(uss);
17696                    }
17697                };
17698                // This is the result receiver for the initial stopping broadcast.
17699                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17700                    @Override
17701                    public void performReceive(Intent intent, int resultCode, String data,
17702                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17703                        // On to the next.
17704                        synchronized (ActivityManagerService.this) {
17705                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17706                                // Whoops, we are being started back up.  Abort, abort!
17707                                return;
17708                            }
17709                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17710                        }
17711                        mBatteryStatsService.noteEvent(
17712                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17713                                Integer.toString(userId), userId);
17714                        mSystemServiceManager.stopUser(userId);
17715                        broadcastIntentLocked(null, null, shutdownIntent,
17716                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17717                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17718                    }
17719                };
17720                // Kick things off.
17721                broadcastIntentLocked(null, null, stoppingIntent,
17722                        null, stoppingReceiver, 0, null, null,
17723                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17724                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17725            } finally {
17726                Binder.restoreCallingIdentity(ident);
17727            }
17728        }
17729
17730        return ActivityManager.USER_OP_SUCCESS;
17731    }
17732
17733    void finishUserStop(UserStartedState uss) {
17734        final int userId = uss.mHandle.getIdentifier();
17735        boolean stopped;
17736        ArrayList<IStopUserCallback> callbacks;
17737        synchronized (this) {
17738            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17739            if (mStartedUsers.get(userId) != uss) {
17740                stopped = false;
17741            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17742                stopped = false;
17743            } else {
17744                stopped = true;
17745                // User can no longer run.
17746                mStartedUsers.remove(userId);
17747                mUserLru.remove(Integer.valueOf(userId));
17748                updateStartedUserArrayLocked();
17749
17750                // Clean up all state and processes associated with the user.
17751                // Kill all the processes for the user.
17752                forceStopUserLocked(userId, "finish user");
17753            }
17754
17755            // Explicitly remove the old information in mRecentTasks.
17756            removeRecentTasksForUserLocked(userId);
17757        }
17758
17759        for (int i=0; i<callbacks.size(); i++) {
17760            try {
17761                if (stopped) callbacks.get(i).userStopped(userId);
17762                else callbacks.get(i).userStopAborted(userId);
17763            } catch (RemoteException e) {
17764            }
17765        }
17766
17767        if (stopped) {
17768            mSystemServiceManager.cleanupUser(userId);
17769            synchronized (this) {
17770                mStackSupervisor.removeUserLocked(userId);
17771            }
17772        }
17773    }
17774
17775    @Override
17776    public UserInfo getCurrentUser() {
17777        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17778                != PackageManager.PERMISSION_GRANTED) && (
17779                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17780                != PackageManager.PERMISSION_GRANTED)) {
17781            String msg = "Permission Denial: getCurrentUser() from pid="
17782                    + Binder.getCallingPid()
17783                    + ", uid=" + Binder.getCallingUid()
17784                    + " requires " + INTERACT_ACROSS_USERS;
17785            Slog.w(TAG, msg);
17786            throw new SecurityException(msg);
17787        }
17788        synchronized (this) {
17789            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17790        }
17791    }
17792
17793    int getCurrentUserIdLocked() {
17794        return mCurrentUserId;
17795    }
17796
17797    @Override
17798    public boolean isUserRunning(int userId, boolean orStopped) {
17799        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17800                != PackageManager.PERMISSION_GRANTED) {
17801            String msg = "Permission Denial: isUserRunning() from pid="
17802                    + Binder.getCallingPid()
17803                    + ", uid=" + Binder.getCallingUid()
17804                    + " requires " + INTERACT_ACROSS_USERS;
17805            Slog.w(TAG, msg);
17806            throw new SecurityException(msg);
17807        }
17808        synchronized (this) {
17809            return isUserRunningLocked(userId, orStopped);
17810        }
17811    }
17812
17813    boolean isUserRunningLocked(int userId, boolean orStopped) {
17814        UserStartedState state = mStartedUsers.get(userId);
17815        if (state == null) {
17816            return false;
17817        }
17818        if (orStopped) {
17819            return true;
17820        }
17821        return state.mState != UserStartedState.STATE_STOPPING
17822                && state.mState != UserStartedState.STATE_SHUTDOWN;
17823    }
17824
17825    @Override
17826    public int[] getRunningUserIds() {
17827        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17828                != PackageManager.PERMISSION_GRANTED) {
17829            String msg = "Permission Denial: isUserRunning() from pid="
17830                    + Binder.getCallingPid()
17831                    + ", uid=" + Binder.getCallingUid()
17832                    + " requires " + INTERACT_ACROSS_USERS;
17833            Slog.w(TAG, msg);
17834            throw new SecurityException(msg);
17835        }
17836        synchronized (this) {
17837            return mStartedUserArray;
17838        }
17839    }
17840
17841    private void updateStartedUserArrayLocked() {
17842        int num = 0;
17843        for (int i=0; i<mStartedUsers.size();  i++) {
17844            UserStartedState uss = mStartedUsers.valueAt(i);
17845            // This list does not include stopping users.
17846            if (uss.mState != UserStartedState.STATE_STOPPING
17847                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17848                num++;
17849            }
17850        }
17851        mStartedUserArray = new int[num];
17852        num = 0;
17853        for (int i=0; i<mStartedUsers.size();  i++) {
17854            UserStartedState uss = mStartedUsers.valueAt(i);
17855            if (uss.mState != UserStartedState.STATE_STOPPING
17856                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17857                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17858                num++;
17859            }
17860        }
17861    }
17862
17863    @Override
17864    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17865        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17866                != PackageManager.PERMISSION_GRANTED) {
17867            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17868                    + Binder.getCallingPid()
17869                    + ", uid=" + Binder.getCallingUid()
17870                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17871            Slog.w(TAG, msg);
17872            throw new SecurityException(msg);
17873        }
17874
17875        mUserSwitchObservers.register(observer);
17876    }
17877
17878    @Override
17879    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17880        mUserSwitchObservers.unregister(observer);
17881    }
17882
17883    private boolean userExists(int userId) {
17884        if (userId == 0) {
17885            return true;
17886        }
17887        UserManagerService ums = getUserManagerLocked();
17888        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17889    }
17890
17891    int[] getUsersLocked() {
17892        UserManagerService ums = getUserManagerLocked();
17893        return ums != null ? ums.getUserIds() : new int[] { 0 };
17894    }
17895
17896    UserManagerService getUserManagerLocked() {
17897        if (mUserManager == null) {
17898            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17899            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17900        }
17901        return mUserManager;
17902    }
17903
17904    private int applyUserId(int uid, int userId) {
17905        return UserHandle.getUid(userId, uid);
17906    }
17907
17908    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17909        if (info == null) return null;
17910        ApplicationInfo newInfo = new ApplicationInfo(info);
17911        newInfo.uid = applyUserId(info.uid, userId);
17912        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17913                + info.packageName;
17914        return newInfo;
17915    }
17916
17917    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17918        if (aInfo == null
17919                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17920            return aInfo;
17921        }
17922
17923        ActivityInfo info = new ActivityInfo(aInfo);
17924        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17925        return info;
17926    }
17927
17928    private final class LocalService extends ActivityManagerInternal {
17929        @Override
17930        public void goingToSleep() {
17931            ActivityManagerService.this.goingToSleep();
17932        }
17933
17934        @Override
17935        public void wakingUp() {
17936            ActivityManagerService.this.wakingUp();
17937        }
17938
17939        @Override
17940        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17941                String processName, String abiOverride, int uid, Runnable crashHandler) {
17942            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17943                    processName, abiOverride, uid, crashHandler);
17944        }
17945    }
17946
17947    /**
17948     * An implementation of IAppTask, that allows an app to manage its own tasks via
17949     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17950     * only the process that calls getAppTasks() can call the AppTask methods.
17951     */
17952    class AppTaskImpl extends IAppTask.Stub {
17953        private int mTaskId;
17954        private int mCallingUid;
17955
17956        public AppTaskImpl(int taskId, int callingUid) {
17957            mTaskId = taskId;
17958            mCallingUid = callingUid;
17959        }
17960
17961        @Override
17962        public void finishAndRemoveTask() {
17963            // Ensure that we are called from the same process that created this AppTask
17964            if (mCallingUid != Binder.getCallingUid()) {
17965                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17966                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17967                return;
17968            }
17969
17970            synchronized (ActivityManagerService.this) {
17971                long origId = Binder.clearCallingIdentity();
17972                try {
17973                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17974                    if (tr != null) {
17975                        // Only kill the process if we are not a new document
17976                        int flags = tr.getBaseIntent().getFlags();
17977                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17978                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17979                        removeTaskByIdLocked(mTaskId,
17980                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17981                    }
17982                } finally {
17983                    Binder.restoreCallingIdentity(origId);
17984                }
17985            }
17986        }
17987
17988        @Override
17989        public ActivityManager.RecentTaskInfo getTaskInfo() {
17990            // Ensure that we are called from the same process that created this AppTask
17991            if (mCallingUid != Binder.getCallingUid()) {
17992                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17993                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17994                return null;
17995            }
17996
17997            synchronized (ActivityManagerService.this) {
17998                long origId = Binder.clearCallingIdentity();
17999                try {
18000                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18001                    if (tr != null) {
18002                        return createRecentTaskInfoFromTaskRecord(tr);
18003                    }
18004                } finally {
18005                    Binder.restoreCallingIdentity(origId);
18006                }
18007                return null;
18008            }
18009        }
18010    }
18011}
18012